From: <sv...@va...> - 2009-01-31 23:03:14
|
Author: sewardj Date: 2009-01-31 23:03:08 +0000 (Sat, 31 Jan 2009) New Revision: 9095 Log: Merge r9094: Move an assertion (pertaining to showing initial segments to the tools) to the correct place, and add a big comment explaining why this is necessary. Modified: branches/VALGRIND_3_4_BRANCH/coregrind/m_main.c Modified: branches/VALGRIND_3_4_BRANCH/coregrind/m_main.c =================================================================== --- branches/VALGRIND_3_4_BRANCH/coregrind/m_main.c 2009-01-31 15:08:08 UTC (rev 9094) +++ branches/VALGRIND_3_4_BRANCH/coregrind/m_main.c 2009-01-31 23:03:08 UTC (rev 9095) @@ -1870,8 +1870,29 @@ NSegment const* seg = VG_(am_find_nsegment)( seg_starts[i] ); vg_assert(seg); - vg_assert(seg->start == seg_starts[i] ); if (seg->kind == SkFileC || seg->kind == SkAnonC) { + /* This next assertion is tricky. If it is placed + immediately before this 'if', it very occasionally fails. + Why? Because previous iterations of the loop may have + caused tools (via the new_mem_startup calls) to do + dynamic memory allocation, and that may affect the mapped + segments; in particular it may cause segment merging to + happen. Hence we cannot assume that seg_starts[i], which + reflects the state of the world before we started this + loop, is the same as seg->start, as the latter reflects + the state of the world (viz, mappings) at this particular + iteration of the loop. + + Why does moving it inside the 'if' make it safe? Because + any dynamic memory allocation done by the tools will + affect only the state of Valgrind-owned segments, not of + Client-owned segments. And the 'if' guards against that + -- we only get in here for Client-owned segments. + + In other words: the loop may change the state of + Valgrind-owned segments as it proceeds. But it should + not cause the Client-owned segments to change. */ + vg_assert(seg->start == seg_starts[i]); VG_(debugLog)(2, "main", "tell tool about %010lx-%010lx %c%c%c\n", seg->start, seg->end, |