Hello community, here is the log from the commit of package valgrind checked in at Tue Aug 29 00:13:07 CEST 2006. -------- --- valgrind/valgrind.changes 2006-08-24 14:52:54.000000000 +0200 +++ valgrind/valgrind.changes 2006-08-28 13:37:24.000000000 +0200 @@ -1,0 +2,6 @@ +Mon Aug 28 13:37:11 CEST 2006 - dmueller@suse.de + +- fix suppressions +- update drd plugin + +------------------------------------------------------------------- Old: ---- valgrind-5999-drd-2006-08-14.tar.bz2 valgrind-5999.patch New: ---- valgrind-6012-drd-2006-08-26.tar.bz2 valgrind-6012.patch valgrind-ppc.diff ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ valgrind.spec ++++++ --- /var/tmp/diff_new_pack.fJdC20/_old 2006-08-29 00:13:00.000000000 +0200 +++ /var/tmp/diff_new_pack.fJdC20/_new 2006-08-29 00:13:00.000000000 +0200 @@ -11,7 +11,7 @@ # norootforbuild Name: valgrind -BuildRequires: gcc-c++ glibc-devel-32bit +BuildRequires: gcc-c++ glibc-devel-32bit xorg-x11-devel %ifarch x86_64 BuildRequires: gcc41-32bit %endif @@ -21,16 +21,17 @@ Summary: Memory Management Debugger BuildRoot: %{_tmppath}/%{name}-%{version}-build Version: 3.2.0 -Release: 6 +Release: 7 Source0: %{name}-%{version}.tar.bz2 # svn di svn://svn.valgrind.org/valgrind/tags/VALGRIND_3_1_0 svn://svn.valgrind.org/valgrind/branches/VALGRIND_3_1_BRANCH > 3_1_BRANCH.diff # svn di svn://svn.valgrind.org/vex/tags/VEX_3_1_0 svn://svn.valgrind.org/vex/branches/VEX_3_1_BRANCH > VEX_3_1_BRANCH.diff #Patch0: 3_1_BRANCH.diff #Patch1: VEX_3_1_BRANCH.diff -Source1: valgrind-5999-drd-2006-08-14.tar.bz2 +Source1: valgrind-6012-drd-2006-08-26.tar.bz2 Patch2: multibyte-nop.diff -Patch3: valgrind-5999.patch +Patch3: valgrind-6012.patch Patch4: drd-fixes.diff +Patch5: valgrind-ppc.diff Provides: callgrind Obsoletes: callgrind ExclusiveArch: %ix86 x86_64 ppc ppc64 @@ -78,13 +79,14 @@ %patch2 %patch3 %patch4 +%patch5 %build export CFLAGS="$RPM_OPT_FLAGS" export CXXFLAGS="$RPM_OPT_FLAGS" autoreconf -fi export GDB=/usr/bin/gdb -%configure --with-x +%configure make %{?jobs:-j%jobs} %install @@ -102,6 +104,9 @@ %doc %_mandir/*/* %changelog -n valgrind +* Mon Aug 28 2006 - dmueller@suse.de +- fix suppressions +- update drd plugin * Thu Aug 24 2006 - dmueller@suse.de - add experimental drd plugin - fix build on x86_64 ++++++ drd-fixes.diff ++++++ --- /var/tmp/diff_new_pack.fJdC20/_old 2006-08-29 00:13:00.000000000 +0200 +++ /var/tmp/diff_new_pack.fJdC20/_new 2006-08-29 00:13:00.000000000 +0200 @@ -1,20 +1,20 @@ ---- drd/drd_malloc_wrappers.c 2006/08/23 13:43:15 1.1 -+++ drd/drd_malloc_wrappers.c 2006/08/23 13:43:56 -@@ -263,6 +263,8 @@ - SizeT* const size, - ExeContext** const where) - { -+ return False; -+ - DRD_Chunk* mc; +--- drd/drd_main.c ++++ drd/drd_main.c +@@ -110,7 +110,7 @@ + addr, size, VG_(get_running_tid)()); + } + #endif +- sg = thread_get_segment(VG_(running_tid)); ++ sg = thread_get_segment(VG_(get_running_tid)()); + bm_access_range(sg->bm, addr, size, eLoad); + } - tl_assert(data); -@@ -289,6 +291,8 @@ +@@ -124,7 +124,7 @@ + addr, size, VG_(get_running_tid)()); + } + #endif +- sg = thread_get_segment(VG_(running_tid)); ++ sg = thread_get_segment(VG_(get_running_tid)()); + bm_access_range(sg->bm, addr, size, eStore); + } - void drd_print_malloc_stats(void) - { -+ return; -+ - DRD_Chunk* mc; - SizeT nblocks = 0; - SizeT nbytes = 0; ++++++ valgrind-5999-drd-2006-08-14.tar.bz2 -> valgrind-6012-drd-2006-08-26.tar.bz2 ++++++ diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/drd/Makefile.am new/drd/Makefile.am --- old/drd/Makefile.am 2006-08-14 15:40:44.000000000 +0200 +++ new/drd/Makefile.am 2006-08-26 15:30:09.000000000 +0200 @@ -2,66 +2,28 @@ noinst_PROGRAMS = if VG_X86_LINUX - noinst_PROGRAMS += drd-x86-linux vgpreload_drd-x86-linux.so + noinst_PROGRAMS += drd-x86-linux PLATFORM = X86 endif if VG_AMD64_LINUX - noinst_PROGRAMS += drd-amd64-linux vgpreload_drd-amd64-linux.so + noinst_PROGRAMS += drd-amd64-linux PLATFORM = AMD64 endif if VG_PPC32_LINUX - noinst_PROGRAMS += drd-ppc32-linux vgpreload_drd-ppc32-linux.so + noinst_PROGRAMS += drd-ppc32-linux PLATFORM = PPC32 endif if VG_PPC64_LINUX -noinst_PROGRAMS += drd-ppc64-linux vgpreload_drd-ppc64-linux.so + noinst_PROGRAMS += drd-ppc64-linux + PLATFORM = PPC64 endif -VGPRELOAD_DRD_SOURCES_COMMON = - -vgpreload_drd_x86_linux_so_SOURCES = $(VGPRELOAD_DRD_SOURCES_COMMON) -vgpreload_drd_x86_linux_so_CPPFLAGS = $(AM_CPPFLAGS_X86_LINUX) -vgpreload_drd_x86_linux_so_CFLAGS = $(AM_CFLAGS_X86_LINUX) $(AM_CFLAGS_PIC) -O2 -vgpreload_drd_x86_linux_so_CCASFLAGS = $(AM_CCASFLAGS_X86_LINUX) -vgpreload_drd_x86_linux_so_DEPENDENCIES = $(LIBREPLACEMALLOC_X86_LINUX) -vgpreload_drd_x86_linux_so_LDFLAGS = \ - $(PRELOAD_LDFLAGS_X86_LINUX) \ - $(LIBREPLACEMALLOC_LDFLAGS_X86_LINUX) - -vgpreload_drd_amd64_linux_so_SOURCES = $(VGPRELOAD_DRD_SOURCES_COMMON) -vgpreload_drd_amd64_linux_so_CPPFLAGS = $(AM_CPPFLAGS_AMD64_LINUX) -vgpreload_drd_amd64_linux_so_CFLAGS = $(AM_CFLAGS_AMD64_LINUX) $(AM_CFLAGS_PIC) -O2 -vgpreload_drd_amd64_linux_so_CCASFLAGS = $(AM_CCASFLAGS_AMD64_LINUX) -vgpreload_drd_amd64_linux_so_DEPENDENCIES = $(LIBREPLACEMALLOC_AMD64_LINUX) -vgpreload_drd_amd64_linux_so_LDFLAGS = \ - $(PRELOAD_LDFLAGS_AMD64_LINUX) \ - $(LIBREPLACEMALLOC_LDFLAGS_AMD64_LINUX) - -vgpreload_drd_ppc32_linux_so_SOURCES = $(VGPRELOAD_DRD_SOURCES_COMMON) -vgpreload_drd_ppc32_linux_so_CPPFLAGS = $(AM_CPPFLAGS_PPC32_LINUX) -vgpreload_drd_ppc32_linux_so_CFLAGS = $(AM_CFLAGS_PPC32_LINUX) $(AM_CFLAGS_PIC) -O2 -vgpreload_drd_ppc32_linux_so_CCASFLAGS = $(AM_CCASFLAGS_PPC32_LINUX) -vgpreload_drd_ppc32_linux_so_DEPENDENCIES = $(LIBREPLACEMALLOC_PPC32_LINUX) -vgpreload_drd_ppc32_linux_so_LDFLAGS = \ - $(PRELOAD_LDFLAGS_PPC32_LINUX) \ - $(LIBREPLACEMALLOC_LDFLAGS_PPC32_LINUX) - -vgpreload_drd_ppc64_linux_so_SOURCES = $(VGPRELOAD_DRD_SOURCES_COMMON) -vgpreload_drd_ppc64_linux_so_CPPFLAGS = $(AM_CPPFLAGS_PPC64_LINUX) -vgpreload_drd_ppc64_linux_so_CFLAGS = $(AM_CFLAGS_PPC64_LINUX) $(AM_CFLAGS_PIC) -O2 -vgpreload_drd_ppc64_linux_so_CCASFLAGS = $(AM_CCASFLAGS_PPC64_LINUX) -vgpreload_drd_ppc64_linux_so_DEPENDENCIES = $(LIBREPLACEMALLOC_PPC64_LINUX) -vgpreload_drd_ppc64_linux_so_LDFLAGS = \ - $(PRELOAD_LDFLAGS_PPC64_LINUX) \ - $(LIBREPLACEMALLOC_LDFLAGS_PPC64_LINUX) - DRD_SOURCES_COMMON = \ drd_bitmap3.c \ drd_clientreq.c \ drd_error.c \ drd_main.c \ - drd_malloc_wrappers.c \ drd_mutex.c \ drd_segment.c \ drd_suppression.c \ @@ -71,6 +33,7 @@ AM_CFLAGS_X86_LINUX += -DCHECK_FORMAT_STRINGS -I$(top_srcdir)/coregrind AM_CFLAGS_AMD64_LINUX += -DCHECK_FORMAT_STRINGS -I$(top_srcdir)/coregrind AM_CFLAGS_PPC32_LINUX += -DCHECK_FORMAT_STRINGS -I$(top_srcdir)/coregrind +AM_CFLAGS_PPC64_LINUX += -DCHECK_FORMAT_STRINGS -I$(top_srcdir)/coregrind drd_x86_linux_SOURCES = $(DRD_SOURCES_COMMON) drd_x86_linux_CPPFLAGS = $(AM_CPPFLAGS_$(PLATFORM)_LINUX) @@ -92,3 +55,10 @@ drd_ppc32_linux_DEPENDENCIES = $(COREGRIND_LIBS_$(PLATFORM)_LINUX) drd_ppc32_linux_LDADD = $(TOOL_LDADD_$(PLATFORM)_LINUX) drd_ppc32_linux_LDFLAGS = $(TOOL_LDFLAGS_$(PLATFORM)_LINUX) + +drd_ppc64_linux_SOURCES = $(DRD_SOURCES_COMMON) +drd_ppc64_linux_CPPFLAGS = $(AM_CPPFLAGS_$(PLATFORM)_LINUX) +drd_ppc64_linux_CFLAGS = $(AM_CFLAGS_$(PLATFORM)_LINUX) +drd_ppc64_linux_DEPENDENCIES = $(COREGRIND_LIBS_$(PLATFORM)_LINUX) +drd_ppc64_linux_LDADD = $(TOOL_LDADD_$(PLATFORM)_LINUX) +drd_ppc64_linux_LDFLAGS = $(TOOL_LDFLAGS_$(PLATFORM)_LINUX) diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/drd/TODO.txt new/drd/TODO.txt --- old/drd/TODO.txt 2006-08-14 18:41:16.000000000 +0200 +++ new/drd/TODO.txt 2006-08-26 17:56:08.000000000 +0200 @@ -14,14 +14,23 @@ - testing on PPC (current implementation is only tested on x86 yet). - Replace representation of suppression ranges as a list of ranges by a bitmap. +- Potential optimization: don't keep any bitmaps if only one thread is running. Known bugs: +- valgrind --tool=drd none/tests/pth_cvsimple triggers an assertion failure. - Gets killed by the OOM handler for some applications. +- drd_malloc_wrappers.c: when data addresses are reused because of a + malloc()/free()/malloc() sequence, the reported allocation stack will be + wrong. + +Valgrind core changes +~~~~~~~~~~~~~~~~~~~~~ +- Explain each of the changes, and submit them as a patch. Especially explain + why the change in the thread state handling is necessary. Error reporting ~~~~~~~~~~~~~~~ -- better error reporting for stack variables -- currently only an address is - printed when a data race is detected for a stack variable, and no name. +- Make sure that Valgrind counts data races reported by drd as errors. Testing ~~~~~~~ diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/drd/drd_bitmap.h new/drd/drd_bitmap.h --- old/drd/drd_bitmap.h 2006-08-14 14:30:22.000000000 +0200 +++ new/drd/drd_bitmap.h 2006-08-26 14:26:04.000000000 +0200 @@ -60,9 +60,6 @@ Addr address, SizeT size, enum bm_access_type access_type); -void bm_access_1(struct bitmap* bm, - Addr address, - enum bm_access_type access_type); void bm_access_4(struct bitmap* bm, Addr address, enum bm_access_type access_type); diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/drd/drd_bitmap3.c new/drd/drd_bitmap3.c --- old/drd/drd_bitmap3.c 2006-08-14 16:45:00.000000000 +0200 +++ new/drd/drd_bitmap3.c 2006-08-26 14:33:07.000000000 +0200 @@ -88,28 +88,10 @@ } /** - * Record an access of type access_type at addresses a .. a + size - 1 in - * bitmap bm. - */ -void bm_access_range(struct bitmap* const bm, - Addr const a, - SizeT const size, - enum bm_access_type access_type) -{ - Addr b; - - tl_assert(bm); - tl_assert(0 < size && size < 4096); - - for (b = a; b != a + size; b++) - { - bm_access_1(bm, b, access_type); - } -} - -/** * Record an access of type access_type at addresses a in bitmap bm. */ +static +__inline__ void bm_access_1(struct bitmap* bm, Addr a, enum bm_access_type access_type) { @@ -118,7 +100,7 @@ unsigned* p0; SPLIT_ADDRESS(a); - tl_assert(bm); + // tl_assert(bm); p2 = &bm->bm2[a2]; if (*p2 == 0) @@ -136,7 +118,31 @@ void bm_access_4(struct bitmap* bm, Addr a, enum bm_access_type access_type) { - bm_access_range(bm, a, 4, access_type); + tl_assert(bm); + bm_access_1(bm, a + 0, access_type); + bm_access_1(bm, a + 1, access_type); + bm_access_1(bm, a + 2, access_type); + bm_access_1(bm, a + 3, access_type); +} + +/** + * Record an access of type access_type at addresses a .. a + size - 1 in + * bitmap bm. + */ +void bm_access_range(struct bitmap* const bm, + Addr const a, + SizeT const size, + enum bm_access_type access_type) +{ + Addr b; + + tl_assert(bm); + tl_assert(0 < size && size < 4096); + + for (b = a; b != a + size; b++) + { + bm_access_1(bm, b, access_type); + } } /** @@ -240,7 +246,7 @@ unsigned range_access = 0; unsigned i; - VG_(message)(Vg_UserMsg, "Actual data races:"); + VG_(message)(Vg_UserMsg, "Data addresses accessed by both segments:"); for (i = 0; i < ADDR2_COUNT; i++) { @@ -271,6 +277,7 @@ range_end = a + 1; else { + tl_assert(range_begin < range_end); if (HAS_RACE(range_access) && ! drd_is_suppressed(range_begin, range_end)) { @@ -280,11 +287,16 @@ dri.range_begin = range_begin; dri.range_end = range_end; dri.range_access = range_access; + tl_assert(dri.range_begin < dri.range_end); +#if 0 VG_(maybe_record_error)(tid1, DataRaceErr, VG_(get_IP)(tid1), // where "data race", &dri); +#else + drd_report_data_race(&dri); +#endif } range_access = access; range_begin = a; @@ -297,7 +309,7 @@ } } - VG_(message)(Vg_UserMsg, "End of detected data races"); + // VG_(message)(Vg_UserMsg, "End of detected data races"); } void bm_print(struct bitmap const* bm) diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/drd/drd_error.c new/drd/drd_error.c --- old/drd/drd_error.c 2006-08-14 15:03:01.000000000 +0200 +++ new/drd/drd_error.c 2006-08-26 14:41:21.000000000 +0200 @@ -39,10 +39,10 @@ // See also memcheck/mc_main.c -/* Describe a data address as good as you can, for error messages, +/* Describe a data address range [a,a+len[ as good as you can, for error messages, putting the result in ai. */ // See also memcheck/mc_main.c -void describe_addr(Addr a, AddrInfo* ai) +void describe_addr(Addr const a, SizeT const len, AddrInfo* const ai) { ThreadId tid; Addr stack_min, stack_max; @@ -55,7 +55,10 @@ if (stack_min <= a && a <= stack_max) { ai->akind = Stack; + ai->size = len; + ai->rwoffset = 0; ai->stack_tid = tid; + tl_assert(a + ai->size <= stack_max); return; } } @@ -64,20 +67,71 @@ sg = VG_(find_seginfo)(a); if (sg) { + int i, n; + ai->akind = Segment; ai->seginfo = sg; + ai->name[0] = 0; + + n = VG_(seginfo_syms_howmany)(sg); + for (i = 0; i < n; i++) + { + Addr addr; + UInt size; + HChar* name; + Char filename[256]; + Int linenum; + + VG_(seginfo_syms_getidx)(sg, i, &addr, &size, &name); + if (addr <= a && a < addr + size) + { + ai->size = size; + ai->rwoffset = a - addr; + tl_assert(name && name[0]); + VG_(snprintf)(ai->name, sizeof(ai->name), "%s", name); + if (VG_(get_filename_linenum)(addr, + filename, sizeof(filename), + 0, 0, 0, + &linenum)) + { + VG_(snprintf)(ai->descr, sizeof(ai->descr), + " in %s:%d", filename, linenum); + } + else + { + i = n; + } + break; + } + } + if (i == n) + { + Char sect_kind_name[16]; + + ai->size = 1; + ai->rwoffset = 0; + VG_(seginfo_sect_kind_name)(a, sect_kind_name, + sizeof(sect_kind_name)); + VG_(snprintf)(ai->descr, sizeof(ai->descr), + " %s, %s:%s", + VG_(seginfo_filename)(sg), + VG_(seginfo_soname)(sg), + sect_kind_name); + } return; } /* Search for a currently malloc'd block which might bracket it. */ { +#if 0 Addr data; - if (drd_heap_addrinfo(a, &data, &ai->blksize, &ai->lastchange)) + if (drd_heap_addrinfo(a, &data, &ai->size, &ai->lastchange)) { ai->akind = Mallocd; ai->rwoffset = a - data; return; } +#endif } /* Clueless ... */ @@ -88,14 +142,14 @@ /** * Generate a description string for the data residing at address a. */ -Char* describe_addr_text(Addr const a, AddrInfo* const ai, +Char* describe_addr_text(Addr const a, SizeT const len, AddrInfo* const ai, Char* const buf, UInt const n_buf) { tl_assert(a); tl_assert(ai); tl_assert(buf); - describe_addr(a, ai); + describe_addr(a, len, ai); switch (ai->akind) { @@ -107,70 +161,29 @@ VG_(get_pthread_id)(ai->stack_tid)); break; case Segment: { - Char sect_kind_name[16]; - int i, n; - - buf[0] = 0; - - n = VG_(seginfo_syms_howmany)(ai->seginfo); - for (i = 0; i < n; i++) + if (ai->name[0]) { - Addr addr; - UInt size; - HChar* name; - VG_(seginfo_syms_getidx)(ai->seginfo, i, &addr, &size, &name); - if (addr <= a && a < addr + size) - { - Char filename[256] = ""; - UInt linenum = 0; - VG_(snprintf)(buf + VG_(strlen)(buf), n_buf - VG_(strlen)(buf), - "%s (offset %ld, size %d) in ", - name, a - addr, size); - if (VG_(get_filename_linenum)(addr, - filename, sizeof(filename), - 0, 0, 0, - &linenum)) - { - VG_(snprintf)(buf + VG_(strlen)(buf), n_buf - VG_(strlen)(buf), - "%s:%d, ", - filename, - linenum); - } - else - { - i = n; - break; - } - break; - } + VG_(snprintf)(buf, n_buf, + "%s (offset %ld, size %ld) in %s", + ai->name, ai->rwoffset, ai->size, ai->descr); } - if (i == n) + else { - VG_(seginfo_sect_kind_name)(a, sect_kind_name, - sizeof(sect_kind_name)); - VG_(snprintf)(buf + VG_(strlen)(buf), n_buf - VG_(strlen)(buf), - "%s, %s:%s", - VG_(seginfo_filename)(ai->seginfo), - VG_(seginfo_soname)(ai->seginfo), - sect_kind_name); + VG_(snprintf)(buf, n_buf, + "%s", + ai->descr); } break; } case Mallocd: { - Addr data; - SizeT size; - ExeContext* where; VG_(snprintf)(buf, n_buf, "heap"); - if (drd_heap_addrinfo(a, &data, &size, &where)) - { - VG_(snprintf)(buf + VG_(strlen)(buf), n_buf - VG_(strlen)(buf), - ", offset %ld in block at 0x%lx of size %ld", - a - data, data, size); - } + VG_(snprintf)(buf + VG_(strlen)(buf), n_buf - VG_(strlen)(buf), + ", offset %ld in block at 0x%lx of size %ld", + ai->rwoffset, a - ai->rwoffset, ai->size); break; } case Unknown: - VG_(snprintf)(buf, n_buf, "unknown"); + VG_(snprintf)(buf, n_buf, "heap"); break; default: tl_assert(0); @@ -178,12 +191,40 @@ return buf; } +void drd_report_data_race(DataRaceInfo const* const dri) +{ + AddrInfo ai; + Char descr[256]; + + tl_assert(dri); + tl_assert(dri->range_begin < dri->range_end); + describe_addr_text(dri->range_begin, dri->range_end - dri->range_begin, + &ai, descr, sizeof(descr)); + VG_(message)(Vg_UserMsg, + "0x%08lx sz %ld %c %c (%s)", + dri->range_begin, + dri->range_end - dri->range_begin, + dri->range_access & LHS_W ? 'W' : 'R', + dri->range_access & RHS_W ? 'W' : 'R', + descr); + if (ai.akind == Mallocd && ai.lastchange) + { + VG_(message)(Vg_UserMsg, "Allocation context:"); + VG_(pp_ExeContext)(ai.lastchange); + } + // Note: for stack and heap variables suppression should be + // stopped automatically as soon as the specified memory + // range has been freed. + tl_assert(dri->range_begin < dri->range_end); + drd_start_suppression(dri->range_begin, dri->range_end); +} + static Bool drd_tool_error_eq(VgRes res, Error* e1, Error* e2) { return False; } -static void drd_tool_error_pp(Error* e) +static void drd_tool_error_pp(Error* const e) { switch (VG_(get_error_kind)(e)) { @@ -198,29 +239,7 @@ break; } case DataRaceErr: { - AddrInfo ai; - DataRaceInfo* dri; - Char descr[256]; - - dri = VG_(get_error_extra)(e); - tl_assert(dri); - describe_addr_text(dri->range_begin, &ai, descr, sizeof(descr)); - VG_(message)(Vg_UserMsg, - "0x%08lx sz %ld %c %c (%s)", - dri->range_begin, - dri->range_end - dri->range_begin, - dri->range_access & LHS_W ? 'W' : 'R', - dri->range_access & RHS_W ? 'W' : 'R', - descr); - if (ai.akind == Mallocd && ai.lastchange) - { - VG_(message)(Vg_UserMsg, "Allocation context:"); - VG_(pp_ExeContext)(ai.lastchange); - } - // Note: for stack and heap variables suppression should be - // stopped automatically as soon as the specified memory - // range has been freed. - drd_start_suppression(dri->range_begin, dri->range_end); + drd_report_data_race(VG_(get_error_extra)(e)); break; } default: diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/drd/drd_error.h new/drd/drd_error.h --- old/drd/drd_error.h 2006-08-14 14:53:04.000000000 +0200 +++ new/drd/drd_error.h 2006-08-26 18:01:29.000000000 +0200 @@ -35,8 +35,8 @@ /* DRD error types. */ typedef enum { - DataRaceErr = 1, - MutexErr = 2, + DataRaceErr = 1, + MutexErr = 2, } DrdErrorKind; /* The classification of a faulting address. */ @@ -56,13 +56,15 @@ /* Records info about a faulting address. */ typedef - struct { // Used by: - AddrKind akind; // ALL - SizeT blksize; // Mallocd - OffT rwoffset; // Mallocd - ExeContext* lastchange; // Mallocd - ThreadId stack_tid; // Stack - SegInfo* seginfo; // Segment + struct { // Used by: + AddrKind akind; // ALL + SizeT size; // ALL + OffT rwoffset; // ALL + ExeContext* lastchange; // Mallocd + ThreadId stack_tid; // Stack + SegInfo* seginfo; // Segment + Char name[256]; // Segment + Char descr[256]; // Segment } AddrInfo; @@ -75,9 +77,10 @@ UInt range_access; // How the range was accessed (LHS_[RW] | RHS_[RW]). } DataRaceInfo; -void describe_addr(Addr const a, AddrInfo* const ai); -Char* describe_addr_text(Addr const a, AddrInfo* const ai, +void describe_addr(Addr const a, SizeT const len, AddrInfo* const ai); +Char* describe_addr_text(Addr const a, SizeT const len, AddrInfo* const ai, Char* const buf, UInt const n_buf); +void drd_report_data_race(DataRaceInfo const* const dri); void drd_register_error_handlers(void); diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/drd/drd_main.c new/drd/drd_main.c --- old/drd/drd_main.c 2006-08-14 17:43:23.000000000 +0200 +++ new/drd/drd_main.c 2006-08-26 17:48:27.000000000 +0200 @@ -26,7 +26,9 @@ #include "drd_bitmap.h" #include "drd_clientreq.h" #include "drd_error.h" +#ifdef USE_MALLOC_WRAPPERS #include "drd_malloc_wrappers.h" +#endif #include "drd_mutex.h" #include "drd_segment.h" #include "drd_suppression.h" @@ -101,28 +103,28 @@ VG_REGPARM(2) void drd_trace_load(Addr addr, SizeT size) { struct segment* sg; - +#if 0 if (drd_trace_mem) { VG_(message)(Vg_UserMsg, "load 0x%lx size %ld thread %d", addr, size, VG_(get_running_tid)()); } - - sg = thread_get_segment(VG_(get_running_tid)()); +#endif + sg = thread_get_segment(VG_(running_tid)); bm_access_range(sg->bm, addr, size, eLoad); } VG_REGPARM(2) void drd_trace_store(Addr addr, SizeT size) { struct segment* sg; - +#if 0 if (drd_trace_mem) { VG_(message)(Vg_UserMsg, "store 0x%lx size %ld thread %d", addr, size, VG_(get_running_tid)()); } - - sg = thread_get_segment(VG_(get_running_tid)()); +#endif + sg = thread_get_segment(VG_(running_tid)); bm_access_range(sg->bm, addr, size, eStore); } @@ -176,7 +178,8 @@ p = mutex_get(mutex); if (p) { - // To do: report an error in case the recursion count is not zero. + // To do: report an error in case the recursion count is not zero + // before asserting. tl_assert(p->recursion_count == 0); mutex_destroy(p); } @@ -327,20 +330,35 @@ { IRDirty* d = st->Ist.Dirty.details; IREffect const mFx = d->mFx; - if (mFx != Ifx_None) - { - VG_(message)(Vg_UserMsg, - "Encountered Ist_Dirty with effect %s addr %p size %d", - mFx == Ifx_None ? "-" - : mFx == Ifx_Read ? "R" - : mFx == Ifx_Write ? "W" - : mFx == Ifx_Modify ? "RW" - : "?", - d->mAddr, - d->mSize); + switch (mFx) { + case Ifx_None: + break; + case Ifx_Read: + case Ifx_Write: + case Ifx_Modify: + tl_assert(d->mAddr); + tl_assert(d->mSize > 0); + argv = mkIRExprVec_2(d->mAddr, mkIRExpr_HWord(d->mSize)); + if (mFx == Ifx_Read || mFx == Ifx_Modify) { + di = unsafeIRDirty_0_N( + /*regparms*/2, + "drd_trace_load", + VG_(fnptr_to_fnentry)(drd_trace_load), + argv); + addStmtToIRBB(bb, IRStmt_Dirty(di)); + } + if (mFx == Ifx_Write || mFx == Ifx_Modify) { + di = unsafeIRDirty_0_N( + /*regparms*/2, + "drd_trace_store", + VG_(fnptr_to_fnentry)(drd_trace_store), + argv); + addStmtToIRBB(bb, IRStmt_Dirty(di)); + } + break; + default: + tl_assert(0); } - // To do: implement handling of Ist_Dirty. - tl_assert(mFx == Ifx_None); } addStmtToIRBB(bb, st); break; @@ -403,12 +421,12 @@ // Other stuff. VG_(needs_data_syms)(); +#ifdef USE_MALLOC_WRAPPERS drd_register_malloc_wrappers(); +#endif drd_clientreq_init(); - //VG_(needs_client_requests)(drd_handle_client_request); - // Unit tests. // bm_test(); // vc_test(); diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/drd/drd_malloc_wrappers.c new/drd/drd_malloc_wrappers.c --- old/drd/drd_malloc_wrappers.c 2006-08-14 09:07:00.000000000 +0200 +++ new/drd/drd_malloc_wrappers.c 2006-08-26 17:43:07.000000000 +0200 @@ -1,11 +1,8 @@ /* - This file is part of drd, a data race detector. Based on - mc_malloc_wrappers.c, part of MemCheck, a heavyweight Valgrind tool for - detecting memory errors, and AddrCheck, a lightweight Valgrind tool - for detecting memory errors. + This file is part of drd, a data race detector. - Copyright (C) 2000-2006 Julian Seward - jseward@acm.org + Copyright (C) 2006 Bart Van Assche + bart.vanassche@gmail.com This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -25,7 +22,9 @@ The GNU General Public License is contained in the file COPYING. */ + #include "drd_malloc_wrappers.h" +#include "drd_thread.h" #include "pub_tool_basics.h" #include "pub_tool_execontext.h" #include "pub_tool_hashtable.h" @@ -71,7 +70,7 @@ static DRD_Chunk* create_DRD_Chunk(ThreadId tid, Addr p, SizeT size) { - DRD_Chunk* mc = VG_(malloc)(sizeof(DRD_Chunk)); + DRD_Chunk* mc = VG_(malloc)(sizeof(DRD_Chunk)); mc->data = p; mc->size = size; mc->where = VG_(record_ExeContext)(tid); @@ -151,7 +150,6 @@ mc = VG_(HT_remove)(drd_malloc_list, (UWord)p ); if (mc == NULL) { tl_assert(0); - // drd_record_free_error(tid, p ); } else { VG_(free)(mc); } @@ -190,8 +188,6 @@ mc = VG_(HT_remove)(drd_malloc_list, (UWord)p_old ); if (mc == NULL) { tl_assert(0); - // drd_record_free_error(tid, (Addr)p_old ); - /* We return to the program regardless. */ return NULL; } diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/drd/drd_mutex.c new/drd/drd_mutex.c --- old/drd/drd_mutex.c 2006-08-12 14:54:06.000000000 +0200 +++ new/drd/drd_mutex.c 2006-08-26 14:25:20.000000000 +0200 @@ -84,16 +84,18 @@ struct mutex_info* p; p = mutex_get_or_allocate(mutex); - p->recursion_count++; - if (p->recursion_count == 1) + if (p->recursion_count == 0) p->owner = tid; else if (p->owner != tid) { - // The impossible happened ... - VG_(message)(Vg_DebugMsg, "mutex 0x%lx recursion count %d owner %d -> %d", + VG_(message)(Vg_DebugMsg, + "The impossible happened: mutex 0x%lx is locked" + " simultaneously by two threads (recursion count %d," + " owners %d and %d) !", p->mutex, p->recursion_count, p->owner, tid); tl_assert(0); } + p->recursion_count++; return p->recursion_count; } diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/drd/drd_thread.c new/drd/drd_thread.c --- old/drd/drd_thread.c 2006-08-14 16:46:26.000000000 +0200 +++ new/drd/drd_thread.c 2006-08-26 13:30:47.000000000 +0200 @@ -44,8 +44,8 @@ typedef struct { - struct segment* first; - struct segment* last; + struct segment* first; + struct segment* last; } ThreadInfo; @@ -62,15 +62,37 @@ // Function definitions. /** + * Sanity check of the doubly linked list of segments referenced by a ThreadInfo struct. + * @return True if sane, False if not. + */ +static Bool sane_ThreadInfo(ThreadInfo const* const ti) +{ + struct segment* p; + for (p = ti->first; p; p = p->next) { + if (p->next && p->next->prev != p) + return False; + if (p->next == 0 && p != ti->last) + return False; + } + for (p = ti->last; p; p = p->prev) { + if (p->prev && p->prev->next != p) + return False; + if (p->prev == 0 && p != ti->first) + return False; + } + return True; +} + +/** * Allocate thread-specific data structure. Call this just after * pthread_create(). Assumption: thread id's are small integers. */ void thread_new(ThreadId const creator, ThreadId const created) { - tl_assert(0 < created && created < MAXTHREADS); - tl_assert(s_threadinfo[created].first == 0); - tl_assert(s_threadinfo[created].last == 0); - thread_append_segment(created, sg_new(creator, created)); + tl_assert(0 < created && created < MAXTHREADS); + tl_assert(s_threadinfo[created].first == 0); + tl_assert(s_threadinfo[created].last == 0); + thread_append_segment(created, sg_new(creator, created)); } /** @@ -79,17 +101,17 @@ */ void thread_delete(ThreadId const threadid) { - struct segment* sg; - struct segment* sg_prev; + struct segment* sg; + struct segment* sg_prev; - tl_assert(0 < threadid && threadid < MAXTHREADS); - for (sg = s_threadinfo[threadid].last; sg; sg = sg_prev) - { - sg_prev = sg->prev; - sg_delete(sg); - } - s_threadinfo[threadid].first = 0; - s_threadinfo[threadid].last = 0; + tl_assert(0 < threadid && threadid < MAXTHREADS); + for (sg = s_threadinfo[threadid].last; sg; sg = sg_prev) + { + sg_prev = sg->prev; + sg_delete(sg); + } + s_threadinfo[threadid].first = 0; + s_threadinfo[threadid].last = 0; } /** @@ -97,9 +119,9 @@ */ struct segment* thread_get_segment(ThreadId const threadid) { - tl_assert(0 < threadid && threadid < MAXTHREADS); - tl_assert(s_threadinfo[threadid].last); - return s_threadinfo[threadid].last; + tl_assert(0 < threadid && threadid < MAXTHREADS); + tl_assert(s_threadinfo[threadid].last); + return s_threadinfo[threadid].last; } /** @@ -108,11 +130,15 @@ static void thread_append_segment(ThreadId const threadid, struct segment* const sg) { - sg->prev = s_threadinfo[threadid].last; - sg->next = 0; - s_threadinfo[threadid].last = sg; - if (s_threadinfo[threadid].first == 0) - s_threadinfo[threadid].first = sg; + tl_assert(sane_ThreadInfo(&s_threadinfo[threadid])); + sg->prev = s_threadinfo[threadid].last; + sg->next = 0; + if (s_threadinfo[threadid].last) + s_threadinfo[threadid].last->next = sg; + s_threadinfo[threadid].last = sg; + if (s_threadinfo[threadid].first == 0) + s_threadinfo[threadid].first = sg; + tl_assert(sane_ThreadInfo(&s_threadinfo[threadid])); } /** @@ -122,22 +148,24 @@ static void thread_discard_segment(ThreadId const threadid, struct segment* const sg) { - if (sg->prev) - sg->prev->next = sg->next; - if (sg->next) - sg->next->prev = sg->prev; - if (sg == s_threadinfo[threadid].first) - s_threadinfo[threadid].first = sg->next; - if (sg == s_threadinfo[threadid].last) - s_threadinfo[threadid].last = sg->prev; - sg_delete(sg); + tl_assert(sane_ThreadInfo(&s_threadinfo[threadid])); + if (sg->prev) + sg->prev->next = sg->next; + if (sg->next) + sg->next->prev = sg->prev; + if (sg == s_threadinfo[threadid].first) + s_threadinfo[threadid].first = sg->next; + if (sg == s_threadinfo[threadid].last) + s_threadinfo[threadid].last = sg->prev; + sg_delete(sg); + tl_assert(sane_ThreadInfo(&s_threadinfo[threadid])); } struct vectorclock* thread_get_vc(ThreadId const threadid) { - tl_assert(0 < threadid && threadid < MAXTHREADS); - tl_assert(s_threadinfo[threadid].last); - return &s_threadinfo[threadid].last->vc; + tl_assert(0 < threadid && threadid < MAXTHREADS); + tl_assert(s_threadinfo[threadid].last); + return &s_threadinfo[threadid].last->vc; } /** @@ -147,50 +175,50 @@ */ static void thread_compute_minimum_vc(struct vectorclock* vc) { - int i; - Bool first; - struct segment* latest_sg; - - first = True; - for (i = 0; i < sizeof(s_threadinfo) / sizeof(s_threadinfo[0]); i++) - { - latest_sg = s_threadinfo[i].last; - if (latest_sg) - { - if (first) + int i; + Bool first; + struct segment* latest_sg; + + first = True; + for (i = 0; i < sizeof(s_threadinfo) / sizeof(s_threadinfo[0]); i++) + { + latest_sg = s_threadinfo[i].last; + if (latest_sg) { - vc_cleanup(vc); - vc_copy(vc, &latest_sg->vc); + if (first) + { + vc_cleanup(vc); + vc_copy(vc, &latest_sg->vc); + } + else + vc_min(vc, &latest_sg->vc); + first = False; } - else - vc_min(vc, &latest_sg->vc); - first = False; - } - } + } } static void thread_compute_maximum_vc(struct vectorclock* vc) { - int i; - Bool first; - struct segment* latest_sg; - - first = True; - for (i = 0; i < sizeof(s_threadinfo) / sizeof(s_threadinfo[0]); i++) - { - latest_sg = s_threadinfo[i].last; - if (latest_sg) - { - if (first) + int i; + Bool first; + struct segment* latest_sg; + + first = True; + for (i = 0; i < sizeof(s_threadinfo) / sizeof(s_threadinfo[0]); i++) + { + latest_sg = s_threadinfo[i].last; + if (latest_sg) { - vc_cleanup(vc); - vc_copy(vc, &latest_sg->vc); + if (first) + { + vc_cleanup(vc); + vc_copy(vc, &latest_sg->vc); + } + else + vc_combine(vc, &latest_sg->vc); + first = False; } - else - vc_combine(vc, &latest_sg->vc); - first = False; - } - } + } } /** @@ -200,134 +228,134 @@ */ static void thread_discard_ordered_segments(void) { - struct vectorclock thread_vc_min; - int i; + struct vectorclock thread_vc_min; + int i; - vc_init(&thread_vc_min, 0, 0); - thread_compute_minimum_vc(&thread_vc_min); - if (sg_get_trace()) - { - char msg[256]; - struct vectorclock thread_vc_max; - - vc_init(&thread_vc_max, 0, 0); - thread_compute_maximum_vc(&thread_vc_max); - VG_(snprintf)(msg, sizeof(msg), - "Discarding ordered segments -- min vc is "); - vc_snprint(msg + VG_(strlen)(msg), sizeof(msg) - VG_(strlen)(msg), - &thread_vc_min); - VG_(snprintf)(msg + VG_(strlen)(msg), sizeof(msg) - VG_(strlen)(msg), - ", max vc is "); - vc_snprint(msg + VG_(strlen)(msg), sizeof(msg) - VG_(strlen)(msg), - &thread_vc_max); - VG_(message)(Vg_DebugMsg, "%s", msg); - vc_cleanup(&thread_vc_max); - } - - for (i = 0; i < sizeof(s_threadinfo) / sizeof(s_threadinfo[0]); i++) - { - struct segment* sg; - struct segment* sg_next; - for (sg = s_threadinfo[i].first; - sg && (sg_next = sg->next) && vc_lte(&sg->vc, &thread_vc_min); - sg = sg_next) - { -#if 1 - VG_(printf)("Discarding a segment of thread %d: ", i); - vc_print(&sg->vc); - VG_(printf)("\n"); + vc_init(&thread_vc_min, 0, 0); + thread_compute_minimum_vc(&thread_vc_min); + if (sg_get_trace()) + { + char msg[256]; + struct vectorclock thread_vc_max; + + vc_init(&thread_vc_max, 0, 0); + thread_compute_maximum_vc(&thread_vc_max); + VG_(snprintf)(msg, sizeof(msg), + "Discarding ordered segments -- min vc is "); + vc_snprint(msg + VG_(strlen)(msg), sizeof(msg) - VG_(strlen)(msg), + &thread_vc_min); + VG_(snprintf)(msg + VG_(strlen)(msg), sizeof(msg) - VG_(strlen)(msg), + ", max vc is "); + vc_snprint(msg + VG_(strlen)(msg), sizeof(msg) - VG_(strlen)(msg), + &thread_vc_max); + VG_(message)(Vg_DebugMsg, "%s", msg); + vc_cleanup(&thread_vc_max); + } + + for (i = 0; i < sizeof(s_threadinfo) / sizeof(s_threadinfo[0]); i++) + { + struct segment* sg; + struct segment* sg_next; + for (sg = s_threadinfo[i].first; + sg && (sg_next = sg->next) && vc_lte(&sg->vc, &thread_vc_min); + sg = sg_next) + { +#if 0 + VG_(printf)("Discarding a segment of thread %d: ", i); + vc_print(&sg->vc); + VG_(printf)("\n"); #endif - thread_discard_segment(i, sg); - } - } - vc_cleanup(&thread_vc_min); + thread_discard_segment(i, sg); + } + } + vc_cleanup(&thread_vc_min); } void thread_new_segment(ThreadId const threadid) { - static int s_calls_since_last_discard = 0; - struct segment* sg; + static int s_calls_since_last_discard = 0; + struct segment* sg; - tl_assert(0 < threadid && threadid < MAXTHREADS); + tl_assert(0 < threadid && threadid < MAXTHREADS); - if (s_threadinfo[threadid].last) - { - thread_report_races_segment(threadid, s_threadinfo[threadid].last); - } - - sg = sg_new(threadid, threadid); - thread_append_segment(threadid, sg); - - if (++s_calls_since_last_discard > 16) - { - s_calls_since_last_discard = 0; - thread_discard_ordered_segments(); - } + if (s_threadinfo[threadid].last) + { + thread_report_races_segment(threadid, s_threadinfo[threadid].last); + } + + sg = sg_new(threadid, threadid); + thread_append_segment(threadid, sg); + + // if (++s_calls_since_last_discard > 16) + { + s_calls_since_last_discard = 0; + thread_discard_ordered_segments(); + } } void thread_combine_vc(ThreadId joiner, ThreadId joinee) { - tl_assert(joiner != joinee); - tl_assert(0 < joiner && joiner < MAXTHREADS); - tl_assert(0 < joinee && joinee < MAXTHREADS); - tl_assert(s_threadinfo[joiner].last); - tl_assert(s_threadinfo[joinee].last); - vc_combine(&s_threadinfo[joiner].last->vc, &s_threadinfo[joinee].last->vc); - thread_discard_ordered_segments(); + tl_assert(joiner != joinee); + tl_assert(0 < joiner && joiner < MAXTHREADS); + tl_assert(0 < joinee && joinee < MAXTHREADS); + tl_assert(s_threadinfo[joiner].last); + tl_assert(s_threadinfo[joinee].last); + vc_combine(&s_threadinfo[joiner].last->vc, &s_threadinfo[joinee].last->vc); + thread_discard_ordered_segments(); } void thread_print_all(void) { - unsigned i; - struct segment* p; + unsigned i; + struct segment* p; - for (i = 0; i < sizeof(s_threadinfo) / sizeof(s_threadinfo[0]); i++) - { - if (s_threadinfo[i].first) - { - VG_(printf)("**************\n" - "* thread %2d *\n" - "**************\n", - i); - for (p = s_threadinfo[i].first; p; p = p->next) + for (i = 0; i < sizeof(s_threadinfo) / sizeof(s_threadinfo[0]); i++) + { + if (s_threadinfo[i].first) { - sg_print(p); + VG_(printf)("**************\n" + "* thread %2d *\n" + "**************\n", + i); + for (p = s_threadinfo[i].first; p; p = p->next) + { + sg_print(p); + } } - } - } + } } static void show_call_stack(ThreadId const tid, Char const* const msg, ExeContext* const callstack) { - VG_(message)(Vg_UserMsg, - "%s (VG t %d, kernel t %d, POSIX t %d)", - msg, - tid, - VG_(get_tid_lwp)(tid), - VG_(get_pthread_id)(tid)); - if (callstack) - { - VG_(pp_ExeContext)(callstack); - } - else - { - VG_(get_and_pp_StackTrace)(tid, 32/*n_ips*/); - } - VG_(message)(Vg_UserMsg, " "); + VG_(message)(Vg_UserMsg, + "%s (VG t %d, kernel t %d, POSIX t %d)", + msg, + tid, + VG_(get_tid_lwp)(tid), + VG_(get_pthread_id)(tid)); + if (callstack) + { + VG_(pp_ExeContext)(callstack); + } + else + { + VG_(get_and_pp_StackTrace)(tid, 32/*n_ips*/); + } + VG_(message)(Vg_UserMsg, " "); } void thread_report_races(ThreadId const threadid) { - struct segment* p; + struct segment* p; - tl_assert(0 < threadid && threadid < MAXTHREADS); + tl_assert(0 < threadid && threadid < MAXTHREADS); - for (p = s_threadinfo[threadid].first; p; p = p->next) - { - thread_report_races_segment(threadid, p); - } + for (p = s_threadinfo[threadid].first; p; p = p->next) + { + thread_report_races_segment(threadid, p); + } } /** @@ -337,68 +365,74 @@ void thread_report_races_segment(ThreadId const threadid, struct segment* const p) { - unsigned i; + unsigned i; - tl_assert(0 < threadid && threadid < MAXTHREADS); - tl_assert(p); + tl_assert(0 < threadid && threadid < MAXTHREADS); + tl_assert(p); - for (i = 0; i < sizeof(s_threadinfo) / sizeof(s_threadinfo[0]); i++) - { - if (i != threadid) - { - struct segment* q; - for (q = s_threadinfo[i].last; q; q = q->prev) + for (i = 0; i < sizeof(s_threadinfo) / sizeof(s_threadinfo[0]); i++) + { + if (i != threadid) { + struct segment* q; + for (q = s_threadinfo[i].last; q; q = q->prev) + { #if 0 - char msg[256]; - VG_(snprintf)(msg, sizeof(msg), "Examining thread %d (vc ", threadid); - vc_snprint(msg + VG_(strlen)(msg), sizeof(msg) - VG_(strlen)(msg), - &p->vc); - VG_(snprintf)(msg + VG_(strlen)(msg), sizeof(msg) - VG_(strlen)(msg), - ") versus thread %d (vc ", i); - vc_snprint(msg + VG_(strlen)(msg), sizeof(msg) - VG_(strlen)(msg), - &q->vc); - VG_(snprintf)(msg + VG_(strlen)(msg), sizeof(msg) - VG_(strlen)(msg), - ") %d %d", - vc_lte(&p->vc, &q->vc), vc_lte(&q->vc, &p->vc)); - VG_(message)(Vg_DebugMsg, "%s", msg); + char msg[256]; + VG_(snprintf)(msg, sizeof(msg), "Examining thread %d (vc ", threadid); + vc_snprint(msg + VG_(strlen)(msg), sizeof(msg) - VG_(strlen)(msg), + &p->vc); + VG_(snprintf)(msg + VG_(strlen)(msg), sizeof(msg) - VG_(strlen)(msg), + ") versus thread %d (vc ", i); + vc_snprint(msg + VG_(strlen)(msg), sizeof(msg) - VG_(strlen)(msg), + &q->vc); + VG_(snprintf)(msg + VG_(strlen)(msg), sizeof(msg) - VG_(strlen)(msg), + ") %d %d", + vc_lte(&p->vc, &q->vc), vc_lte(&q->vc, &p->vc)); + VG_(message)(Vg_DebugMsg, "%s", msg); #endif - // Since q iterates over the segments of thread i in order of - // decreasing vector clocks, if q->vc <= p->vc, then - // q->next->vc <= p->vc will also hold. Hence, break out of the - // loop once this condition is met. - if (vc_lte(&q->vc, &p->vc)) - break; - if (! vc_lte(&p->vc, &q->vc)) - { - if (bm_has_races(p->bm, q->bm)) - { - VG_(message)(Vg_UserMsg, "Detected data races. Context:"); - tl_assert(p->stacktrace); - show_call_stack(threadid, "1st segment start", p->stacktrace); - show_call_stack(threadid, "1st segment end", - p->next ? p->next->stacktrace : 0); - tl_assert(q->stacktrace); - show_call_stack(i, "2nd segment start", q->stacktrace); - show_call_stack(i, "2nd segment end", - q->next ? q->next->stacktrace : 0); - bm_report_races(threadid, i, p->bm, q->bm); - } - } + // Since q iterates over the segments of thread i in order of + // decreasing vector clocks, if q->vc <= p->vc, then + // q->next->vc <= p->vc will also hold. Hence, break out of the + // loop once this condition is met. + if (vc_lte(&q->vc, &p->vc)) + break; + if (! vc_lte(&p->vc, &q->vc)) + { + if (bm_has_races(p->bm, q->bm)) + { + VG_(message)(Vg_UserMsg, "----------------------------------------------------------------------"); + tl_assert(p->stacktrace); + show_call_stack(threadid, "1st segment start", p->stacktrace); + show_call_stack(threadid, "1st segment end", + p->next ? p->next->stacktrace : 0); + tl_assert(q->stacktrace); + show_call_stack(i, "2nd segment start", q->stacktrace); + show_call_stack(i, "2nd segment end", + q->next ? q->next->stacktrace : 0); + bm_report_races(threadid, i, p->bm, q->bm); + } + } + } } - } - } + } } void thread_report_all_races(void) { - unsigned i; + unsigned i; - for (i = 0; i < sizeof(s_threadinfo) / sizeof(s_threadinfo[0]); i++) - { - if (s_threadinfo[i].last) - { - thread_report_races(i); - } - } + for (i = 0; i < sizeof(s_threadinfo) / sizeof(s_threadinfo[0]); i++) + { + if (s_threadinfo[i].last) + { + thread_report_races(i); + } + } } + +/* + * Local variables: + * c-basic-offset: 3 + * End: + */ ++++++ valgrind-5999.patch -> valgrind-6012.patch ++++++ --- valgrind/valgrind-5999.patch 2006-08-24 14:43:08.000000000 +0200 +++ valgrind/valgrind-6012.patch 2006-08-26 18:06:22.000000000 +0200 @@ -1,6 +1,6 @@ Index: helgrind/hg_main.c =================================================================== ---- helgrind/hg_main.c (revision 5999) +--- helgrind/hg_main.c (revision 6012) +++ helgrind/hg_main.c (working copy) @@ -2857,17 +2857,17 @@ /* Do nothing */ @@ -58,7 +58,7 @@ /*--------------------------------------------------------------------*/ Index: include/pub_tool_tooliface.h =================================================================== ---- include/pub_tool_tooliface.h (revision 5999) +--- include/pub_tool_tooliface.h (revision 6012) +++ include/pub_tool_tooliface.h (working copy) @@ -411,20 +411,32 @@ void VG_(track_post_thread_join) (void(*f)(ThreadId joiner, ThreadId joinee)); @@ -110,7 +110,7 @@ */ Index: include/pub_tool_threadstate.h =================================================================== ---- include/pub_tool_threadstate.h (revision 5999) +--- include/pub_tool_threadstate.h (revision 6012) +++ include/pub_tool_threadstate.h (working copy) @@ -46,6 +46,10 @@ /* Get the TID of the thread which currently has the CPU. */ @@ -125,7 +125,7 @@ /*--------------------------------------------------------------------*/ Index: include/pub_tool_libcprint.h =================================================================== ---- include/pub_tool_libcprint.h (revision 5999) +--- include/pub_tool_libcprint.h (revision 6012) +++ include/pub_tool_libcprint.h (working copy) @@ -39,15 +39,27 @@ * --log-fd/--log-file/--log-socket argument, which defaults to 2 (stderr). @@ -173,7 +173,7 @@ #endif // __PUB_TOOL_LIBCPRINT_H Index: include/pub_tool_debuginfo.h =================================================================== ---- include/pub_tool_debuginfo.h (revision 5999) +--- include/pub_tool_debuginfo.h (revision 6012) +++ include/pub_tool_debuginfo.h (working copy) @@ -135,6 +135,9 @@ @@ -187,7 +187,7 @@ /*--------------------------------------------------------------------*/ Index: include/valgrind.h =================================================================== ---- include/valgrind.h (revision 5999) +--- include/valgrind.h (revision 6012) +++ include/valgrind.h (working copy) @@ -2298,6 +2298,48 @@ VG_USERREQ__STACK_REGISTER = 0x1501, @@ -240,21 +240,28 @@ #if !defined(__GNUC__) Index: include/pub_tool_basics.h =================================================================== ---- include/pub_tool_basics.h (revision 5999) +--- include/pub_tool_basics.h (revision 6012) +++ include/pub_tool_basics.h (working copy) -@@ -97,6 +97,9 @@ +@@ -97,6 +97,16 @@ /* ThreadIds are simply indices into the VG_(threads)[] array. */ typedef UInt ThreadId; -+/* pthread_t as handled internally in valgrind. */ -+typedef UInt PosixThreadId; ++/* A PosixThreadId uniquely identifies a POSIX thread in the client. This ++ datatype must be able to represent any client pthread_t value. The only ++ operations performed on this datatype are copying and comparison (==). ++ Note: the POSIX standard specifies that POSIX thread IDs may be implemented ++ as a struct, and that these must be compared by calling pthread_equal(). ++ Representing POSIX thread IDs by an integer, and comparing these IDs via ++ "==" is a shortcut that works (at least) on Linux. ++ */ ++typedef UWord PosixThreadId; + /* An abstraction of syscall return values. When .isError == False, val holds the return value. When .isError == True, val holds the error code. Index: configure.in =================================================================== ---- configure.in (revision 5999) +--- configure.in (revision 6012) +++ configure.in (working copy) @@ -738,6 +738,9 @@ none/tests/ppc64/Makefile @@ -268,7 +275,7 @@ cat<<EOF Index: Makefile.am =================================================================== ---- Makefile.am (revision 5999) +--- Makefile.am (revision 6012) +++ Makefile.am (working copy) @@ -8,6 +8,7 @@ callgrind \ @@ -280,17 +287,9 @@ # Temporary: we want to compile Helgrind, but not regtest it. Index: coregrind/vg_preloaded.c =================================================================== ---- coregrind/vg_preloaded.c (revision 5999) +--- coregrind/vg_preloaded.c (revision 6012) +++ coregrind/vg_preloaded.c (working copy) -@@ -46,6 +46,7 @@ - #include "pub_core_clreq.h" - #include "pub_core_debuginfo.h" // Needed for pub_core_redir.h - #include "pub_core_redir.h" // For VG_NOTIFY_ON_LOAD -+#include "drd/drd_clientreq.h" - - /* --------------------------------------------------------------------- - Hook for running __libc_freeres once the program exits. -@@ -71,8 +72,6 @@ +@@ -71,8 +71,6 @@ /*--- end ---*/ /*--------------------------------------------------------------------*/ @@ -299,7 +298,7 @@ #define PTH_FUNC(ret_ty, f, args...) \ ret_ty VG_WRAP_FUNCTION_ZZ(libpthreadZdsoZd0,f)(args); \ ret_ty VG_WRAP_FUNCTION_ZZ(libpthreadZdsoZd0,f)(args) -@@ -80,34 +79,159 @@ +@@ -80,34 +78,157 @@ #include <stdio.h> #include <pthread.h> @@ -331,8 +330,6 @@ + + VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__SET_PTHREAD_SELF, + pthread_self(), 0, 0, 0, 0); -+ VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__DRD_START_NEW_SEGMENT, -+ pthread_self(), 0, 0, 0, 0); + return (arg_copy.start)(arg_copy.arg); +} + @@ -469,7 +466,7 @@ return ret; } -@@ -116,15 +240,44 @@ +@@ -116,15 +237,44 @@ pthread_mutex_t *mutex) { int ret; @@ -522,7 +519,7 @@ + */ Index: coregrind/m_syswrap/syswrap-linux.c =================================================================== ---- coregrind/m_syswrap/syswrap-linux.c (revision 5999) +--- coregrind/m_syswrap/syswrap-linux.c (revision 6012) +++ coregrind/m_syswrap/syswrap-linux.c (working copy) @@ -164,7 +164,7 @@ assembler. */ @@ -553,7 +550,7 @@ "sc\n\t" /* exit(tst->os_state.exitcode) */ Index: coregrind/m_tooliface.c =================================================================== ---- coregrind/m_tooliface.c (revision 5999) +--- coregrind/m_tooliface.c (revision 6012) +++ coregrind/m_tooliface.c (working copy) @@ -326,13 +326,21 @@ DEF(track_post_thread_create, ThreadId, ThreadId) @@ -582,7 +579,7 @@ /*--------------------------------------------------------------------*/ Index: coregrind/pub_core_tooliface.h =================================================================== ---- coregrind/pub_core_tooliface.h (revision 5999) +--- coregrind/pub_core_tooliface.h (revision 6012) +++ coregrind/pub_core_tooliface.h (working copy) @@ -205,10 +205,18 @@ void (*track_post_thread_create)(ThreadId, ThreadId); @@ -608,7 +605,7 @@ Index: coregrind/m_debuginfo/debuginfo.c =================================================================== ---- coregrind/m_debuginfo/debuginfo.c (revision 5999) +--- coregrind/m_debuginfo/debuginfo.c (revision 6012) +++ coregrind/m_debuginfo/debuginfo.c (working copy) @@ -912,6 +912,35 @@ return ret; @@ -648,7 +645,7 @@ return si->symtab_used; Index: coregrind/m_threadmodel.c =================================================================== ---- coregrind/m_threadmodel.c (revision 5999) +--- coregrind/m_threadmodel.c (revision 6012) +++ coregrind/m_threadmodel.c (working copy) @@ -807,7 +807,7 @@ if (mx->state == MX_Locked && mx->owner == tid) /* deadlock */ @@ -697,7 +694,7 @@ Index: coregrind/m_scheduler/scheduler.c =================================================================== ---- coregrind/m_scheduler/scheduler.c (revision 5999) +--- coregrind/m_scheduler/scheduler.c (revision 6012) +++ coregrind/m_scheduler/scheduler.c (working copy) @@ -364,7 +364,10 @@ VG_(sigemptyset)(&VG_(threads)[tid].sig_mask); @@ -797,7 +794,7 @@ + */ Index: coregrind/m_threadstate.c =================================================================== ---- coregrind/m_threadstate.c (revision 5999) +--- coregrind/m_threadstate.c (revision 6012) +++ coregrind/m_threadstate.c (working copy) @@ -123,6 +123,41 @@ return VG_INVALID_THREADID; @@ -843,7 +840,7 @@ /*--------------------------------------------------------------------*/ Index: coregrind/pub_core_threadstate.h =================================================================== ---- coregrind/pub_core_threadstate.h (revision 5999) +--- coregrind/pub_core_threadstate.h (revision 6012) +++ coregrind/pub_core_threadstate.h (working copy) @@ -112,6 +112,7 @@ struct { ++++++ valgrind-ppc.diff ++++++ ------------------------------------------------------------------------ r6010 | sewardj | 2006-08-25 13:48:38 +0200 (Fri, 25 Aug 2006) | 2 lines SuSE 10.1 (ppc32/64) fixlet. ------------------------------------------------------------------------ Index: coregrind/m_redir.c =================================================================== --- coregrind/m_redir.c (revision 6009) +++ coregrind/m_redir.c (revision 6010) @@ -762,6 +762,10 @@ void VG_(redir_initialise) ( void ) "ld.so.1", "strcmp", (Addr)&VG_(ppc32_linux_REDIR_FOR_strcmp) ); + add_hardwired_spec( + "ld.so.1", "index", + (Addr)&VG_(ppc32_linux_REDIR_FOR_strchr) + ); } # elif defined(VGP_ppc64_linux) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Remember to have fun... --------------------------------------------------------------------- To unsubscribe, e-mail: opensuse-commit+unsubscribe@opensuse.org For additional commands, e-mail: opensuse-commit+help@opensuse.org
participants (1)
-
root@suse.de