This fixes a bug in Helgrind in which all memory access by syscalls was being treated as if it were happening in thread 1. This is because the eraser_mem_read/write functions were using get_current_tid_1_if_root() to get the current tid. Unfortunately, during syscalls there is no current thread, so it was getting 1_if_root. This patch fixes this by using what thread ID information we're given, and only using get_current_tid() if we're recording a memory access performed by code (rather than by a syscall). coregrind/vg_scheduler.c | 6 ++++++ helgrind/hg_main.c | 35 ++++++++++++++++++++++------------- include/vg_skin.h | 2 ++ 3 files changed, 30 insertions(+), 13 deletions(-) --- valgrind/helgrind/hg_main.c~14-hg-tid Fri Oct 18 16:13:48 2002 +++ valgrind-jsgf/helgrind/hg_main.c Fri Oct 18 16:26:21 2002 @@ -748,28 +748,30 @@ static void copy_address_range_state(Add } // SSS: put these somewhere better -static void eraser_mem_read (Addr a, UInt data_size); -static void eraser_mem_write(Addr a, UInt data_size); +static void eraser_mem_read (Addr a, UInt data_size, ThreadId tid); +static void eraser_mem_write(Addr a, UInt data_size, ThreadId tid); +static void eraser_mem_read_notid (Addr a, UInt data_size); +static void eraser_mem_write_notid(Addr a, UInt data_size); static void eraser_pre_mem_read(CorePart part, ThreadState* tst, Char* s, UInt base, UInt size ) { - eraser_mem_read(base, size); + eraser_mem_read(base, size, VG_(get_tid_from_ThreadState)(tst)); } static void eraser_pre_mem_read_asciiz(CorePart part, ThreadState* tst, Char* s, UInt base ) { - eraser_mem_read(base, VG_(strlen)((Char*)base)); + eraser_mem_read(base, VG_(strlen)((Char*)base), VG_(get_tid_from_ThreadState)(tst)); } static void eraser_pre_mem_write(CorePart part, ThreadState* tst, Char* s, UInt base, UInt size ) { - eraser_mem_write(base, size); + eraser_mem_write(base, size, VG_(get_tid_from_ThreadState)(tst)); } @@ -889,7 +891,7 @@ UCodeBlock* SK_(instrument) ( UCodeBlock 8 == u_in->size || 10 == u_in->size); uInstr2(cb, CCALL, 0, TempReg, u_in->val1, TempReg, t_size); // SSS: make regparms(2) eventually... - uCCall(cb, (Addr) & eraser_mem_read, 2, 0, False); + uCCall(cb, (Addr) & eraser_mem_read_notid, 2, 0, False); VG_(copy_UInstr)(cb, u_in); t_size = INVALID_TEMPREG; break; @@ -903,7 +905,7 @@ UCodeBlock* SK_(instrument) ( UCodeBlock sk_assert(1 == u_in->size || 2 == u_in->size || 4 == u_in->size || 8 == u_in->size || 10 == u_in->size); uInstr2(cb, CCALL, 0, TempReg, u_in->val2, TempReg, t_size); - uCCall(cb, (Addr) & eraser_mem_write, 2, 0, False); + uCCall(cb, (Addr) & eraser_mem_write_notid, 2, 0, False); VG_(copy_UInstr)(cb, u_in); t_size = INVALID_TEMPREG; break; @@ -1194,10 +1196,9 @@ Int compute_num_words_accessed(Addr a, U #endif -static void eraser_mem_read(Addr a, UInt size) +static void eraser_mem_read(Addr a, UInt size, ThreadId tid) { shadow_word* sword; - ThreadId tid = VG_(get_current_tid_1_if_root)(); Addr end = a + 4*compute_num_words_accessed(a, size); for ( ; a < end; a += 4) { @@ -1262,10 +1263,9 @@ static void eraser_mem_read(Addr a, UInt } -static void eraser_mem_write(Addr a, UInt size) +static void eraser_mem_write(Addr a, UInt size, ThreadId tid) { shadow_word* sword; - ThreadId tid = VG_(get_current_tid_1_if_root)(); Addr end = a + 4*compute_num_words_accessed(a, size); for ( ; a < end; a += 4) { @@ -1325,6 +1325,15 @@ static void eraser_mem_write(Addr a, UIn #undef DEBUG_STATE +static void eraser_mem_read_notid(Addr a, UInt size) +{ + eraser_mem_read(a, size, VG_(get_current_tid)()); +} + +static void eraser_mem_write_notid(Addr a, UInt size) +{ + eraser_mem_write(a, size, VG_(get_current_tid)()); +} /*--------------------------------------------------------------------*/ /*--- Setup ---*/ @@ -1373,8 +1382,8 @@ void SK_(pre_clo_init)(VgDetails* detail track->post_mutex_lock = & eraser_post_mutex_lock; track->post_mutex_unlock = & eraser_post_mutex_unlock; - VG_(register_compact_helper)((Addr) & eraser_mem_read); - VG_(register_compact_helper)((Addr) & eraser_mem_write); + VG_(register_compact_helper)((Addr) & eraser_mem_read_notid); + VG_(register_compact_helper)((Addr) & eraser_mem_write_notid); /* Init lock table */ for (i = 0; i < VG_N_THREADS; i++) --- valgrind/coregrind/vg_scheduler.c~14-hg-tid Fri Oct 18 16:13:58 2002 +++ valgrind-jsgf/coregrind/vg_scheduler.c Fri Oct 18 16:29:35 2002 @@ -389,6 +389,12 @@ ThreadId VG_(get_current_tid_1_if_root) return vg_tid_currently_in_baseBlock; } +ThreadId VG_(get_tid_from_ThreadState) (ThreadState* tst) +{ + vg_assert(tst >= &VG_(threads)[1] && tst < &VG_(threads)[VG_N_THREADS]); + return tst->tid; +} + /* Copy the saved state of a thread into VG_(baseBlock), ready for it to be run. */ --- valgrind/include/vg_skin.h~14-hg-tid Fri Oct 18 16:14:01 2002 +++ valgrind-jsgf/include/vg_skin.h Fri Oct 18 16:24:20 2002 @@ -253,7 +253,9 @@ typedef struct _ThreadState ThreadState; +extern ThreadId VG_(get_current_tid) ( void ); extern ThreadId VG_(get_current_tid_1_if_root) ( void ); +extern ThreadId VG_(get_tid_from_ThreadState) ( ThreadState* ); extern ThreadState* VG_(get_ThreadState) ( ThreadId tid ); .