You can subscribe to this list here.
| 2002 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
(1) |
Oct
(122) |
Nov
(152) |
Dec
(69) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2003 |
Jan
(6) |
Feb
(25) |
Mar
(73) |
Apr
(82) |
May
(24) |
Jun
(25) |
Jul
(10) |
Aug
(11) |
Sep
(10) |
Oct
(54) |
Nov
(203) |
Dec
(182) |
| 2004 |
Jan
(307) |
Feb
(305) |
Mar
(430) |
Apr
(312) |
May
(187) |
Jun
(342) |
Jul
(487) |
Aug
(637) |
Sep
(336) |
Oct
(373) |
Nov
(441) |
Dec
(210) |
| 2005 |
Jan
(385) |
Feb
(480) |
Mar
(636) |
Apr
(544) |
May
(679) |
Jun
(625) |
Jul
(810) |
Aug
(838) |
Sep
(634) |
Oct
(521) |
Nov
(965) |
Dec
(543) |
| 2006 |
Jan
(494) |
Feb
(431) |
Mar
(546) |
Apr
(411) |
May
(406) |
Jun
(322) |
Jul
(256) |
Aug
(401) |
Sep
(345) |
Oct
(542) |
Nov
(308) |
Dec
(481) |
| 2007 |
Jan
(427) |
Feb
(326) |
Mar
(367) |
Apr
(255) |
May
(244) |
Jun
(204) |
Jul
(223) |
Aug
(231) |
Sep
(354) |
Oct
(374) |
Nov
(497) |
Dec
(362) |
| 2008 |
Jan
(322) |
Feb
(482) |
Mar
(658) |
Apr
(422) |
May
(476) |
Jun
(396) |
Jul
(455) |
Aug
(267) |
Sep
(280) |
Oct
(253) |
Nov
(232) |
Dec
(304) |
| 2009 |
Jan
(486) |
Feb
(470) |
Mar
(458) |
Apr
(423) |
May
(696) |
Jun
(461) |
Jul
(551) |
Aug
(575) |
Sep
(134) |
Oct
(110) |
Nov
(157) |
Dec
(102) |
| 2010 |
Jan
(226) |
Feb
(86) |
Mar
(147) |
Apr
(117) |
May
(107) |
Jun
(203) |
Jul
(193) |
Aug
(238) |
Sep
(300) |
Oct
(246) |
Nov
(23) |
Dec
(75) |
| 2011 |
Jan
(133) |
Feb
(195) |
Mar
(315) |
Apr
(200) |
May
(267) |
Jun
(293) |
Jul
(353) |
Aug
(237) |
Sep
(278) |
Oct
(611) |
Nov
(274) |
Dec
(260) |
| 2012 |
Jan
(303) |
Feb
(391) |
Mar
(417) |
Apr
(441) |
May
(488) |
Jun
(655) |
Jul
(590) |
Aug
(610) |
Sep
(526) |
Oct
(478) |
Nov
(359) |
Dec
(372) |
| 2013 |
Jan
(467) |
Feb
(226) |
Mar
(391) |
Apr
(281) |
May
(299) |
Jun
(252) |
Jul
(311) |
Aug
(352) |
Sep
(481) |
Oct
(571) |
Nov
(222) |
Dec
(231) |
| 2014 |
Jan
(185) |
Feb
(329) |
Mar
(245) |
Apr
(238) |
May
(281) |
Jun
(399) |
Jul
(382) |
Aug
(500) |
Sep
(579) |
Oct
(435) |
Nov
(487) |
Dec
(256) |
| 2015 |
Jan
(338) |
Feb
(357) |
Mar
(330) |
Apr
(294) |
May
(191) |
Jun
(108) |
Jul
(142) |
Aug
(261) |
Sep
(190) |
Oct
(54) |
Nov
(83) |
Dec
(22) |
| 2016 |
Jan
(49) |
Feb
(89) |
Mar
(33) |
Apr
(50) |
May
(27) |
Jun
(34) |
Jul
(53) |
Aug
(53) |
Sep
(98) |
Oct
(206) |
Nov
(93) |
Dec
(53) |
| 2017 |
Jan
(65) |
Feb
(82) |
Mar
(102) |
Apr
(86) |
May
(187) |
Jun
(67) |
Jul
(23) |
Aug
(93) |
Sep
(65) |
Oct
(45) |
Nov
(35) |
Dec
(17) |
| 2018 |
Jan
(26) |
Feb
(35) |
Mar
(38) |
Apr
(32) |
May
(8) |
Jun
(43) |
Jul
(27) |
Aug
(30) |
Sep
(43) |
Oct
(42) |
Nov
(38) |
Dec
(67) |
| 2019 |
Jan
(32) |
Feb
(37) |
Mar
(53) |
Apr
(64) |
May
(49) |
Jun
(18) |
Jul
(14) |
Aug
(53) |
Sep
(25) |
Oct
(30) |
Nov
(49) |
Dec
(31) |
| 2020 |
Jan
(87) |
Feb
(45) |
Mar
(37) |
Apr
(51) |
May
(99) |
Jun
(36) |
Jul
(11) |
Aug
(14) |
Sep
(20) |
Oct
(24) |
Nov
(40) |
Dec
(23) |
| 2021 |
Jan
(14) |
Feb
(53) |
Mar
(85) |
Apr
(15) |
May
(19) |
Jun
(3) |
Jul
(14) |
Aug
(1) |
Sep
(57) |
Oct
(73) |
Nov
(56) |
Dec
(22) |
| 2022 |
Jan
(3) |
Feb
(22) |
Mar
(6) |
Apr
(55) |
May
(46) |
Jun
(39) |
Jul
(15) |
Aug
(9) |
Sep
(11) |
Oct
(34) |
Nov
(20) |
Dec
(36) |
| 2023 |
Jan
(79) |
Feb
(41) |
Mar
(99) |
Apr
(169) |
May
(48) |
Jun
(16) |
Jul
(16) |
Aug
(57) |
Sep
(32) |
Oct
|
Nov
|
Dec
|
|
From: Julian S. <se...@so...> - 2023-01-04 16:44:55
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=394ca9b400d7b69942967cce0fa89a344558c8c5 commit 394ca9b400d7b69942967cce0fa89a344558c8c5 Author: Julian Seward <js...@ac...> Date: Wed Jan 4 17:43:21 2023 +0100 Remove a debugging line `if (0) ..` that mistakenly got landed in fa3a9cc43c22593c70796a99aff33bb9436ad448. Diff: --- dhat/dh_main.c | 1 - 1 file changed, 1 deletion(-) diff --git a/dhat/dh_main.c b/dhat/dh_main.c index 5ae3fd29ac..6f15ae82e3 100644 --- a/dhat/dh_main.c +++ b/dhat/dh_main.c @@ -1245,7 +1245,6 @@ static Bool dh_handle_client_request(ThreadId tid, UWord* arg, UWord* ret) } default: - if (0) VG_(message)( Vg_UserMsg, "Warning: unknown DHAT client request code %llx\n", |
|
From: Julian S. <se...@so...> - 2023-01-04 16:19:13
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=1b8d0cbc813e936e96e76390873fbe9bc2fc4d83 commit 1b8d0cbc813e936e96e76390873fbe9bc2fc4d83 Author: Julian Seward <js...@ac...> Date: Wed Jan 4 17:12:21 2023 +0100 Fix 64-bit uncleanness in VG_(get_bbs_translated)/VG_(get_bbs_discarded_or_dumped) .. .. and some debug printing associated with them. I don't think this affects anything apart from debug printing. Noticed when running a x86 (32-bit) Firefox build. Diff: --- coregrind/m_translate.c | 2 +- coregrind/m_transtab.c | 4 ++-- coregrind/pub_core_transtab.h | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/coregrind/m_translate.c b/coregrind/m_translate.c index 60d5a05c86..8ae06d2a67 100644 --- a/coregrind/m_translate.c +++ b/coregrind/m_translate.c @@ -1597,7 +1597,7 @@ Bool VG_(translate) ( ThreadId tid, Bool ok = VG_(get_fnname_w_offset)(ep, addr, &fnname); if (!ok) fnname = "UNKNOWN_FUNCTION"; VG_(printf)( - "==== SB %u (evchecks %llu) [tid %u] 0x%lx %s %s%c0x%lx\n", + "==== SB %llu (evchecks %llu) [tid %u] 0x%lx %s %s%c0x%lx\n", VG_(get_bbs_translated)(), bbs_done, tid, addr, fnname, objname, objoff >= 0 ? '+' : '-', (UWord)(objoff >= 0 ? objoff : -objoff) diff --git a/coregrind/m_transtab.c b/coregrind/m_transtab.c index 09a3da02ba..384461289d 100644 --- a/coregrind/m_transtab.c +++ b/coregrind/m_transtab.c @@ -2664,12 +2664,12 @@ static Double safe_idiv( ULong a, ULong b ) return (b == 0 ? 0 : (Double)a / (Double)b); } -UInt VG_(get_bbs_translated) ( void ) +ULong VG_(get_bbs_translated) ( void ) { return n_in_count; } -UInt VG_(get_bbs_discarded_or_dumped) ( void ) +ULong VG_(get_bbs_discarded_or_dumped) ( void ) { return n_disc_count + n_dump_count; } diff --git a/coregrind/pub_core_transtab.h b/coregrind/pub_core_transtab.h index 1470b7afbe..6cc11f6580 100644 --- a/coregrind/pub_core_transtab.h +++ b/coregrind/pub_core_transtab.h @@ -200,8 +200,8 @@ extern void VG_(discard_translations) ( Addr start, ULong range, extern void VG_(print_tt_tc_stats) ( void ); -extern UInt VG_(get_bbs_translated) ( void ); -extern UInt VG_(get_bbs_discarded_or_dumped) ( void ); +extern ULong VG_(get_bbs_translated) ( void ); +extern ULong VG_(get_bbs_discarded_or_dumped) ( void ); /* Add to / search the auxiliary, small, unredirected translation table. */ |
|
From: Julian S. <se...@so...> - 2023-01-04 16:07:05
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=fe4e6578d451327829a6908a01bb27995c198acb commit fe4e6578d451327829a6908a01bb27995c198acb Author: Julian Seward <js...@ac...> Date: Wed Jan 4 17:04:03 2023 +0100 amd64 and x86 front ends: add a few more spec rules. amd64: S and NS after LOGICQ (per comments from Eyal Soha on the dev list) S after SHLQ NZ after SHLL x86: NZ after SHRL Z after SHLL I would have liked to have added the inverse conditions in all cases (eg, both S and NS, or both Z and NZ), but finding use cases for some of these is almost impossible, hence they are sometimes omitted. All of the added cases have been tested. Diff: --- VEX/priv/guest_amd64_helpers.c | 35 +++++++++++++++++++++++++++-------- VEX/priv/guest_x86_helpers.c | 17 ++++++++++++++++- 2 files changed, 43 insertions(+), 9 deletions(-) diff --git a/VEX/priv/guest_amd64_helpers.c b/VEX/priv/guest_amd64_helpers.c index abd2a1e370..42ec80e036 100644 --- a/VEX/priv/guest_amd64_helpers.c +++ b/VEX/priv/guest_amd64_helpers.c @@ -1684,6 +1684,19 @@ IRExpr* guest_amd64_spechelper ( const HChar* function_name, mkU64(0))); } + // Verified + if (isU64(cc_op, AMD64G_CC_OP_LOGICQ) && isU64(cond, AMD64CondS)) { + /* long long and/or/xor, then S --> (ULong)result[63] */ + return binop(Iop_Shr64, cc_dep1, mkU8(63)); + } + // Verified + if (isU64(cc_op, AMD64G_CC_OP_LOGICQ) && isU64(cond, AMD64CondNS)) { + /* long long and/or/xor, then S --> (ULong) ~ result[63] */ + return binop(Iop_Xor64, + binop(Iop_Shr64, cc_dep1, mkU8(63)), + mkU64(1)); + } + /*---------------- LOGICL ----------------*/ if (isU64(cc_op, AMD64G_CC_OP_LOGICL) && isU64(cond, AMD64CondZ)) { @@ -1932,10 +1945,12 @@ IRExpr* guest_amd64_spechelper ( const HChar* function_name, binop(Iop_CmpNE64, cc_dep1, mkU64(0))); } - //if (isU64(cc_op, AMD64G_CC_OP_SHLQ) && isU64(cond, AMD64CondS)) { - // /* SHLQ, then S --> (ULong)result[63] */ - // vassert(0); - //} + // Verified + if (isU64(cc_op, AMD64G_CC_OP_SHLQ) && isU64(cond, AMD64CondS)) { + /* SHLQ, then S --> (ULong)result[63] */ + return binop(Iop_Shr64, cc_dep1, mkU8(63)); + } + // No known test case //if (isU64(cc_op, AMD64G_CC_OP_SHLQ) && isU64(cond, AMD64CondNS)) { // /* SHLQ, then NS --> (ULong) ~ result[63] */ // vassert(0); @@ -1949,10 +1964,13 @@ IRExpr* guest_amd64_spechelper ( const HChar* function_name, binop(Iop_CmpEQ32, unop(Iop_64to32, cc_dep1), mkU32(0))); } - //if (isU64(cc_op, AMD64G_CC_OP_SHLL) && isU64(cond, AMD64CondNZ)) { - // /* SHLL, then NZ --> test dep1 != 0 */ - // vassert(0); - //} + // Verified + if (isU64(cc_op, AMD64G_CC_OP_SHLL) && isU64(cond, AMD64CondNZ)) { + /* SHLL, then NZ --> test dep1 != 0 */ + return unop(Iop_1Uto64, + binop(Iop_CmpNE32, unop(Iop_64to32, cc_dep1), + mkU32(0))); + } if (isU64(cc_op, AMD64G_CC_OP_SHLL) && isU64(cond, AMD64CondS)) { /* SHLL, then S --> (ULong)result[31] */ @@ -1960,6 +1978,7 @@ IRExpr* guest_amd64_spechelper ( const HChar* function_name, binop(Iop_Shr64, cc_dep1, mkU8(31)), mkU64(1)); } + // No known test case //if (isU64(cc_op, AMD64G_CC_OP_SHLL) && isU64(cond, AMD64CondNS)) { // /* SHLL, then NS --> (ULong) ~ result[31] */ // vassert(0); diff --git a/VEX/priv/guest_x86_helpers.c b/VEX/priv/guest_x86_helpers.c index 7b229cb795..a1d086369d 100644 --- a/VEX/priv/guest_x86_helpers.c +++ b/VEX/priv/guest_x86_helpers.c @@ -1203,9 +1203,24 @@ IRExpr* guest_x86_spechelper ( const HChar* function_name, /*---------------- SHRL ----------------*/ if (isU32(cc_op, X86G_CC_OP_SHRL) && isU32(cond, X86CondZ)) { - /* SHRL, then Z --> test dep1 == 0 */ + /* SHRL, then Z --> test dep1(result) == 0 */ return unop(Iop_1Uto32,binop(Iop_CmpEQ32, cc_dep1, mkU32(0))); } + if (isU32(cc_op, X86G_CC_OP_SHRL) && isU32(cond, X86CondNZ)) { + /* SHRL, then NZ --> test dep1(result) != 0 */ + return unop(Iop_1Uto32,binop(Iop_CmpNE32, cc_dep1, mkU32(0))); + } + + /*---------------- SHLL ----------------*/ + + if (isU32(cc_op, X86G_CC_OP_SHLL) && isU32(cond, X86CondZ)) { + /* SHLL, then Z --> test dep1(result) == 0 */ + return unop(Iop_1Uto32,binop(Iop_CmpEQ32, cc_dep1, mkU32(0))); + } + //if (isU32(cc_op, X86G_CC_OP_SHLL) && isU32(cond, X86CondNZ)) { + // /* SHLL, then NZ --> test dep1(result) != 0 */ + // vassert(0); // No test case yet observed + //} /*---------------- COPY ----------------*/ /* This can happen, as a result of x87 FP compares: "fcom ... ; |
|
From: Julian S. <se...@so...> - 2023-01-04 15:34:55
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=d99a6f70e2e8bce1eaef0038f3b36e627255d68f commit d99a6f70e2e8bce1eaef0038f3b36e627255d68f Author: Julian Seward <js...@ac...> Date: Wed Jan 4 16:32:03 2023 +0100 Memcheck: handle origin data for 8-/16-bit shadow stores a bit more accurately. With origin tracking enabled, 8- and 16-bit stores could sometimes lose origin info unnecessarily. This patch removes this avoidable lossage. (Since MC only stores 1 origin value for each 32-bit word of address space, there is still unavoidable lossage of origins in some cases; this patch does not help in those cases since it's a fundamental design limitation.) Diff: --- memcheck/mc_main.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/memcheck/mc_main.c b/memcheck/mc_main.c index fe15d23321..8efd7cb40c 100644 --- a/memcheck/mc_main.c +++ b/memcheck/mc_main.c @@ -79,6 +79,10 @@ static void ocache_sarp_Clear_Origins ( Addr, UWord ); /* fwds */ paths */ #define OC_ENABLE_ASSERTIONS 0 +/* Change this to 1 for experimental, higher precision origin tracking + 8- and 16-bit store handling. */ +#define OC_PRECISION_STORE 1 + /*------------------------------------------------------------*/ /*--- Comments on the origin tracking implementation ---*/ @@ -7655,12 +7659,31 @@ void VG_REGPARM(2) MC_(helperc_b_store1)( Addr a, UWord d32 ) { line = find_OCacheLine( a ); +#if OC_PRECISION_STORE + if (LIKELY(d32 == 0)) { + // The byte is defined. Just mark it as so in the descr and leave the w32 + // unchanged. This may make the descr become zero, so the line no longer + // contains useful info, but that's OK. No loss of information. + line->u.main.descr[lineoff] &= ~(1 << byteoff); + } else if (d32 == line->u.main.w32[lineoff]) { + // At least one of the four bytes in the w32 is undefined with the same + // origin. Just extend the mask. No loss of information. + line->u.main.descr[lineoff] |= (1 << byteoff); + } else { + // Here, we have a conflict: at least one byte in the group is undefined + // but with some other origin. We can't represent both origins, so we + // forget about the previous origin and install this one instead. + line->u.main.descr[lineoff] = (1 << byteoff); + line->u.main.w32[lineoff] = d32; + } +#else if (d32 == 0) { line->u.main.descr[lineoff] &= ~(1 << byteoff); } else { line->u.main.descr[lineoff] |= (1 << byteoff); line->u.main.w32[lineoff] = d32; } +#endif } void VG_REGPARM(2) MC_(helperc_b_store2)( Addr a, UWord d32 ) { @@ -7683,12 +7706,25 @@ void VG_REGPARM(2) MC_(helperc_b_store2)( Addr a, UWord d32 ) { line = find_OCacheLine( a ); +#if OC_PRECISION_STORE + // Same logic as in the store1 case above. + if (LIKELY(d32 == 0)) { + line->u.main.descr[lineoff] &= ~(3 << byteoff); + } else if (d32 == line->u.main.w32[lineoff]) { + line->u.main.descr[lineoff] |= (3 << byteoff); + line->u.main.w32[lineoff] = d32; + } else { + line->u.main.descr[lineoff] = (3 << byteoff); + line->u.main.w32[lineoff] = d32; + } +#else if (d32 == 0) { line->u.main.descr[lineoff] &= ~(3 << byteoff); } else { line->u.main.descr[lineoff] |= (3 << byteoff); line->u.main.w32[lineoff] = d32; } +#endif } void VG_REGPARM(2) MC_(helperc_b_store4)( Addr a, UWord d32 ) { |
|
From: Julian S. <se...@so...> - 2023-01-04 15:12:14
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=fa3a9cc43c22593c70796a99aff33bb9436ad448 commit fa3a9cc43c22593c70796a99aff33bb9436ad448 Author: Julian Seward <js...@ac...> Date: Wed Jan 4 15:38:12 2023 +0100 DHAT: increase the size of the cache for `find_Block_containing` from 2 to 3. In the hope of making DHAT a bit faster. Diff: --- dhat/dh_main.c | 52 ++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 38 insertions(+), 14 deletions(-) diff --git a/dhat/dh_main.c b/dhat/dh_main.c index 69e6fb6d01..5ae3fd29ac 100644 --- a/dhat/dh_main.c +++ b/dhat/dh_main.c @@ -151,11 +151,14 @@ static Word interval_tree_Cmp ( UWord k1, UWord k2 ) return 0; } -// 2-entry cache for find_Block_containing +// 3-entry cache for find_Block_containing static Block* fbc_cache0 = NULL; static Block* fbc_cache1 = NULL; +static Block* fbc_cache2 = NULL; -static UWord stats__n_fBc_cached = 0; +static UWord stats__n_fBc_cached0 = 0; +static UWord stats__n_fBc_cached1 = 0; +static UWord stats__n_fBc_cached2 = 0; static UWord stats__n_fBc_uncached = 0; static UWord stats__n_fBc_notfound = 0; @@ -167,19 +170,30 @@ static Block* find_Block_containing ( Addr a ) && fbc_cache0->payload <= a && a < fbc_cache0->payload + fbc_cache0->req_szB)) { // found at 0 - stats__n_fBc_cached++; + stats__n_fBc_cached0++; return fbc_cache0; } if (LIKELY(fbc_cache1 && fbc_cache1->payload <= a && a < fbc_cache1->payload + fbc_cache1->req_szB)) { // found at 1; swap 0 and 1 - Block* tmp = fbc_cache0; - fbc_cache0 = fbc_cache1; + Block* tmp = fbc_cache1; + fbc_cache1 = fbc_cache0; + fbc_cache0 = tmp; + stats__n_fBc_cached1++; + return tmp; + } + if (LIKELY(fbc_cache2 + && fbc_cache2->payload <= a + && a < fbc_cache2->payload + fbc_cache2->req_szB)) { + // found at 2; swap 1 and 2 + Block* tmp = fbc_cache2; + fbc_cache2 = fbc_cache1; fbc_cache1 = tmp; - stats__n_fBc_cached++; - return fbc_cache0; + stats__n_fBc_cached2++; + return tmp; } + Block fake; fake.payload = a; fake.req_szB = 1; @@ -196,6 +210,7 @@ static Block* find_Block_containing ( Addr a ) Block* res = (Block*)foundkey; tl_assert(res != &fake); // put at the top position + fbc_cache2 = fbc_cache1; fbc_cache1 = fbc_cache0; fbc_cache0 = res; stats__n_fBc_uncached++; @@ -214,7 +229,7 @@ static void delete_Block_starting_at ( Addr a ) Bool found = VG_(delFromFM)( interval_tree, NULL, NULL, (Addr)&fake ); tl_assert(found); - fbc_cache0 = fbc_cache1 = NULL; + fbc_cache0 = fbc_cache1 = fbc_cache2 = NULL; } //------------------------------------------------------------// @@ -600,7 +615,7 @@ void* new_block ( ThreadId tid, void* p, SizeT req_szB, SizeT req_alignB, Bool present = VG_(addToFM)( interval_tree, (UWord)bk, (UWord)0/*no val*/); tl_assert(!present); - fbc_cache0 = fbc_cache1 = NULL; + fbc_cache0 = fbc_cache1 = fbc_cache2 = NULL; intro_Block(bk); @@ -727,7 +742,7 @@ void* renew_block ( ThreadId tid, void* p_old, SizeT new_req_szB ) Bool present = VG_(addToFM)( interval_tree, (UWord)bk, (UWord)0/*no val*/); tl_assert(!present); - fbc_cache0 = fbc_cache1 = NULL; + fbc_cache0 = fbc_cache1 = fbc_cache2 = NULL; } return p_new; @@ -1230,6 +1245,7 @@ static Bool dh_handle_client_request(ThreadId tid, UWord* arg, UWord* ret) } default: + if (0) VG_(message)( Vg_UserMsg, "Warning: unknown DHAT client request code %llx\n", @@ -1609,11 +1625,17 @@ static void dh_fini(Int exit_status) // Stats. if (VG_(clo_stats)) { VG_(dmsg)(" dhat: find_Block_containing:\n"); - VG_(dmsg)(" found: %'lu (%'lu cached + %'lu uncached)\n", - stats__n_fBc_cached + stats__n_fBc_uncached, - stats__n_fBc_cached, + VG_(dmsg)(" dhat: found: %'lu\n", + stats__n_fBc_cached0 + stats__n_fBc_cached1 + + stats__n_fBc_cached2 + + stats__n_fBc_uncached); + VG_(dmsg)(" dhat: at cache0 %'14lu at cache1 %'14lu\n", + stats__n_fBc_cached0, + stats__n_fBc_cached1); + VG_(dmsg)(" dhat: at cache2 %'14lu uncached %'14lu\n", + stats__n_fBc_cached2, stats__n_fBc_uncached); - VG_(dmsg)(" notfound: %'lu\n", stats__n_fBc_notfound); + VG_(dmsg)(" dhat: notfound: %'lu\n", stats__n_fBc_notfound); VG_(dmsg)("\n"); } } @@ -1777,6 +1799,7 @@ static void dh_pre_clo_init(void) VG_(details_copyright_author)( "Copyright (C) 2010-2018, and GNU GPL'd, by Mozilla Foundation"); VG_(details_bug_reports_to) (VG_BUGS_TO); + VG_(details_avg_translation_sizeB) ( 600 ); // Basic functions. VG_(basic_tool_funcs) (dh_post_clo_init, @@ -1811,6 +1834,7 @@ static void dh_pre_clo_init(void) tl_assert(!interval_tree); tl_assert(!fbc_cache0); tl_assert(!fbc_cache1); + tl_assert(!fbc_cache2); interval_tree = VG_(newFM)( VG_(malloc), "dh.interval_tree.1", |
|
From: Paul F. <pa...@so...> - 2023-01-03 20:29:31
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=74e20007467b930fb14264519f74a45179b5f740 commit 74e20007467b930fb14264519f74a45179b5f740 Author: Paul Floyd <pj...@wa...> Date: Tue Jan 3 21:28:42 2023 +0100 Bug 327548 - false positive while destroying mutex Diff: --- .gitignore | 1 + NEWS | 1 + helgrind/hg_intercepts.c | 4 +++ helgrind/tests/Makefile.am | 2 ++ helgrind/tests/bug327548.c | 50 +++++++++++++++++++++++++++++++++++++ helgrind/tests/bug327548.stderr.exp | 0 helgrind/tests/bug327548.vgtest | 2 ++ 7 files changed, 60 insertions(+) diff --git a/.gitignore b/.gitignore index 20282b8a20..4277dd2a6f 100644 --- a/.gitignore +++ b/.gitignore @@ -653,6 +653,7 @@ /helgrind/tests/bar_bad /helgrind/tests/bar_trivial /helgrind/tests/bug322621 +/helgrind/tests/bug327548 /helgrind/tests/bug392331 /helgrind/tests/cond_init_destroy /helgrind/tests/cond_timedwait_invalid diff --git a/NEWS b/NEWS index f73541187a..27fe0df194 100644 --- a/NEWS +++ b/NEWS @@ -40,6 +40,7 @@ than mailing the developers (or mailing lists) directly -- bugs that are not entered into bugzilla tend to get forgotten about or ignored. 170510 Don't warn about ioctl of size 0 without direction hint +327548 false positive while destroying mutex 351857 confusing error message about valid command line option 392331 Spurious lock not held error from inside pthread_cond_timedwait 400793 pthread_rwlock_timedwrlock false positive diff --git a/helgrind/hg_intercepts.c b/helgrind/hg_intercepts.c index 5a83996e36..8c98e4ee03 100644 --- a/helgrind/hg_intercepts.c +++ b/helgrind/hg_intercepts.c @@ -879,7 +879,9 @@ static int mutex_destroy_WRK(pthread_mutex_t *mutex) if (mutex != NULL) { static const pthread_mutex_t mutex_init = PTHREAD_MUTEX_INITIALIZER; + VALGRIND_HG_DISABLE_CHECKING(mutex, sizeof(*mutex)); mutex_is_init = my_memcmp(mutex, &mutex_init, sizeof(*mutex)) == 0; + VALGRIND_HG_ENABLE_CHECKING(mutex, sizeof(*mutex)); } else { mutex_is_init = 0; } @@ -1785,7 +1787,9 @@ static int pthread_cond_destroy_WRK(pthread_cond_t* cond) if (cond != NULL) { const pthread_cond_t cond_init = PTHREAD_COND_INITIALIZER; + VALGRIND_HG_DISABLE_CHECKING(cond, sizeof(*cond)); cond_is_init = my_memcmp(cond, &cond_init, sizeof(*cond)) == 0; + VALGRIND_HG_ENABLE_CHECKING(cond, sizeof(*cond)); } else { cond_is_init = 0; } diff --git a/helgrind/tests/Makefile.am b/helgrind/tests/Makefile.am index ac6b15af77..721749f1ce 100755 --- a/helgrind/tests/Makefile.am +++ b/helgrind/tests/Makefile.am @@ -16,6 +16,7 @@ EXTRA_DIST = \ annotate_smart_pointer.vgtest annotate_smart_pointer.stdout.exp \ annotate_smart_pointer.stderr.exp \ bug322621.vgtest bug322621.stderr.exp \ + bug327548.vgtest bug327548.stderr.exp \ bug392331.vgtest bug392331.stdout.exp bug392331.stderr.exp \ bug392331_supp.vgtest bug392331_supp.stdout.exp bug392331_supp.stderr.exp \ bug392331.supp \ @@ -146,6 +147,7 @@ noinst_HEADERS = safe-pthread.h safe-semaphore.h # should be conditionally compiled like tc20_verifywrap is. check_PROGRAMS = \ annotate_hbefore \ + bug327548 \ cond_init_destroy \ cond_timedwait_invalid \ cond_timedwait_test \ diff --git a/helgrind/tests/bug327548.c b/helgrind/tests/bug327548.c new file mode 100644 index 0000000000..7b6e8a9ced --- /dev/null +++ b/helgrind/tests/bug327548.c @@ -0,0 +1,50 @@ +#include <pthread.h> +#include <stdio.h> +#include <semaphore.h> + +sem_t sem; +pthread_cond_t cond; +pthread_mutex_t mutex; +int finished; + +void *f(void *foo) { + while(1) + { + /* Wait for main() to have built mutex/cond */ + sem_wait(&sem); + + pthread_mutex_lock(&mutex); + finished = 1; + pthread_cond_signal(&cond); + pthread_mutex_unlock(&mutex); + } + return NULL; +} + +int main(void) { + pthread_t t; + sem_init(&sem, 0, 0); + int count = 1000; + + pthread_create(&t, NULL, f, NULL); + + while (count--) + { + pthread_mutex_init(&mutex, NULL); + pthread_cond_init(&cond, NULL); + + pthread_mutex_lock(&mutex); + /* Tell thread there is a new item to process */ + sem_post(&sem); + while (!finished) + pthread_cond_wait(&cond, &mutex); + pthread_mutex_unlock(&mutex); + + finished = 0; + + pthread_cond_destroy(&cond); + pthread_mutex_destroy(&mutex); + } + + return 0; +} diff --git a/helgrind/tests/bug327548.stderr.exp b/helgrind/tests/bug327548.stderr.exp new file mode 100644 index 0000000000..e69de29bb2 diff --git a/helgrind/tests/bug327548.vgtest b/helgrind/tests/bug327548.vgtest new file mode 100644 index 0000000000..e064b32572 --- /dev/null +++ b/helgrind/tests/bug327548.vgtest @@ -0,0 +1,2 @@ +vgopts: -q +prog: bug327548 |
|
From: Philippe W. <phi...@so...> - 2023-01-02 22:06:36
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=56971834a79eff2decd16cdb23f16a2d4d37181a commit 56971834a79eff2decd16cdb23f16a2d4d37181a Author: Philippe Waroquiers <phi...@sk...> Date: Mon Jan 2 23:04:44 2023 +0100 Small improvement to documentation. Diff: --- docs/xml/manual-core-adv.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/xml/manual-core-adv.xml b/docs/xml/manual-core-adv.xml index 1fa801edc1..6991a95e06 100644 --- a/docs/xml/manual-core-adv.xml +++ b/docs/xml/manual-core-adv.xml @@ -308,9 +308,9 @@ tool-specific macros).</para> xreflabel="&vg-gdbserver-label;"> <title>Debugging your program using Valgrind gdbserver and GDB</title> -<para>A program running under Valgrind is not executed directly by the -CPU. Instead it runs on a synthetic CPU provided by Valgrind. This is -why a debugger cannot debug your program when it runs on Valgrind. +<para>A program running under Valgrind is not executed directly by the CPU. +Instead it runs on a synthetic CPU provided by Valgrind. This is why a debugger +cannot natively debug your program when it runs on Valgrind. </para> <para> This section describes how GDB can interact with the |
|
From: Mark W. <ma...@kl...> - 2022-12-31 23:38:08
|
On Tue, Nov 15, 2022 at 11:07:15PM +0100, Mark Wielaard wrote: > https://www.fsf.org/events/sourceware-infrastructure-a-presentation-and-community-q-a > https://inbox.sourceware.org/overseers/6e9...@fs.../ > > We like to discuss how to use the new infrastructure setup this last > year, builder, try/ci/full buildbots, bunsen testsuite analysis, > patchwork patch tracking, handling patches/email with public-inbox, > b4, the sourcehut mirror. And the future of Sourceware as a Software > Freedom Conservancy member project. (*) Thanks to everybody who could attend. For those who couldn't the html slides and markdown sources with the presenter notes are here: https://gnu.wildebeest.org/blog/mjw/2022/11/20/new-services-for-sourceware-sfc-fsf/ And a (video) recording is here: https://media.libreplanet.org/u/libreplanet/m/sourceware-infrastructure-a-presentation-and-community-q-a/ We hope to have answered all questions, but if we missed anything, or you want to help with the infrastructure please contact us at the overseers mailinglist or file a sourceware infrastructure bug: https://sourceware.org/mailman/listinfo/overseers https://sourceware.org/bugzilla/buglist.cgi?component=Infrastructure&product=sourceware In 2023 Sourceware will be 25 years. Happy new year! (*) The Software Freedom Conservancy is currently running a fundraiser: https://sfconservancy.org/sustainer/#YearInReview |
|
From: Paul F. <pa...@so...> - 2022-12-31 09:13:59
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=8224cf37a9358728413dc753fd4afb50dcdfd2fd commit 8224cf37a9358728413dc753fd4afb50dcdfd2fd Author: Paul Floyd <pj...@wa...> Date: Sat Dec 31 10:13:19 2022 +0100 Update none/tests/cmdline1 and 2 for non-linux Diff: --- none/tests/cmdline1.stdout.exp-non-linux | 2 ++ none/tests/cmdline2.stdout.exp-non-linux | 2 ++ 2 files changed, 4 insertions(+) diff --git a/none/tests/cmdline1.stdout.exp-non-linux b/none/tests/cmdline1.stdout.exp-non-linux index 51d699bba6..cdc13fd61c 100644 --- a/none/tests/cmdline1.stdout.exp-non-linux +++ b/none/tests/cmdline1.stdout.exp-non-linux @@ -113,6 +113,8 @@ usage: valgrind [options] prog-and-args where hint is one of: lax-ioctls lax-doors fuse-compatible enable-outer no-inner-prefix no-nptl-pthread-stackcache fallback-llsc none + --scheduling-quantum=<number> thread-scheduling timeslice in number of + basic blocks [100000] --fair-sched=no|yes|try schedule threads fairly on multicore systems [no] --kernel-variant=variant1,variant2,... handle non-standard kernel variants [none] diff --git a/none/tests/cmdline2.stdout.exp-non-linux b/none/tests/cmdline2.stdout.exp-non-linux index d76c502fda..7b65b731fe 100644 --- a/none/tests/cmdline2.stdout.exp-non-linux +++ b/none/tests/cmdline2.stdout.exp-non-linux @@ -113,6 +113,8 @@ usage: valgrind [options] prog-and-args where hint is one of: lax-ioctls lax-doors fuse-compatible enable-outer no-inner-prefix no-nptl-pthread-stackcache fallback-llsc none + --scheduling-quantum=<number> thread-scheduling timeslice in number of + basic blocks [100000] --fair-sched=no|yes|try schedule threads fairly on multicore systems [no] --kernel-variant=variant1,variant2,... handle non-standard kernel variants [none] |
|
From: Philippe W. <phi...@sk...> - 2022-12-30 20:17:36
|
On Fri, 2022-12-30 at 17:54 +0100, Paul Floyd wrote: > Hi Philippe > > I can't comment on the python binding aspects as scripting is somewhat > my Achilles heel. > > For the functionality this would be a welcome improvement. > > Many is the time that I've wanted to be able to type > > mo xb &foo sizeof(foo) > > but instead need to do p(rint)s first. > > Do you know whether this would also facilitate integration of Valgrind > debugging in environments like vscode, Qt Creator and CLion? These new GDB python front end commands are provided in the command line interface of GDB. They can for sure be used from GUI environments, if the GUI provides a console. To provide a functionality similar to 'xb &foo sizeof(foo)' directly in the GUI, I guess it will be needed to have some changes done in the GUI either to implement a similar front end command or to interface with these new GDB valgrind python commands, whatever is easier. > > Whilst on the subject of CLion, I did recently get an opensource licence > for it from jetbrains (mostly to check integration and things like this > https://bugs.kde.org/show_bug.cgi?id=454925). If anyone else would like > to try it out for Valgrind use only then let me know. > > A+ > Paul > > > _______________________________________________ > Valgrind-developers mailing list > Val...@li... > https://lists.sourceforge.net/lists/listinfo/valgrind-developers |
|
From: Philippe W. <phi...@so...> - 2022-12-30 19:57:31
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=f6fcc74a68ab00e642ecac3d99f634bfe9e634a8 commit f6fcc74a68ab00e642ecac3d99f634bfe9e634a8 Author: Philippe Waroquiers <phi...@sk...> Date: Fri Dec 30 20:05:40 2022 +0100 Allows to only output "new" loss records when doing a leak search. In the memcheck monitor 'leak_search', add a "new" keyword corresponding to the delta leak search mode LCD_New. Add a new client request VALGRIND_DO_NEW_LEAK_CHECK. When doing a delta leak search, new loss records are marked with "new" (whatever the delta leak search mode). Note that trailing white spaces were removed in mc_main.c. A much small diff can be looked at by using the -w diff option. Diff: --- NEWS | 10 ++ gdbserver_tests/mchelp.stdoutB.exp | 4 +- gdbserver_tests/mcleak.stderr.exp | 28 ++-- gdbserver_tests/mcleak.stderrB.exp | 94 ++++++----- gdbserver_tests/mcleak.stdinB.gdb | 9 + gdbserver_tests/mcleak.stdoutB.exp | 100 +++++------ memcheck/docs/mc-manual.xml | 28 +++- memcheck/mc_errors.c | 24 ++- memcheck/mc_include.h | 9 +- memcheck/mc_leakcheck.c | 12 +- memcheck/mc_main.c | 312 ++++++++++++++++++----------------- memcheck/memcheck.h | 7 + memcheck/tests/filter_stderr.in | 2 +- memcheck/tests/leak-delta.c | 14 +- memcheck/tests/leak-delta.stderr.exp | 79 +++++---- 15 files changed, 421 insertions(+), 311 deletions(-) diff --git a/NEWS b/NEWS index 16ae313dfc..f73541187a 100644 --- a/NEWS +++ b/NEWS @@ -15,6 +15,16 @@ AMD64/macOS 10.13 and nanoMIPS/Linux. * ==================== TOOL CHANGES =================== +* Memcheck: + - When doing a delta leak_search, it is now possible to only + output the new loss records compared to the previous leak search. + This is available in the memcheck monitor command 'leak_search' + by specifying the "new" keyword or in your program by using + the client request VALGRIND_DO_NEW_LEAK_CHECK. + Whenever a "delta" leak search is done (i.e. when specifying + "new" or "increased" or "changed" in the monitor command), + the new loss records have a "new" marker. + * Helgrind: - The option ---history-backtrace-size=<number> allows to configure the number of entries to record in the stack traces of "old" diff --git a/gdbserver_tests/mchelp.stdoutB.exp b/gdbserver_tests/mchelp.stdoutB.exp index 6f45932d10..916c8a70d2 100644 --- a/gdbserver_tests/mchelp.stdoutB.exp +++ b/gdbserver_tests/mchelp.stdoutB.exp @@ -32,7 +32,7 @@ memcheck monitor commands: leak_check [full*|summary|xtleak] [kinds kind1,kind2,...|reachable|possibleleak*|definiteleak] [heuristics heur1,heur2,...] - [increased*|changed|any] + [new|increased*|changed|any] [unlimited*|limited <max_loss_records_output>] * = defaults xtleak produces an xtree full leak result in xtleak.kcg.%p.%n @@ -106,7 +106,7 @@ memcheck monitor commands: leak_check [full*|summary|xtleak] [kinds kind1,kind2,...|reachable|possibleleak*|definiteleak] [heuristics heur1,heur2,...] - [increased*|changed|any] + [new|increased*|changed|any] [unlimited*|limited <max_loss_records_output>] * = defaults xtleak produces an xtree full leak result in xtleak.kcg.%p.%n diff --git a/gdbserver_tests/mcleak.stderr.exp b/gdbserver_tests/mcleak.stderr.exp index 0496c1d6aa..c6f0b01ff6 100644 --- a/gdbserver_tests/mcleak.stderr.exp +++ b/gdbserver_tests/mcleak.stderr.exp @@ -2,8 +2,8 @@ expecting details 10 bytes reachable 10 bytes in 1 blocks are still reachable in loss record ... of ... at 0x........: malloc (vg_replace_malloc.c:...) - by 0x........: f (leak-delta.c:14) - by 0x........: main (leak-delta.c:60) + by 0x........: f (leak-delta.c:15) + by 0x........: main (leak-delta.c:72) expecting to have NO details expecting details +10 bytes lost, +21 bytes reachable expecting details +65 bytes reachable @@ -12,24 +12,30 @@ expecting details +10 bytes reachable expecting details -10 bytes reachable, +10 bytes lost expecting details -10 bytes lost, +10 bytes reachable expecting details 32 (+32) bytes lost, 33 (-32) bytes reachable +expecting details 42 (+42) bytes lost, 43 (+43) bytes reachable +expecting to have NO details finished -leaked: 32 bytes in 1 blocks +leaked: 117 bytes in 3 blocks dubious: 0 bytes in 0 blocks reachable: 64 bytes in 3 blocks suppressed: 0 bytes in 0 blocks 10 bytes in 1 blocks are still reachable in loss record ... of ... at 0x........: malloc (vg_replace_malloc.c:...) - by 0x........: f (leak-delta.c:14) - by 0x........: main (leak-delta.c:60) + by 0x........: f (leak-delta.c:15) + by 0x........: main (leak-delta.c:72) 21 bytes in 1 blocks are still reachable in loss record ... of ... at 0x........: malloc (vg_replace_malloc.c:...) - by 0x........: f (leak-delta.c:23) - by 0x........: main (leak-delta.c:60) + by 0x........: f (leak-delta.c:24) + by 0x........: main (leak-delta.c:72) 32 bytes in 1 blocks are definitely lost in loss record ... of ... at 0x........: malloc (vg_replace_malloc.c:...) - by 0x........: f (leak-delta.c:28) - by 0x........: main (leak-delta.c:60) + by 0x........: f (leak-delta.c:29) + by 0x........: main (leak-delta.c:72) 33 bytes in 1 blocks are still reachable in loss record ... of ... at 0x........: malloc (vg_replace_malloc.c:...) - by 0x........: f (leak-delta.c:28) - by 0x........: main (leak-delta.c:60) + by 0x........: f (leak-delta.c:29) + by 0x........: main (leak-delta.c:72) +85 bytes in 2 blocks are definitely lost in loss record ... of ... + at 0x........: malloc (vg_replace_malloc.c:...) + by 0x........: f (leak-delta.c:53) + by 0x........: main (leak-delta.c:72) diff --git a/gdbserver_tests/mcleak.stderrB.exp b/gdbserver_tests/mcleak.stderrB.exp index 7ed392057a..6e6ee24870 100644 --- a/gdbserver_tests/mcleak.stderrB.exp +++ b/gdbserver_tests/mcleak.stderrB.exp @@ -1,77 +1,89 @@ vgdb-error value changed from 0 to 999999 10 bytes in 1 blocks are still reachable in loss record ... of ... at 0x........: malloc (vg_replace_malloc.c:...) - by 0x........: f (leak-delta.c:14) - by 0x........: main (leak-delta.c:60) + by 0x........: f (leak-delta.c:15) + by 0x........: main (leak-delta.c:72) 10 (+10) bytes in 1 (+1) blocks are definitely lost in loss record ... of ... at 0x........: malloc (vg_replace_malloc.c:...) - by 0x........: f (leak-delta.c:14) - by 0x........: main (leak-delta.c:60) + by 0x........: f (leak-delta.c:15) + by 0x........: main (leak-delta.c:72) 21 (+21) bytes in 1 (+1) blocks are still reachable in loss record ... of ... at 0x........: malloc (vg_replace_malloc.c:...) - by 0x........: f (leak-delta.c:23) - by 0x........: main (leak-delta.c:60) + by 0x........: f (leak-delta.c:24) + by 0x........: main (leak-delta.c:72) 65 (+65) bytes in 2 (+2) blocks are still reachable in loss record ... of ... at 0x........: malloc (vg_replace_malloc.c:...) - by 0x........: f (leak-delta.c:28) - by 0x........: main (leak-delta.c:60) + by 0x........: f (leak-delta.c:29) + by 0x........: main (leak-delta.c:72) 10 (+10) bytes in 1 (+1) blocks are still reachable in loss record ... of ... at 0x........: malloc (vg_replace_malloc.c:...) - by 0x........: f (leak-delta.c:14) - by 0x........: main (leak-delta.c:60) + by 0x........: f (leak-delta.c:15) + by 0x........: main (leak-delta.c:72) 0 (-10) bytes in 0 (-1) blocks are still reachable in loss record ... of ... at 0x........: malloc (vg_replace_malloc.c:...) - by 0x........: f (leak-delta.c:14) - by 0x........: main (leak-delta.c:60) + by 0x........: f (leak-delta.c:15) + by 0x........: main (leak-delta.c:72) 10 (+10) bytes in 1 (+1) blocks are definitely lost in loss record ... of ... at 0x........: malloc (vg_replace_malloc.c:...) - by 0x........: f (leak-delta.c:14) - by 0x........: main (leak-delta.c:60) + by 0x........: f (leak-delta.c:15) + by 0x........: main (leak-delta.c:72) 0 (-10) bytes in 0 (-1) blocks are definitely lost in loss record ... of ... at 0x........: malloc (vg_replace_malloc.c:...) - by 0x........: f (leak-delta.c:14) - by 0x........: main (leak-delta.c:60) + by 0x........: f (leak-delta.c:15) + by 0x........: main (leak-delta.c:72) 10 (+10) bytes in 1 (+1) blocks are still reachable in loss record ... of ... at 0x........: malloc (vg_replace_malloc.c:...) - by 0x........: f (leak-delta.c:14) - by 0x........: main (leak-delta.c:60) + by 0x........: f (leak-delta.c:15) + by 0x........: main (leak-delta.c:72) 32 (+32) bytes in 1 (+1) blocks are definitely lost in loss record ... of ... at 0x........: malloc (vg_replace_malloc.c:...) - by 0x........: f (leak-delta.c:28) - by 0x........: main (leak-delta.c:60) + by 0x........: f (leak-delta.c:29) + by 0x........: main (leak-delta.c:72) 33 (-32) bytes in 1 (-1) blocks are still reachable in loss record ... of ... at 0x........: malloc (vg_replace_malloc.c:...) - by 0x........: f (leak-delta.c:28) - by 0x........: main (leak-delta.c:60) + by 0x........: f (leak-delta.c:29) + by 0x........: main (leak-delta.c:72) +42 (+42) bytes in 1 (+1) blocks are definitely lost in loss record ... of ... + at 0x........: malloc (vg_replace_malloc.c:...) + by 0x........: f (leak-delta.c:53) + by 0x........: main (leak-delta.c:72) +43 (+43) bytes in 1 (+1) blocks are still reachable in loss record ... of ... + at 0x........: malloc (vg_replace_malloc.c:...) + by 0x........: f (leak-delta.c:53) + by 0x........: main (leak-delta.c:72) 10 bytes in 1 blocks are still reachable in loss record ... of ... at 0x........: malloc (vg_replace_malloc.c:...) - by 0x........: f (leak-delta.c:14) - by 0x........: main (leak-delta.c:60) + by 0x........: f (leak-delta.c:15) + by 0x........: main (leak-delta.c:72) 21 bytes in 1 blocks are still reachable in loss record ... of ... at 0x........: malloc (vg_replace_malloc.c:...) - by 0x........: f (leak-delta.c:23) - by 0x........: main (leak-delta.c:60) + by 0x........: f (leak-delta.c:24) + by 0x........: main (leak-delta.c:72) 32 bytes in 1 blocks are definitely lost in loss record ... of ... at 0x........: malloc (vg_replace_malloc.c:...) - by 0x........: f (leak-delta.c:28) - by 0x........: main (leak-delta.c:60) + by 0x........: f (leak-delta.c:29) + by 0x........: main (leak-delta.c:72) 33 bytes in 1 blocks are still reachable in loss record ... of ... at 0x........: malloc (vg_replace_malloc.c:...) - by 0x........: f (leak-delta.c:28) - by 0x........: main (leak-delta.c:60) -32 bytes in 1 blocks are definitely lost in loss record ... of ... + by 0x........: f (leak-delta.c:29) + by 0x........: main (leak-delta.c:72) +85 bytes in 2 blocks are definitely lost in loss record ... of ... at 0x........: malloc (vg_replace_malloc.c:...) - by 0x........: f (leak-delta.c:28) - by 0x........: main (leak-delta.c:60) + by 0x........: f (leak-delta.c:53) + by 0x........: main (leak-delta.c:72) 33 bytes in 1 blocks are still reachable in loss record ... of ... at 0x........: malloc (vg_replace_malloc.c:...) - by 0x........: f (leak-delta.c:28) - by 0x........: main (leak-delta.c:60) -33 bytes in 1 blocks are still reachable in loss record ... of ... + by 0x........: f (leak-delta.c:29) + by 0x........: main (leak-delta.c:72) +85 bytes in 2 blocks are definitely lost in loss record ... of ... at 0x........: malloc (vg_replace_malloc.c:...) - by 0x........: f (leak-delta.c:28) - by 0x........: main (leak-delta.c:60) -32 bytes in 1 blocks are definitely lost in loss record ... of ... + by 0x........: f (leak-delta.c:53) + by 0x........: main (leak-delta.c:72) +85 bytes in 2 blocks are definitely lost in loss record ... of ... + at 0x........: malloc (vg_replace_malloc.c:...) + by 0x........: f (leak-delta.c:53) + by 0x........: main (leak-delta.c:72) +85 bytes in 2 blocks are definitely lost in loss record ... of ... at 0x........: malloc (vg_replace_malloc.c:...) - by 0x........: f (leak-delta.c:28) - by 0x........: main (leak-delta.c:60) + by 0x........: f (leak-delta.c:53) + by 0x........: main (leak-delta.c:72) diff --git a/gdbserver_tests/mcleak.stdinB.gdb b/gdbserver_tests/mcleak.stdinB.gdb index 437556ab66..0862a85414 100644 --- a/gdbserver_tests/mcleak.stdinB.gdb +++ b/gdbserver_tests/mcleak.stdinB.gdb @@ -70,6 +70,15 @@ continue # fprintf(stderr, "expecting details 32 (+32) bytes lost, 33 (-32) bytes reachable\n"); fflush(stderr); breakme(); up monitor leak_check full reachable changed +continue +# b42_43[0]--; +# fprintf(stderr, "expecting details 42 (+42) bytes lost, 43 (+43) bytes reachable\n"); fflush(stderr); breakme(); +up +monitor leak_check full reachable new +continue +# b42_43[1]--; +# fprintf(stderr, "expecting to have NO details\n"); fflush(stderr); breakme(); +monitor leak_check full reachable new # output all leak records: monitor leak_check full reachable any unlimited # output the 2 biggest leak records: diff --git a/gdbserver_tests/mcleak.stdoutB.exp b/gdbserver_tests/mcleak.stdoutB.exp index 41be83e684..62b7449fcb 100644 --- a/gdbserver_tests/mcleak.stdoutB.exp +++ b/gdbserver_tests/mcleak.stdoutB.exp @@ -1,48 +1,56 @@ -Breakpoint 1 at 0x........: file leak-delta.c, line 9. -Continuing. -Breakpoint 1, breakme () at leak-delta.c:9 -9 static void breakme() {}; -#1 0x........ in f () at leak-delta.c:16 -16 fprintf(stderr, "expecting details 10 bytes reachable\n"); fflush(stderr); breakme(); -Continuing. -Breakpoint 1, breakme () at leak-delta.c:9 -9 static void breakme() {}; -#1 0x........ in f () at leak-delta.c:19 -19 fprintf(stderr, "expecting to have NO details\n"); fflush(stderr); breakme(); -Continuing. -Breakpoint 1, breakme () at leak-delta.c:9 -9 static void breakme() {}; -#1 0x........ in f () at leak-delta.c:24 -24 fprintf(stderr, "expecting details +10 bytes lost, +21 bytes reachable\n"); fflush(stderr); breakme(); -Continuing. -Breakpoint 1, breakme () at leak-delta.c:9 -9 static void breakme() {}; -#1 0x........ in f () at leak-delta.c:29 -29 fprintf(stderr, "expecting details +65 bytes reachable\n"); fflush(stderr); breakme(); -Continuing. -Breakpoint 1, breakme () at leak-delta.c:9 -9 static void breakme() {}; -#1 0x........ in f () at leak-delta.c:32 -32 fprintf(stderr, "expecting to have NO details\n"); fflush(stderr); breakme(); -Continuing. -Breakpoint 1, breakme () at leak-delta.c:9 -9 static void breakme() {}; -#1 0x........ in f () at leak-delta.c:36 -36 fprintf(stderr, "expecting details +10 bytes reachable\n"); fflush(stderr); breakme(); -Continuing. -Breakpoint 1, breakme () at leak-delta.c:9 -9 static void breakme() {}; -#1 0x........ in f () at leak-delta.c:40 -40 fprintf(stderr, "expecting details -10 bytes reachable, +10 bytes lost\n"); fflush(stderr); breakme(); -Continuing. -Breakpoint 1, breakme () at leak-delta.c:9 -9 static void breakme() {}; -#1 0x........ in f () at leak-delta.c:44 -44 fprintf(stderr, "expecting details -10 bytes lost, +10 bytes reachable\n"); fflush(stderr); breakme(); -Continuing. -Breakpoint 1, breakme () at leak-delta.c:9 -9 static void breakme() {}; -#1 0x........ in f () at leak-delta.c:48 -48 fprintf(stderr, "expecting details 32 (+32) bytes lost, 33 (-32) bytes reachable\n"); fflush(stderr); breakme(); +Breakpoint 1 at 0x........: file leak-delta.c, line 10. +Continuing. +Breakpoint 1, breakme () at leak-delta.c:10 +10 static void breakme() {}; +#1 0x........ in f () at leak-delta.c:17 +17 fprintf(stderr, "expecting details 10 bytes reachable\n"); fflush(stderr); breakme(); +Continuing. +Breakpoint 1, breakme () at leak-delta.c:10 +10 static void breakme() {}; +#1 0x........ in f () at leak-delta.c:20 +20 fprintf(stderr, "expecting to have NO details\n"); fflush(stderr); breakme(); +Continuing. +Breakpoint 1, breakme () at leak-delta.c:10 +10 static void breakme() {}; +#1 0x........ in f () at leak-delta.c:25 +25 fprintf(stderr, "expecting details +10 bytes lost, +21 bytes reachable\n"); fflush(stderr); breakme(); +Continuing. +Breakpoint 1, breakme () at leak-delta.c:10 +10 static void breakme() {}; +#1 0x........ in f () at leak-delta.c:30 +30 fprintf(stderr, "expecting details +65 bytes reachable\n"); fflush(stderr); breakme(); +Continuing. +Breakpoint 1, breakme () at leak-delta.c:10 +10 static void breakme() {}; +#1 0x........ in f () at leak-delta.c:33 +33 fprintf(stderr, "expecting to have NO details\n"); fflush(stderr); breakme(); +Continuing. +Breakpoint 1, breakme () at leak-delta.c:10 +10 static void breakme() {}; +#1 0x........ in f () at leak-delta.c:37 +37 fprintf(stderr, "expecting details +10 bytes reachable\n"); fflush(stderr); breakme(); +Continuing. +Breakpoint 1, breakme () at leak-delta.c:10 +10 static void breakme() {}; +#1 0x........ in f () at leak-delta.c:41 +41 fprintf(stderr, "expecting details -10 bytes reachable, +10 bytes lost\n"); fflush(stderr); breakme(); +Continuing. +Breakpoint 1, breakme () at leak-delta.c:10 +10 static void breakme() {}; +#1 0x........ in f () at leak-delta.c:45 +45 fprintf(stderr, "expecting details -10 bytes lost, +10 bytes reachable\n"); fflush(stderr); breakme(); +Continuing. +Breakpoint 1, breakme () at leak-delta.c:10 +10 static void breakme() {}; +#1 0x........ in f () at leak-delta.c:49 +49 fprintf(stderr, "expecting details 32 (+32) bytes lost, 33 (-32) bytes reachable\n"); fflush(stderr); breakme(); +Continuing. +Breakpoint 1, breakme () at leak-delta.c:10 +10 static void breakme() {}; +#1 0x........ in f () at leak-delta.c:56 +56 fprintf(stderr, "expecting details 42 (+42) bytes lost, 43 (+43) bytes reachable\n"); fflush(stderr); breakme(); +Continuing. +Breakpoint 1, breakme () at leak-delta.c:10 +10 static void breakme() {}; Continuing. Program exited normally. diff --git a/memcheck/docs/mc-manual.xml b/memcheck/docs/mc-manual.xml index 4de7c3debc..2eb5b12f92 100644 --- a/memcheck/docs/mc-manual.xml +++ b/memcheck/docs/mc-manual.xml @@ -1930,7 +1930,7 @@ Address 0x8049E28 len 1 defined <para><varname>leak_check [full*|summary|xtleak] [kinds <set>|reachable|possibleleak*|definiteleak] [heuristics heur1,heur2,...] - [increased*|changed|any] + [new|increased*|changed|any] [unlimited*|limited <max_loss_records_output>] </varname> performs a leak check. The <varname>*</varname> in the arguments @@ -1980,18 +1980,22 @@ Address 0x8049E28 len 1 defined <varname>heuristics none</varname>. </para> - <para>The <varname>[increased*|changed|any]</varname> argument controls what - kinds of changes are shown for a <varname>full</varname> leak search. The - value <varname>increased</varname> specifies that only block + <para>The <varname>[new|increased*|changed|any]</varname> argument controls + what kinds of changes are shown for a <varname>full</varname> leak search. + The value <varname>increased</varname> specifies that only block allocation stacks with an increased number of leaked bytes or blocks since the previous leak check should be shown. The value <varname>changed</varname> specifies that allocation stacks with any change since the previous leak check should be shown. + The value <varname>new</varname> specifies to show only the block + allocation stacks that are new since the previous leak search. The value <varname>any</varname> specifies that all leak entries - should be shown, regardless of any increase or decrease. When - If <varname>increased</varname> or <varname>changed</varname> are - specified, the leak report entries will show the delta relative to - the previous leak report. + should be shown, regardless of any increase or decrease. + If <varname>new</varname> or <varname>increased</varname> or + <varname>changed</varname> are specified, the leak report entries will show + the delta relative to the previous leak report and the new loss records + will have a "new" marker (even when <varname>increased</varname> or + <varname>changed</varname> were specified). </para> <para>The following example shows usage of the @@ -2004,7 +2008,7 @@ Address 0x8049E28 len 1 defined there was no increase since the previous leak search.</para> <programlisting><![CDATA[ (gdb) monitor leak_check full possibleleak increased -==19520== 16 (+16) bytes in 1 (+1) blocks are possibly lost in loss record 9 of 12 +==19520== 16 (+16) bytes in 1 (+1) blocks are possibly lost in new loss record 9 of 12 ==19520== at 0x40070B4: malloc (vg_replace_malloc.c:263) ==19520== by 0x80484D5: mk (leak-cases.c:52) ==19520== by 0x804855F: f (leak-cases.c:81) @@ -2294,6 +2298,12 @@ arguments.</para> has no return value.</para> </listitem> + <listitem> + <para><varname>VALGRIND_DO_NEW_LEAK_CHECK</varname>: same as + <varname> VALGRIND_DO_LEAK_CHECK</varname> but only shows the new + entries since the previous leak search. It has no return value.</para> + </listitem> + <listitem> <para><varname>VALGRIND_DO_QUICK_LEAK_CHECK</varname>: like <varname>VALGRIND_DO_LEAK_CHECK</varname>, except it produces only a leak diff --git a/memcheck/mc_errors.c b/memcheck/mc_errors.c index d47cfa7713..ee5533a632 100644 --- a/memcheck/mc_errors.c +++ b/memcheck/mc_errors.c @@ -329,9 +329,15 @@ static void pp_LossRecord(UInt n_this_record, UInt n_total_records, HChar d_direct_bytes[31]; HChar d_indirect_bytes[31]; HChar d_num_blocks[31]; + /* A loss record that had an old number of blocks 0 is a new loss record. + We mark it as new only when doing any kind of delta leak search. */ + const HChar *new_loss_record_marker + = MC_(detect_memory_leaks_last_delta_mode) != LCD_Any + && lr->old_num_blocks == 0 + ? "new " : ""; MC_(snprintf_delta) (d_bytes, sizeof(d_bytes), - lr->szB + lr->indirect_szB, + lr->szB + lr->indirect_szB, lr->old_szB + lr->old_indirect_szB, MC_(detect_memory_leaks_last_delta_mode)); MC_(snprintf_delta) (d_direct_bytes, sizeof(d_direct_bytes), @@ -353,14 +359,15 @@ static void pp_LossRecord(UInt n_this_record, UInt n_total_records, emit( " <xwhat>\n" ); emit( " <text>%'lu%s (%'lu%s direct, %'lu%s indirect) bytes " "in %'u%s blocks" - " are %s in loss record %'u of %'u</text>\n", + " are %s in %sloss record %'u of %'u</text>\n", lr->szB + lr->indirect_szB, d_bytes, lr->szB, d_direct_bytes, lr->indirect_szB, d_indirect_bytes, lr->num_blocks, d_num_blocks, str_leak_lossmode(lr->key.state), + new_loss_record_marker, n_this_record, n_total_records ); - // Nb: don't put commas in these XML numbers + // Nb: don't put commas in these XML numbers emit( " <leakedbytes>%lu</leakedbytes>\n", lr->szB + lr->indirect_szB ); emit( " <leakedblocks>%u</leakedblocks>\n", lr->num_blocks ); @@ -368,10 +375,11 @@ static void pp_LossRecord(UInt n_this_record, UInt n_total_records, } else { emit( " <xwhat>\n" ); emit( " <text>%'lu%s bytes in %'u%s blocks" - " are %s in loss record %'u of %'u</text>\n", + " are %s in %sloss record %'u of %'u</text>\n", lr->szB, d_direct_bytes, lr->num_blocks, d_num_blocks, - str_leak_lossmode(lr->key.state), + str_leak_lossmode(lr->key.state), + new_loss_record_marker, n_this_record, n_total_records ); emit( " <leakedbytes>%lu</leakedbytes>\n", lr->szB); emit( " <leakedblocks>%u</leakedblocks>\n", lr->num_blocks); @@ -382,20 +390,22 @@ static void pp_LossRecord(UInt n_this_record, UInt n_total_records, if (lr->indirect_szB > 0) { emit( "%'lu%s (%'lu%s direct, %'lu%s indirect) bytes in %'u%s blocks" - " are %s in loss record %'u of %'u\n", + " are %s in %sloss record %'u of %'u\n", lr->szB + lr->indirect_szB, d_bytes, lr->szB, d_direct_bytes, lr->indirect_szB, d_indirect_bytes, lr->num_blocks, d_num_blocks, str_leak_lossmode(lr->key.state), + new_loss_record_marker, n_this_record, n_total_records ); } else { emit( - "%'lu%s bytes in %'u%s blocks are %s in loss record %'u of %'u\n", + "%'lu%s bytes in %'u%s blocks are %s in %sloss record %'u of %'u\n", lr->szB, d_direct_bytes, lr->num_blocks, d_num_blocks, str_leak_lossmode(lr->key.state), + new_loss_record_marker, n_this_record, n_total_records ); } diff --git a/memcheck/mc_include.h b/memcheck/mc_include.h index 035c2276cf..30d0affdb2 100644 --- a/memcheck/mc_include.h +++ b/memcheck/mc_include.h @@ -430,10 +430,11 @@ typedef typedef enum { - LCD_Any, // output all loss records, whatever the delta - LCD_Increased, // output loss records with an increase in size or blocks - LCD_Changed, // output loss records with an increase or - //decrease in size or blocks + LCD_Any, // Output all loss records, whatever the delta. + LCD_Increased, // Output loss records with an increase in size or blocks. + LCD_Changed, // Output loss records with an increase or + // decrease in size or blocks. + LCD_New // Output new loss records. } LeakCheckDeltaMode; diff --git a/memcheck/mc_leakcheck.c b/memcheck/mc_leakcheck.c index c78960c0cb..b2a133f3fe 100644 --- a/memcheck/mc_leakcheck.c +++ b/memcheck/mc_leakcheck.c @@ -1275,25 +1275,29 @@ static void get_printing_rules(LeakCheckParams* lcp, Bool delta_considered; switch (lcp->deltamode) { - case LCD_Any: + case LCD_Any: delta_considered = lr->num_blocks > 0; break; case LCD_Increased: - delta_considered + delta_considered = lr->szB > lr->old_szB || lr->indirect_szB > lr->old_indirect_szB || lr->num_blocks > lr->old_num_blocks; break; - case LCD_Changed: + case LCD_Changed: delta_considered = lr->szB != lr->old_szB || lr->indirect_szB != lr->old_indirect_szB || lr->num_blocks != lr->old_num_blocks; break; + case LCD_New: + delta_considered + = lr->num_blocks > 0 && lr->old_num_blocks == 0; + break; default: tl_assert(0); } - *print_record = lcp->mode == LC_Full && delta_considered + *print_record = lcp->mode == LC_Full && delta_considered && RiS(lr->key.state,lcp->show_leak_kinds); // We don't count a leaks as errors with lcp->mode==LC_Summary. // Otherwise you can get high error counts with few or no error diff --git a/memcheck/mc_main.c b/memcheck/mc_main.c index 94af5b28a2..fe15d23321 100644 --- a/memcheck/mc_main.c +++ b/memcheck/mc_main.c @@ -10,7 +10,7 @@ This file is part of MemCheck, a heavyweight Valgrind tool for detecting memory errors. - Copyright (C) 2000-2017 Julian Seward + Copyright (C) 2000-2017 Julian Seward js...@ac... This program is free software; you can redistribute it and/or @@ -64,7 +64,7 @@ static void ocache_sarp_Clear_Origins ( Addr, UWord ); /* fwds */ /*------------------------------------------------------------*/ /*--- Fast-case knobs ---*/ /*------------------------------------------------------------*/ - + // Comment these out to disable the fast cases (don't just set them to zero). /* PERF_FAST_LOADV is in mc_include.h */ @@ -113,8 +113,8 @@ static void ocache_sarp_Clear_Origins ( Addr, UWord ); /* fwds */ /*------------------------------------------------------------*/ /* All reads and writes are checked against a memory map (a.k.a. shadow - memory), which records the state of all memory in the process. - + memory), which records the state of all memory in the process. + On 32-bit machines the memory map is organised as follows. The top 16 bits of an address are used to index into a top-level map table, containing 65536 entries. Each entry is a pointer to a @@ -222,7 +222,7 @@ static void ocache_sarp_Clear_Origins ( Addr, UWord ); /* fwds */ // Ie. instead of particular value bits being held in certain addresses, in // this case certain addresses are represented by particular value bits. // See insert_vabits2_into_vabits8() for an example. -// +// // But note that we don't compress the V bits stored in registers; they // need to be explicit to made the shadow operations possible. Therefore // when moving values between registers and memory we need to convert @@ -272,7 +272,7 @@ static INLINE Bool is_start_of_sm ( Addr a ) { STATIC_ASSERT(SM_CHUNKS % 2 == 0); -typedef +typedef union { UChar vabits8[SM_CHUNKS]; UShort vabits16[SM_CHUNKS/2]; @@ -307,7 +307,7 @@ static SecMap* copy_for_writing ( SecMap* dist_sm ) new_sm = VG_(am_shadow_alloc)(sizeof(SecMap)); if (new_sm == NULL) - VG_(out_of_memory_NORETURN)( "memcheck:allocate new SecMap", + VG_(out_of_memory_NORETURN)( "memcheck:allocate new SecMap", sizeof(SecMap) ); VG_(memcpy)(new_sm, dist_sm, sizeof(SecMap)); update_SM_counts(dist_sm, new_sm); @@ -358,14 +358,14 @@ static void update_SM_counts(SecMap* oldSM, SecMap* newSM) if (n_noaccess_SMs > max_noaccess_SMs ) max_noaccess_SMs = n_noaccess_SMs; if (n_undefined_SMs > max_undefined_SMs) max_undefined_SMs = n_undefined_SMs; if (n_defined_SMs > max_defined_SMs ) max_defined_SMs = n_defined_SMs; - if (n_non_DSM_SMs > max_non_DSM_SMs ) max_non_DSM_SMs = n_non_DSM_SMs; + if (n_non_DSM_SMs > max_non_DSM_SMs ) max_non_DSM_SMs = n_non_DSM_SMs; } /* --------------- Primary maps --------------- */ /* The main primary map. This covers some initial part of the address space, addresses 0 .. (N_PRIMARY_MAP << 16)-1. The rest of it is - handled using the auxiliary primary map. + handled using the auxiliary primary map. */ #if ENABLE_ASSEMBLY_HELPERS && defined(PERF_FAST_LOADV) \ && (defined(VGP_arm_linux) \ @@ -387,7 +387,7 @@ MC_MAIN_STATIC SecMap* primary_map[N_PRIMARY_MAP]; LAYOUT: the first word has to be the key for OSet fast lookups. */ typedef - struct { + struct { Addr base; SecMap* sm; } @@ -403,7 +403,7 @@ typedef static struct { Addr base; AuxMapEnt* ent; // pointer to the matching auxmap_L2 node - } + } auxmap_L1[N_AUXMAP_L1]; static OSet* auxmap_L2 = NULL; @@ -451,7 +451,7 @@ static const HChar* check_auxmap_L1_L2_sanity ( Word* n_secmaps_found ) /* 32-bit platform */ if (VG_(OSetGen_Size)(auxmap_L2) != 0) return "32-bit: auxmap_L2 is non-empty"; - for (i = 0; i < N_AUXMAP_L1; i++) + for (i = 0; i < N_AUXMAP_L1; i++) if (auxmap_L1[i].base != 0 || auxmap_L1[i].ent != NULL) return "32-bit: auxmap_L1 is non-empty"; } else { @@ -631,8 +631,8 @@ static INLINE SecMap** get_secmap_high_ptr ( Addr a ) static INLINE SecMap** get_secmap_ptr ( Addr a ) { - return ( a <= MAX_PRIMARY_ADDRESS - ? get_secmap_low_ptr(a) + return ( a <= MAX_PRIMARY_ADDRESS + ? get_secmap_low_ptr(a) : get_secmap_high_ptr(a)); } @@ -665,7 +665,7 @@ static INLINE SecMap* get_secmap_for_writing_high ( Addr a ) /* Produce the secmap for 'a', either from the primary map or by ensuring there is an entry for it in the aux primary map. The secmap may be a distinguished one as the caller will only want to - be able to read it. + be able to read it. */ static INLINE SecMap* get_secmap_for_reading ( Addr a ) { @@ -767,7 +767,7 @@ UChar get_vabits2 ( Addr a ) // *** WARNING! *** // Any time this function is called, if it is possible that any of the -// 4 2-bit fields in vabits8 are equal to VA_BITS2_PARTDEFINED, then the +// 4 2-bit fields in vabits8 are equal to VA_BITS2_PARTDEFINED, then the // corresponding entry(s) in the sec-V-bits table must also be set! static INLINE UChar get_vabits8_for_aligned_word32 ( Addr a ) @@ -847,13 +847,13 @@ Bool get_vbits8 ( Addr a, UChar* vbits8 ) // Note: the nodes in this table can become stale. Eg. if you write a PDB, // then overwrite the same address with a fully defined byte, the sec-V-bit // node will not necessarily be removed. This is because checking for -// whether removal is necessary would slow down the fast paths. +// whether removal is necessary would slow down the fast paths. // // To avoid the stale nodes building up too much, we periodically (once the // table reaches a certain size) garbage collect (GC) the table by // traversing it and evicting any nodes not having PDB. // If more than a certain proportion of nodes survived, we increase the -// table size so that GCs occur less often. +// table size so that GCs occur less often. // // This policy is designed to avoid bad table bloat in the worst case where // a program creates huge numbers of stale PDBs -- we would get this bloat @@ -881,7 +881,7 @@ Bool get_vbits8 ( Addr a, UChar* vbits8 ) // will be deleted and re-added less frequently. // // The previous scaling up mechanism (now called STEPUP) is retained: -// if residency exceeds 50%, the table is scaled up, although by a +// if residency exceeds 50%, the table is scaled up, although by a // factor sqrt(2) rather than 2 as before. This effectively doubles the // frequency of GCs when there are many PDBs at reduces the tendency of // stale PDBs to reside for long periods in the table. @@ -930,20 +930,20 @@ static Int secVBitLimit = 1000; // come out anyway. static UInt GCs_done = 0; -typedef +typedef struct { Addr a; UChar vbits8[BYTES_PER_SEC_VBIT_NODE]; - } + } SecVBitNode; static OSet* createSecVBitTable(void) { OSet* newSecVBitTable; newSecVBitTable = VG_(OSetGen_Create_With_Pool) - ( offsetof(SecVBitNode, a), + ( offsetof(SecVBitNode, a), NULL, // use fast comparisons - VG_(malloc), "mc.cSVT.1 (sec VBit table)", + VG_(malloc), "mc.cSVT.1 (sec VBit table)", VG_(free), 1000, sizeof(SecVBitNode)); @@ -971,7 +971,7 @@ static void gcSecVBitTable(void) if (VA_BITS2_PARTDEFINED == get_vabits2(n->a + i)) { // Found a non-stale byte, so keep => // Insert a copy of the node into the new table. - SecVBitNode* n2 = + SecVBitNode* n2 = VG_(OSetGen_AllocNode)(secVBitTable2, sizeof(SecVBitNode)); *n2 = *n; VG_(OSetGen_Insert)(secVBitTable2, n2); @@ -994,7 +994,7 @@ static void gcSecVBitTable(void) } // Increase table size if necessary. - if ((Double)n_survivors + if ((Double)n_survivors > ((Double)secVBitLimit * STEPUP_SURVIVOR_PROPORTION)) { secVBitLimit = (Int)((Double)secVBitLimit * (Double)STEPUP_GROWTH_FACTOR); if (VG_(clo_verbosity) > 1) @@ -1004,7 +1004,7 @@ static void gcSecVBitTable(void) } else if (secVBitLimit < DRIFTUP_MAX_SIZE - && (Double)n_survivors + && (Double)n_survivors > ((Double)secVBitLimit * DRIFTUP_SURVIVOR_PROPORTION)) { secVBitLimit = (Int)((Double)secVBitLimit * (Double)DRIFTUP_GROWTH_FACTOR); if (VG_(clo_verbosity) > 1) @@ -1069,7 +1069,7 @@ static void set_sec_vbits8(Addr a, UWord vbits8) /* Returns the offset in memory of the byteno-th most significant byte in a wordszB-sized word, given the specified endianness. */ -static INLINE UWord byte_offset_w ( UWord wordszB, Bool bigendian, +static INLINE UWord byte_offset_w ( UWord wordszB, Bool bigendian, UWord byteno ) { return bigendian ? (wordszB-1-byteno) : byteno; } @@ -1460,7 +1460,7 @@ ULong mc_LOADVn_slow ( Addr a, SizeT nBits, Bool bigendian ) PROF_EVENT(MCPE_LOADVN_SLOW_LOOP); ai = a + byte_offset_w(szB, bigendian, i); ok = get_vbits8(ai, &vbits8); - vbits64 <<= 8; + vbits64 <<= 8; vbits64 |= vbits8; if (!ok) n_addrs_bad++; pessim64 <<= 8; @@ -1590,7 +1590,7 @@ void mc_STOREVn_slow ( Addr a, SizeT nBits, ULong vbytes, Bool bigendian ) SecMap* sm = get_secmap_for_reading(a); UWord sm_off16 = SM_OFF_16(a); UWord vabits16 = sm->vabits16[sm_off16]; - if (LIKELY( !is_distinguished_sm(sm) && + if (LIKELY( !is_distinguished_sm(sm) && (VA_BITS16_DEFINED == vabits16 || VA_BITS16_UNDEFINED == vabits16) )) { /* Handle common case quickly: a is suitably aligned, */ @@ -1617,7 +1617,7 @@ void mc_STOREVn_slow ( Addr a, SizeT nBits, ULong vbytes, Bool bigendian ) SecMap* sm = get_secmap_for_reading(a); UWord sm_off = SM_OFF(a); UWord vabits8 = sm->vabits8[sm_off]; - if (LIKELY( !is_distinguished_sm(sm) && + if (LIKELY( !is_distinguished_sm(sm) && (VA_BITS8_DEFINED == vabits8 || VA_BITS8_UNDEFINED == vabits8) )) { /* Handle common case quickly: a is suitably aligned, */ @@ -1727,7 +1727,7 @@ static void set_address_range_perms ( Addr a, SizeT lenT, UWord vabits16, // * one partial sec-map (p) 1 // - one whole sec-map (P) 2 // - // * two partial sec-maps (pp) 1,3 + // * two partial sec-maps (pp) 1,3 // - one partial, one whole sec-map (pP) 1,2 // - one whole, one partial sec-map (Pp) 2,3 // - two whole sec-maps (PP) 2,2 @@ -1976,7 +1976,7 @@ static void make_mem_defined_if_addressable ( Addr a, SizeT len ) set_vabits2(a+i, VA_BITS2_DEFINED); if (UNLIKELY(MC_(clo_mc_level) >= 3)) { MC_(helperc_b_store1)( a+i, 0 ); /* clear the origin tag */ - } + } } } } @@ -1993,7 +1993,7 @@ static void make_mem_defined_if_noaccess ( Addr a, SizeT len ) set_vabits2(a+i, VA_BITS2_DEFINED); if (UNLIKELY(MC_(clo_mc_level) >= 3)) { MC_(helperc_b_store1)( a+i, 0 ); /* clear the origin tag */ - } + } } } } @@ -2024,8 +2024,8 @@ void MC_(copy_address_range_state) ( Addr src, Addr dst, SizeT len ) while (len >= 4) { vabits8 = get_vabits8_for_aligned_word32( src+i ); set_vabits8_for_aligned_word32( dst+i, vabits8 ); - if (LIKELY(VA_BITS8_DEFINED == vabits8 - || VA_BITS8_UNDEFINED == vabits8 + if (LIKELY(VA_BITS8_DEFINED == vabits8 + || VA_BITS8_UNDEFINED == vabits8 || VA_BITS8_NOACCESS == vabits8)) { /* do nothing */ } else { @@ -2541,7 +2541,7 @@ static void init_OCache ( void ) tl_assert(ocacheL1 == NULL); ocacheL1 = VG_(am_shadow_alloc)(sizeof(OCache)); if (ocacheL1 == NULL) { - VG_(out_of_memory_NORETURN)( "memcheck:allocating ocacheL1", + VG_(out_of_memory_NORETURN)( "memcheck:allocating ocacheL1", sizeof(OCache) ); } tl_assert(ocacheL1 != NULL); @@ -2708,7 +2708,7 @@ static OCacheLine* find_OCacheLine_SLOW ( Addr a ) } else { stats_ocacheL1_found_at_N++; } - if (UNLIKELY(0 == (ocacheL1_event_ctr++ + if (UNLIKELY(0 == (ocacheL1_event_ctr++ & ((1<<OC_MOVE_FORWARDS_EVERY_BITS)-1)))) { moveLineForwards( &ocacheL1->set[setno], line ); line--; @@ -2802,7 +2802,7 @@ static INLINE void set_aligned_word64_Origin_to_undef ( Addr a, UInt otag ) { OCacheLine* line; UWord lineoff = oc_line_offset(a); if (OC_ENABLE_ASSERTIONS) { - tl_assert(lineoff >= 0 + tl_assert(lineoff >= 0 && lineoff < OC_W32S_PER_LINE -1/*'cos 8-aligned*/); } line = find_OCacheLine( a ); @@ -2940,7 +2940,7 @@ void make_aligned_word64_undefined_w_otag ( Addr a, UInt otag ) //// Set the origins for a+0 .. a+7 { OCacheLine* line; UWord lineoff = oc_line_offset(a); - tl_assert(lineoff >= 0 + tl_assert(lineoff >= 0 && lineoff < OC_W32S_PER_LINE -1/*'cos 8-aligned*/); line = find_OCacheLine( a ); line->u.main.descr[lineoff+0] = 0xF; @@ -2978,7 +2978,7 @@ void make_aligned_word64_noaccess ( Addr a ) if (UNLIKELY( MC_(clo_mc_level) == 3 )) { OCacheLine* line; UWord lineoff = oc_line_offset(a); - tl_assert(lineoff >= 0 + tl_assert(lineoff >= 0 && lineoff < OC_W32S_PER_LINE -1/*'cos 8-aligned*/); line = find_OCacheLine( a ); line->u.main.descr[lineoff+0] = 0; @@ -3777,7 +3777,7 @@ void MC_(helperc_MAKE_STACK_UNINIT_w_o) ( Addr base, UWord len, Addr nia ) } else { MC_(make_mem_undefined_w_otag)(base, len, otag); } -# endif +# endif /* Idea is: go fast when * 8-aligned and length is 128 @@ -3974,7 +3974,7 @@ void MC_(helperc_MAKE_STACK_UNINIT_no_o) ( Addr base, UWord len ) } else { make_mem_undefined(base, len); } -# endif +# endif /* Idea is: go fast when * 8-aligned and length is 128 @@ -4118,7 +4118,7 @@ void MC_(helperc_MAKE_STACK_UNINIT_128_no_o) ( Addr base ) } else { make_mem_undefined(base, 128); } -# endif +# endif /* Idea is: go fast when * 16-aligned and length is 128 @@ -4162,7 +4162,7 @@ void MC_(helperc_MAKE_STACK_UNINIT_128_no_o) ( Addr base ) } } } - + /* The same, but for when base is 8 % 16, which is the situation with RSP for amd64-ELF immediately after call instructions. */ @@ -4214,12 +4214,12 @@ void MC_(helperc_MAKE_STACK_UNINIT_128_no_o) ( Addr base ) /*--- Checking memory ---*/ /*------------------------------------------------------------*/ -typedef +typedef enum { - MC_Ok = 5, - MC_AddrErr = 6, + MC_Ok = 5, + MC_AddrErr = 6, MC_ValueErr = 7 - } + } MC_ReadResult; @@ -4249,7 +4249,7 @@ Bool MC_(check_mem_is_noaccess) ( Addr a, SizeT len, Addr* bad_addr ) return True; } -static Bool is_mem_addressable ( Addr a, SizeT len, +static Bool is_mem_addressable ( Addr a, SizeT len, /*OUT*/Addr* bad_addr ) { SizeT i; @@ -4337,8 +4337,8 @@ static void is_mem_defined_comprehensive ( PROF_EVENT(MCPE_IS_MEM_DEFINED_COMPREHENSIVE_LOOP); vabits2 = get_vabits2(a); switch (vabits2) { - case VA_BITS2_DEFINED: - a++; + case VA_BITS2_DEFINED: + a++; break; case VA_BITS2_UNDEFINED: case VA_BITS2_PARTDEFINED: @@ -4421,7 +4421,7 @@ void check_mem_is_addressable ( CorePart part, ThreadId tid, const HChar* s, if (!ok) { switch (part) { case Vg_CoreSysCall: - MC_(record_memparam_error) ( tid, bad_addr, + MC_(record_memparam_error) ( tid, bad_addr, /*isAddrErr*/True, s, 0/*otag*/ ); break; @@ -4438,7 +4438,7 @@ void check_mem_is_addressable ( CorePart part, ThreadId tid, const HChar* s, static void check_mem_is_defined ( CorePart part, ThreadId tid, const HChar* s, Addr base, SizeT size ) -{ +{ UInt otag = 0; Addr bad_addr; MC_ReadResult res = is_mem_defined ( base, size, &bad_addr, &otag ); @@ -4451,12 +4451,12 @@ void check_mem_is_defined ( CorePart part, ThreadId tid, const HChar* s, MC_(record_memparam_error) ( tid, bad_addr, isAddrErr, s, isAddrErr ? 0 : otag ); break; - + case Vg_CoreSysCallArgInMem: MC_(record_regparam_error) ( tid, s, otag ); break; - /* If we're being asked to jump to a silly address, record an error + /* If we're being asked to jump to a silly address, record an error message before potentially crashing the entire system. */ case Vg_CoreTranslate: MC_(record_jump_error)( tid, bad_addr ); @@ -4571,7 +4571,7 @@ void mc_new_mem_startup( Addr a, SizeT len, { // Because code is defined, initialised variables get put in the data // segment and are defined, and uninitialised variables get put in the - // bss segment and are auto-zeroed (and so defined). + // bss segment and are auto-zeroed (and so defined). // // It's possible that there will be padding between global variables. // This will also be auto-zeroed, and marked as defined by Memcheck. If @@ -4629,7 +4629,7 @@ static UInt mb_get_origin_for_guest_offset ( ThreadId tid, chunks of guest state, hence the _SIZE value, which has to be as big as the biggest guest state. */ -static void mc_post_reg_write ( CorePart part, ThreadId tid, +static void mc_post_reg_write ( CorePart part, ThreadId tid, PtrdiffT offset, SizeT size) { # define MAX_REG_WRITE_SIZE 2264 @@ -4640,18 +4640,18 @@ static void mc_post_reg_write ( CorePart part, ThreadId tid, # undef MAX_REG_WRITE_SIZE } -static -void mc_post_reg_write_clientcall ( ThreadId tid, +static +void mc_post_reg_write_clientcall ( ThreadId tid, PtrdiffT offset, SizeT size, Addr f) { mc_post_reg_write(/*dummy*/0, tid, offset, size); } -/* Look at the definedness of the guest's shadow state for - [offset, offset+len). If any part of that is undefined, record +/* Look at the definedness of the guest's shadow state for + [offset, offset+len). If any part of that is undefined, record a parameter error. */ -static void mc_pre_reg_read ( CorePart part, ThreadId tid, const HChar* s, +static void mc_pre_reg_read ( CorePart part, ThreadId tid, const HChar* s, PtrdiffT offset, SizeT size) { Int i; @@ -5088,7 +5088,7 @@ void mc_STOREV64 ( Addr a, ULong vbits64, Bool isBigEndian ) if (!is_distinguished_sm(sm) && VA_BITS16_DEFINED == vabits16) { sm->vabits16[sm_off16] = VA_BITS16_UNDEFINED; return; - } + } PROF_EVENT(MCPE_STOREV64_SLOW3); mc_STOREVn_slow( a, 64, vbits64, isBigEndian ); return; @@ -5303,7 +5303,7 @@ __asm__( /* Derived from NCode template */ ".global vgMemCheck_helperc_LOADV16le \n" ".type vgMemCheck_helperc_LOADV16le, %function \n" "vgMemCheck_helperc_LOADV16le: \n" // -" tst r0, #1 \n" // +" tst r0, #1 \n" // " bne .LLV16LEc12 \n" // if misaligned " lsr r2, r0, #16 \n" // r2 = pri-map-ix " movw r3, #:lower16:primary_map \n" // @@ -5445,7 +5445,7 @@ void mc_STOREV16 ( Addr a, UWord vbits16, Bool isBigEndian ) if (LIKELY(vabits8 == VA_BITS8_DEFINED)) { return; } - if (!is_distinguished_sm(sm) + if (!is_distinguished_sm(sm) && accessible_vabits4_in_vabits8(a, vabits8)) { insert_vabits4_into_vabits8( a, VA_BITS4_DEFINED, &(sm->vabits8[sm_off]) ); @@ -5458,7 +5458,7 @@ void mc_STOREV16 ( Addr a, UWord vbits16, Bool isBigEndian ) if (vabits8 == VA_BITS8_UNDEFINED) { return; } - if (!is_distinguished_sm(sm) + if (!is_distinguished_sm(sm) && accessible_vabits4_in_vabits8(a, vabits8)) { insert_vabits4_into_vabits8( a, VA_BITS4_UNDEFINED, &(sm->vabits8[sm_off]) ); @@ -5693,7 +5693,7 @@ void MC_(helperc_STOREV8) ( Addr a, UWord vbits8 ) if (LIKELY(vabits8 == VA_BITS8_DEFINED)) { return; // defined on defined } - if (!is_distinguished_sm(sm) + if (!is_distinguished_sm(sm) && VA_BITS2_NOACCESS != extract_vabits2_from_vabits8(a, vabits8)) { // direct mod insert_vabits2_into_vabits8( a, VA_BITS2_DEFINED, @@ -5708,8 +5708,8 @@ void MC_(helperc_STOREV8) ( Addr a, UWord vbits8 ) if (vabits8 == VA_BITS8_UNDEFINED) { return; // undefined on undefined } - if (!is_distinguished_sm(sm) - && (VA_BITS2_NOACCESS + if (!is_distinguished_sm(sm) + && (VA_BITS2_NOACCESS != extract_vabits2_from_vabits8(a, vabits8))) { // direct mod insert_vabits2_into_vabits8( a, VA_BITS2_UNDEFINED, @@ -5755,7 +5755,7 @@ void MC_(helperc_value_check8_fail_w_o) ( UWord origin ) { MC_(record_value_error) ( VG_(get_running_tid)(), 8, (UInt)origin ); } -VG_REGPARM(2) +VG_REGPARM(2) void MC_(helperc_value_checkN_fail_w_o) ( HWord sz, UWord origin ) { MC_(record_value_error) ( VG_(get_running_tid)(), (Int)sz, (UInt)origin ); } @@ -5782,7 +5782,7 @@ void MC_(helperc_value_check8_fail_no_o) ( void ) { MC_(record_value_error) ( VG_(get_running_tid)(), 8, 0/*origin*/ ); } -VG_REGPARM(1) +VG_REGPARM(1) void MC_(helperc_value_checkN_fail_no_o) ( HWord sz ) { MC_(record_value_error) ( VG_(get_running_tid)(), (Int)sz, 0/*origin*/ ); } @@ -5801,13 +5801,13 @@ void MC_(helperc_value_checkN_fail_no_o) ( HWord sz ) { /* Nb: We used to issue various definedness/addressability errors from here, but we took them out because they ranged from not-very-helpful to downright annoying, and they complicated the error data structures. */ -static Int mc_get_or_set_vbits_for_client ( - Addr a, - Addr vbits, - SizeT szB, - Bool setting, /* True <=> set vbits, False <=> get vbits */ - Bool is_client_request /* True <=> real user request - False <=> internal call from gdbserver */ +static Int mc_get_or_set_vbits_for_client ( + Addr a, + Addr vbits, + SizeT szB, + Bool setting, /* True <=> set vbits, False <=> get vbits */ + Bool is_client_request /* True <=> real user request + False <=> internal call from gdbserver */ ) { SizeT i; @@ -5918,7 +5918,7 @@ static void init_shadow_memory ( void ) /* Auxiliary primary maps */ init_auxmap_L1_L2(); - /* auxmap_size = auxmap_used = 0; + /* auxmap_size = auxmap_used = 0; no ... these are statically initialised */ /* Secondary V bit table */ @@ -6320,7 +6320,7 @@ static void mc_print_usage(void) } static void mc_print_debug_usage(void) -{ +{ VG_(printf)( " (none)\n" ); @@ -6332,13 +6332,13 @@ static void mc_print_debug_usage(void) /*------------------------------------------------------------*/ /* Client block management: - + This is managed as an expanding array of client block descriptors. Indices of live descriptors are issued to the client, so it can ask to free them later. Therefore we cannot slide live entries down over dead ones. Instead we must use free/inuse flags and scan for an empty slot at allocation time. This in turn means allocation is - relatively expensive, so we hope this does not happen too often. + relatively expensive, so we hope this does not happen too often. An unused block has start == size == 0 */ @@ -6391,7 +6391,7 @@ Int alloc_client_block ( void ) sz_new = (cgbs == NULL) ? 10 : (2 * cgb_size); cgbs_new = VG_(malloc)( "mc.acb.1", sz_new * sizeof(CGenBlock) ); - for (i = 0; i < cgb_used; i++) + for (i = 0; i < cgb_used; i++) cgbs_new[i] = cgbs[i]; if (cgbs != NULL) @@ -6408,14 +6408,14 @@ Int alloc_client_block ( void ) static void show_client_block_stats ( void ) { - VG_(message)(Vg_DebugMsg, + VG_(message)(Vg_DebugMsg, "general CBs: %llu allocs, %llu discards, %llu maxinuse, %llu search\n", - cgb_allocs, cgb_discards, cgb_used_MAX, cgb_search + cgb_allocs, cgb_discards, cgb_used_MAX, cgb_search ); } static void print_monitor_help ( void ) { - VG_(gdb_printf) + VG_(gdb_printf) ( "\n" "memcheck monitor commands:\n" @@ -6436,7 +6436,7 @@ static void print_monitor_help ( void ) " leak_check [full*|summary|xtleak]\n" " [kinds kind1,kind2,...|reachable|possibleleak*|definiteleak]\n" " [heuristics heur1,heur2,...]\n" -" [increased*|changed|any]\n" +" [new|increased*|changed|any]\n" " [unlimited*|limited <max_loss_records_output>]\n" " * = defaults\n" " xtleak produces an xtree full leak result in xtleak.kcg.%%p.%%n\n" @@ -6574,9 +6574,9 @@ static Bool handle_gdb_monitor_command (ThreadId tid, HChar *req) /* NB: if possible, avoid introducing a new command below which starts with the same first letter(s) as an already existing command. This ensures a shorter abbreviation for the user. */ - switch (VG_(keyword_id) + switch (VG_(keyword_id) ("help get_vbits leak_check make_memory check_memory " - "block_list who_points_at xb xtmemory", + "block_list who_points_at xb xtmemory", wcmd, kwd_report_duplicated_matches)) { case -2: /* multiple matches */ return True; @@ -6593,10 +6593,10 @@ static Bool handle_gdb_monitor_command (ThreadId tid, HChar *req) Int i; Int unaddressable = 0; for (i = 0; i < szB; i++) { - Int res = mc_get_or_set_vbits_for_client - (address+i, (Addr) &vbits, 1, + Int res = mc_get_or_set_vbits_for_client + (address+i, (Addr) &vbits, 1, False, /* get them */ - False /* is client request */ ); + False /* is client request */ ); /* we are before the first character on next line, print a \n. */ if ((i % 32) == 0 && i != 0) VG_(printf) ("\n"); @@ -6625,7 +6625,7 @@ static Bool handle_gdb_monitor_command (ThreadId tid, HChar *req) LeakCheckParams lcp; HChar* xt_filename = NULL; HChar* kw; - + lcp.mode = LC_Full; lcp.show_leak_kinds = R2S(Possible) | R2S(Unreached); lcp.errors_for_leak_kinds = 0; // no errors for interactive leak search. @@ -6634,15 +6634,15 @@ static Bool handle_gdb_monitor_command (ThreadId tid, HChar *req) lcp.max_loss_records_output = 999999999; lcp.requested_by_monitor_command = True; lcp.xt_filename = NULL; - - for (kw = VG_(strtok_r) (NULL, " ", &ssaveptr); - kw != NULL; + + for (kw = VG_(strtok_r) (NULL, " ", &ssaveptr); + kw != NULL; kw = VG_(strtok_r) (NULL, " ", &ssaveptr)) { - switch (VG_(keyword_id) + switch (VG_(keyword_id) ("full summary xtleak " "kinds reachable possibleleak definiteleak " "heuristics " - "increased changed any " + "new increased changed any " "unlimited limited ", kw, kwd_report_all)) { case -2: err++; break; @@ -6653,14 +6653,14 @@ static Bool handle_gdb_monitor_command (ThreadId tid, HChar *req) lcp.mode = LC_Summary; break; case 2: /* xtleak */ lcp.mode = LC_Full; - xt_filename + xt_filename = VG_(expand_file_name)("--xtleak-mc_main.c", "xtleak.kcg.%p.%n"); lcp.xt_filename = xt_filename; break; case 3: { /* kinds */ wcmd = VG_(strtok_r) (NULL, " ", &ssaveptr); - if (wcmd == NULL + if (wcmd == NULL || !VG_(parse_enum_set)(MC_(parse_leak_kinds_tokens), True/*allow_all*/, wcmd, @@ -6674,7 +6674,7 @@ static Bool handle_gdb_monitor_command (ThreadId tid, HChar *req) lcp.show_leak_kinds = MC_(all_Reachedness)(); break; case 5: /* possibleleak */ - lcp.show_leak_kinds + lcp.show_leak_kinds = R2S(Possible) | R2S(IndirectLeak) | R2S(Unreached); break; case 6: /* definiteleak */ @@ -6682,7 +6682,7 @@ static Bool handle_gdb_monitor_command (ThreadId tid, HChar *req) break; case 7: { /* heuristics */ wcmd = VG_(strtok_r) (NULL, " ", &ssaveptr); - if (wcmd == NULL + if (wcmd == NULL || !VG_(parse_enum_set)(MC_(parse_leak_heuristics_tokens), True,/*allow_all*/ wcmd, @@ -6692,15 +6692,17 @@ static Bool handle_gdb_monitor_command (ThreadId tid, HChar *req) } break; } - case 8: /* increased */ + case 8: /* new */ + lcp.deltamode = LCD_New; break; + case 9: /* increased */ lcp.deltamode = LCD_Increased; break; - case 9: /* changed */ + case 10: /* changed */ lcp.deltamode = LCD_Changed; break; - case 10: /* any */ + case 11: /* any */ lcp.deltamode = LCD_Any; break; - case 11: /* unlimited */ + case 12: /* unlimited */ lcp.max_loss_records_output = 999999999; break; - case 12: { /* limited */ + case 13: { /* limited */ Int int_value; const HChar* endptr; @@ -6732,11 +6734,11 @@ static Bool handle_gdb_monitor_command (ThreadId tid, HChar *req) VG_(free)(xt_filename); return True; } - + case 3: { /* make_memory */ Addr address; SizeT szB = 1; - Int kwdid = VG_(keyword_id) + Int kwdid = VG_(keyword_id) ("noaccess undefined defined Definedifaddressable", VG_(strtok_r) (NULL, " ", &ssaveptr), kwd_report_all); if (!VG_(strtok_get_address_and_size) (&address, &szB, &ssaveptr)) @@ -6745,7 +6747,7 @@ static Bool handle_gdb_monitor_command (ThreadId tid, HChar *req) case -2: break; case -1: break; case 0: MC_(make_mem_noaccess) (address, szB); break; - case 1: make_mem_undefined_w_tid_and_okind ( address, szB, tid, + case 1: make_mem_undefined_w_tid_and_okind ( address, szB, tid, MC_OKIND_USER ); break; case 2: MC_(make_mem_defined) ( address, szB ); break; case 3: make_mem_defined_if_addressable ( address, szB ); break;; @@ -6765,7 +6767,7 @@ static Bool handle_gdb_monitor_command (ThreadId tid, HChar *req) ExeContext* origin_ec; MC_ReadResult res; - Int kwdid = VG_(keyword_id) + Int kwdid = VG_(keyword_id) ("addressable defined", VG_(strtok_r) (NULL, " ", &ssaveptr), kwd_report_all); if (!VG_(strtok_get_address_and_size) (&address, &szB, &ssaveptr)) @@ -6775,7 +6777,7 @@ static Bool handle_gdb_monitor_command (ThreadId tid, HChar *req) case -1: break; case 0: /* addressable */ if (is_mem_addressable ( address, szB, &bad_addr )) - VG_(printf) ("Address %p len %lu addressable\n", + VG_(printf) ("Address %p len %lu addressable\n", (void *)addre... [truncated message content] |
|
From: Paul F. <pj...@wa...> - 2022-12-30 16:54:45
|
Hi Philippe I can't comment on the python binding aspects as scripting is somewhat my Achilles heel. For the functionality this would be a welcome improvement. Many is the time that I've wanted to be able to type mo xb &foo sizeof(foo) but instead need to do p(rint)s first. Do you know whether this would also facilitate integration of Valgrind debugging in environments like vscode, Qt Creator and CLion? Whilst on the subject of CLion, I did recently get an opensource licence for it from jetbrains (mostly to check integration and things like this https://bugs.kde.org/show_bug.cgi?id=454925). If anyone else would like to try it out for Valgrind use only then let me know. A+ Paul |
|
From: Philippe W. <phi...@so...> - 2022-12-30 15:30:31
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=c8bb6a62caf701b204362a46a8722b0e9d843d07 commit c8bb6a62caf701b204362a46a8722b0e9d843d07 Author: Philippe Waroquiers <phi...@sk...> Date: Fri Dec 30 16:28:23 2022 +0100 Add clo option -scheduling-quantum=<number> to control scheduler time slice. This option can be useful when tracking race conditions which are sensitive to thread scheduling. Diff: --- coregrind/m_main.c | 4 ++++ coregrind/m_options.c | 5 +++++ coregrind/m_scheduler/scheduler.c | 9 ++------- coregrind/pub_core_options.h | 2 ++ docs/xml/manual-core.xml | 17 +++++++++++++++++ none/tests/cmdline1.stdout.exp | 2 ++ none/tests/cmdline2.stdout.exp | 2 ++ 7 files changed, 34 insertions(+), 7 deletions(-) diff --git a/coregrind/m_main.c b/coregrind/m_main.c index 2b4a8748ff..c966873e26 100644 --- a/coregrind/m_main.c +++ b/coregrind/m_main.c @@ -202,6 +202,8 @@ static void usage_NORETURN ( int need_help ) " where hint is one of:\n" " lax-ioctls lax-doors fuse-compatible enable-outer\n" " no-inner-prefix no-nptl-pthread-stackcache fallback-llsc none\n" +" --scheduling-quantum=<number> thread-scheduling timeslice in number of\n" +" basic blocks [100000]\n" " --fair-sched=no|yes|try schedule threads fairly on multicore systems [no]\n" " --kernel-variant=variant1,variant2,...\n" " handle non-standard kernel variants [none]\n" @@ -622,6 +624,8 @@ static void process_option (Clo_Mode mode, else if VG_BOOL_CLOM(cloPD, arg, "--trace-children", VG_(clo_trace_children)) {} else if VG_BOOL_CLOM(cloPD, arg, "--child-silent-after-fork", VG_(clo_child_silent_after_fork)) {} +else if VG_INT_CLOM(cloPD, arg, "--scheduling-quantum", + VG_(clo_scheduling_quantum)) {} else if VG_STR_CLO(arg, "--fair-sched", tmp_str) { if (VG_(Clo_Mode)() != cloP) ; diff --git a/coregrind/m_options.c b/coregrind/m_options.c index c35d0aa1dd..92ac3ad190 100644 --- a/coregrind/m_options.c +++ b/coregrind/m_options.c @@ -150,6 +150,11 @@ Bool VG_(clo_debug_dump_frames) = False; Bool VG_(clo_trace_redir) = False; enum FairSchedType VG_(clo_fair_sched) = disable_fair_sched; +/* VG_(clo_scheduling_quantum) defines the thread-scheduling timeslice, + in terms of the number of basic blocks we attempt to run each thread for. + Smaller values give finer interleaving but much increased scheduling + overheads. */ +Word VG_(clo_scheduling_quantum) = 100000; Bool VG_(clo_trace_sched) = False; Bool VG_(clo_profile_heap) = False; UInt VG_(clo_progress_interval) = 0; /* in seconds, 1 .. 3600, diff --git a/coregrind/m_scheduler/scheduler.c b/coregrind/m_scheduler/scheduler.c index 027560c2ad..5ecb39076b 100644 --- a/coregrind/m_scheduler/scheduler.c +++ b/coregrind/m_scheduler/scheduler.c @@ -101,11 +101,6 @@ /* ThreadId and ThreadState are defined elsewhere*/ -/* Defines the thread-scheduling timeslice, in terms of the number of - basic blocks we attempt to run each thread for. Smaller values - give finer interleaving but much increased scheduling overheads. */ -#define SCHEDULING_QUANTUM 100000 - /* If False, a fault is Valgrind-internal (ie, a bug) */ Bool VG_(in_generated_code) = False; @@ -1389,7 +1384,7 @@ VgSchedReturnCode VG_(scheduler) ( ThreadId tid ) vg_assert(VG_(is_running_thread)(tid)); - dispatch_ctr = SCHEDULING_QUANTUM; + dispatch_ctr = VG_(clo_scheduling_quantum); while (!VG_(is_exiting)(tid)) { @@ -1440,7 +1435,7 @@ VgSchedReturnCode VG_(scheduler) ( ThreadId tid ) n_scheduling_events_MAJOR++; /* Figure out how many bbs to ask vg_run_innerloop to do. */ - dispatch_ctr = SCHEDULING_QUANTUM; + dispatch_ctr = VG_(clo_scheduling_quantum); /* paranoia ... */ vg_assert(tst->tid == tid); diff --git a/coregrind/pub_core_options.h b/coregrind/pub_core_options.h index e2ea1dc5b1..e949311af1 100644 --- a/coregrind/pub_core_options.h +++ b/coregrind/pub_core_options.h @@ -209,6 +209,8 @@ extern Bool VG_(clo_trace_redir); /* Enable fair scheduling on multicore systems? default: NO */ enum FairSchedType { disable_fair_sched, enable_fair_sched, try_fair_sched }; extern enum FairSchedType VG_(clo_fair_sched); +/* thread-scheduling timeslice. */ +extern Word VG_(clo_scheduling_quantum); /* DEBUG: print thread scheduling events? default: NO */ extern Bool VG_(clo_trace_sched); /* DEBUG: do heap profiling? default: NO */ diff --git a/docs/xml/manual-core.xml b/docs/xml/manual-core.xml index 70253e7c31..558d1f62df 100644 --- a/docs/xml/manual-core.xml +++ b/docs/xml/manual-core.xml @@ -2303,6 +2303,23 @@ need to use them.</para> </listitem> </varlistentry> + <varlistentry id="opt.scheduling-quantum" xreflabel="--scheduling-quantum"> + <term> + <option><![CDATA[--scheduling-quantum=<number> [default: 100000] ]]></option> + </term> + <listitem> + <para>The <option>--scheduling-quantum</option> option controls + the maximum number of basic blocks executed by a thread before releasing + the lock used by Valgrind to serialise thread execution. Smaller values + give finer interleaving but increases the scheduling overhead. Finer + interleaving can be useful to reproduce race conditions with helgrind or + DRD. For more details about the Valgrind thread serialisation scheme and + its impact on performance and thread scheduling, see + <xref linkend="&vg-pthreads-perf-sched-id;"/>. + </para> + </listitem> + </varlistentry> + <varlistentry id="opt.fair-sched" xreflabel="--fair-sched"> <term> <option><![CDATA[--fair-sched=<no|yes|try> [default: no] ]]></option> diff --git a/none/tests/cmdline1.stdout.exp b/none/tests/cmdline1.stdout.exp index 6a3405090b..de5fcd819a 100644 --- a/none/tests/cmdline1.stdout.exp +++ b/none/tests/cmdline1.stdout.exp @@ -115,6 +115,8 @@ usage: valgrind [options] prog-and-args where hint is one of: lax-ioctls lax-doors fuse-compatible enable-outer no-inner-prefix no-nptl-pthread-stackcache fallback-llsc none + --scheduling-quantum=<number> thread-scheduling timeslice in number of + basic blocks [100000] --fair-sched=no|yes|try schedule threads fairly on multicore systems [no] --kernel-variant=variant1,variant2,... handle non-standard kernel variants [none] diff --git a/none/tests/cmdline2.stdout.exp b/none/tests/cmdline2.stdout.exp index 95e9e96f83..d810cc7fa3 100644 --- a/none/tests/cmdline2.stdout.exp +++ b/none/tests/cmdline2.stdout.exp @@ -115,6 +115,8 @@ usage: valgrind [options] prog-and-args where hint is one of: lax-ioctls lax-doors fuse-compatible enable-outer no-inner-prefix no-nptl-pthread-stackcache fallback-llsc none + --scheduling-quantum=<number> thread-scheduling timeslice in number of + basic blocks [100000] --fair-sched=no|yes|try schedule threads fairly on multicore systems [no] --kernel-variant=variant1,variant2,... handle non-standard kernel variants [none] |
|
From: Paul F. <pa...@so...> - 2022-12-30 12:48:02
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=ccbb75cf1d6fa24562f7fa5c5a70a4a56dcc7fa0 commit ccbb75cf1d6fa24562f7fa5c5a70a4a56dcc7fa0 Author: Paul Floyd <pj...@wa...> Date: Fri Dec 30 13:46:09 2022 +0100 FreeeBSD: Add Helgrind suppression for void __thread_specific_ptr<_Tp>::set_pointer(pointer __p) Diff: --- freebsd-helgrind.supp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/freebsd-helgrind.supp b/freebsd-helgrind.supp index 6c51bfbd01..71bfcb6abc 100644 --- a/freebsd-helgrind.supp +++ b/freebsd-helgrind.supp @@ -157,3 +157,8 @@ Helgrind:Race fun:_ZL11* } +{ + HELGRIND-CXX-TLS + Helgrind:Race + fun:_ZNSt3__121__thread_specific_ptrINS_15__thread_structEE11set_pointerEPS1_ +} |
|
From: Paul F. <pa...@so...> - 2022-12-29 21:23:17
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=5cfb0173eda1843904650bef755b3e19a5b3fb1b commit 5cfb0173eda1843904650bef755b3e19a5b3fb1b Author: Paul Floyd <pj...@wa...> Date: Thu Dec 29 22:21:03 2022 +0100 Add DRD shared_timed_mutex to Helgrind This uses pthread_rwlock_timedrdlock / pthread_rwlock_timedwrlock (see commit 6ffb70e650ee7cf4ada829557dd30ababb09e078) Diff: --- helgrind/tests/Makefile.am | 1 + helgrind/tests/shared_timed_mutex.stderr.exp | 3 +++ helgrind/tests/shared_timed_mutex.vgtest | 3 +++ 3 files changed, 7 insertions(+) diff --git a/helgrind/tests/Makefile.am b/helgrind/tests/Makefile.am index 32f926b74f..ac6b15af77 100755 --- a/helgrind/tests/Makefile.am +++ b/helgrind/tests/Makefile.am @@ -66,6 +66,7 @@ EXTRA_DIST = \ pth_spinlock.vgtest pth_spinlock.stdout.exp pth_spinlock.stderr.exp \ rwlock_race.vgtest rwlock_race.stdout.exp rwlock_race.stderr.exp \ rwlock_test.vgtest rwlock_test.stdout.exp rwlock_test.stderr.exp \ + shared_timed_mutex.vgtest shared_timed_mutex.stderr.exp \ shmem_abits.vgtest shmem_abits.stdout.exp shmem_abits.stderr.exp \ stackteardown.vgtest stackteardown.stdout.exp stackteardown.stderr.exp \ t2t_laog.vgtest t2t_laog.stdout.exp t2t_laog.stderr.exp \ diff --git a/helgrind/tests/shared_timed_mutex.stderr.exp b/helgrind/tests/shared_timed_mutex.stderr.exp new file mode 100644 index 0000000000..d18786f806 --- /dev/null +++ b/helgrind/tests/shared_timed_mutex.stderr.exp @@ -0,0 +1,3 @@ + + +ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) diff --git a/helgrind/tests/shared_timed_mutex.vgtest b/helgrind/tests/shared_timed_mutex.vgtest new file mode 100644 index 0000000000..d3a044379c --- /dev/null +++ b/helgrind/tests/shared_timed_mutex.vgtest @@ -0,0 +1,3 @@ +prereq: test -e ../../drd/tests/shared_timed_mutex +vgopts: --read-var-info=yes +prog: ../../drd/tests/shared_timed_mutex |
|
From: Paul F. <pa...@so...> - 2022-12-29 21:10:14
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=d7c93d1f71f36e0b67770125b48a2583662af152 commit d7c93d1f71f36e0b67770125b48a2583662af152 Author: Paul Floyd <pj...@wa...> Date: Thu Dec 29 22:08:14 2022 +0100 Add a variation of the Helgrind tls_threads test This version uses GLIBC_TUNABLES in the environment so it checks that glibc.pthread.stack_cache_size can be detected and modified. Diff: --- helgrind/tests/Makefile.am | 1 + helgrind/tests/tls_threads2.stderr.exp | 2 ++ helgrind/tests/tls_threads2.vgtest | 4 ++++ 3 files changed, 7 insertions(+) diff --git a/helgrind/tests/Makefile.am b/helgrind/tests/Makefile.am index 2157f7cd38..32f926b74f 100755 --- a/helgrind/tests/Makefile.am +++ b/helgrind/tests/Makefile.am @@ -135,6 +135,7 @@ EXTRA_DIST = \ tc24_nonzero_sem.stderr.exp \ tls_threads.vgtest tls_threads.stdout.exp \ tls_threads.stderr.exp \ + tls_threads2.vgtest tls_threads2.stderr.exp \ trylock.vgtest trylock.stderr.exp # Wrapper headers used by some check programs. diff --git a/helgrind/tests/tls_threads2.stderr.exp b/helgrind/tests/tls_threads2.stderr.exp new file mode 100644 index 0000000000..be3b8904e7 --- /dev/null +++ b/helgrind/tests/tls_threads2.stderr.exp @@ -0,0 +1,2 @@ +starting join in main +finished join in main diff --git a/helgrind/tests/tls_threads2.vgtest b/helgrind/tests/tls_threads2.vgtest new file mode 100644 index 0000000000..f8f0ad15be --- /dev/null +++ b/helgrind/tests/tls_threads2.vgtest @@ -0,0 +1,4 @@ +prereq: ../../tests/os_test linux +env: GLIBC_TUNABLES=glibc.pthread.mutex_spin_count=4:glibc.pthread.stack_cache_size=41943040:glibc.pthread.rseq=1 +prog: tls_threads +vgopts: -q --sim-hints=no-nptl-pthread-stackcache |
|
From: Paul F. <pa...@so...> - 2022-12-29 21:03:03
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=6ffb70e650ee7cf4ada829557dd30ababb09e078 commit 6ffb70e650ee7cf4ada829557dd30ababb09e078 Author: Paul Floyd <pj...@wa...> Date: Thu Dec 29 22:00:53 2022 +0100 Bug 400793 - pthread_rwlock_timedwrlock false positive Add Helgrind intercepts for pthread_rwlock_timedwrlock (and pthread_rwlock_timedrdlock) Reuse the DRD trylock test Diff: --- NEWS | 1 + helgrind/hg_intercepts.c | 18 ++++++++++++------ helgrind/tests/Makefile.am | 3 ++- helgrind/tests/trylock.stderr.exp | 13 +++++++++++++ helgrind/tests/trylock.vgtest | 1 + 5 files changed, 29 insertions(+), 7 deletions(-) diff --git a/NEWS b/NEWS index 071f654b50..16ae313dfc 100644 --- a/NEWS +++ b/NEWS @@ -32,6 +32,7 @@ are not entered into bugzilla tend to get forgotten about or ignored. 170510 Don't warn about ioctl of size 0 without direction hint 351857 confusing error message about valid command line option 392331 Spurious lock not held error from inside pthread_cond_timedwait +400793 pthread_rwlock_timedwrlock false positive 444110 priv/guest_ppc_toIR.c:36198:31: warning: duplicated 'if' condition. 444488 Use glibc.pthread.stack_cache_size tunable 444568 drd/tests/pth_barrier_thr_cr fails on Fedora 38 diff --git a/helgrind/hg_intercepts.c b/helgrind/hg_intercepts.c index 0d29cb3bfa..5a83996e36 100644 --- a/helgrind/hg_intercepts.c +++ b/helgrind/hg_intercepts.c @@ -2222,9 +2222,6 @@ static int pthread_spin_trylock_WRK(pthread_spinlock_t *lock) pthread_rwlock_unlock pthread_rwlock_tryrdlock pthread_rwlock_trywrlock - - Unhandled: pthread_rwlock_timedrdlock - pthread_rwlock_timedwrlock */ //----------------------------------------------------------- @@ -2676,7 +2673,7 @@ static int pthread_rwlock_tryrdlock_WRK(pthread_rwlock_t* rwlock) //----------------------------------------------------------- -// glibc: Unhandled +// glibc: pthread_rwlock_timedrdlock // darwin: Unhandled // Solaris: pthread_rwlock_timedrdlock // Solaris: pthread_rwlock_reltimedrdlock_np @@ -2712,6 +2709,11 @@ static int pthread_rwlock_timedrdlock_WRK(pthread_rwlock_t *rwlock, return ret; } #if defined(VGO_linux) +PTH_FUNC(int, pthreadZurwlockZutimedrdlock, // pthread_rwlock_timedrdlock + pthread_rwlock_t *rwlock, + const struct timespec *timeout) { + return pthread_rwlock_timedrdlock_WRK(rwlock, timeout); +} #elif defined(VGO_darwin) #elif defined(VGO_freebsd) PTH_FUNC(int, pthreadZurwlockZutimedrdlock, // pthread_rwlock_timedrdlock @@ -2779,8 +2781,7 @@ PTH_FUNC(int, pthreadZurwlockZuclockrdlock, // pthread_rwlock_clockrdlock //----------------------------------------------------------- -// glibc: Unhandled -// darwin: Unhandled +// glibc: pthread_rwlock_timedwrlock // Solaris: pthread_rwlock_timedwrlock // Solaris: pthread_rwlock_reltimedwrlock_np // FreeBSD: pthread_rwlock_timedwrlock @@ -2815,6 +2816,11 @@ static int pthread_rwlock_timedwrlock_WRK(pthread_rwlock_t *rwlock, return ret; } #if defined(VGO_linux) +PTH_FUNC(int, pthreadZurwlockZutimedwrlock, // pthread_rwlock_timedwrlock + pthread_rwlock_t *rwlock, + const struct timespec *timeout) { + return pthread_rwlock_timedwrlock_WRK(rwlock, timeout); +} #elif defined(VGO_darwin) #elif defined(VGO_freebsd) PTH_FUNC(int, pthreadZurwlockZutimedwrlock, // pthread_rwlock_timedwrlock diff --git a/helgrind/tests/Makefile.am b/helgrind/tests/Makefile.am index 28f4c61912..2157f7cd38 100755 --- a/helgrind/tests/Makefile.am +++ b/helgrind/tests/Makefile.am @@ -134,7 +134,8 @@ EXTRA_DIST = \ tc24_nonzero_sem.vgtest tc24_nonzero_sem.stdout.exp \ tc24_nonzero_sem.stderr.exp \ tls_threads.vgtest tls_threads.stdout.exp \ - tls_threads.stderr.exp + tls_threads.stderr.exp \ + trylock.vgtest trylock.stderr.exp # Wrapper headers used by some check programs. noinst_HEADERS = safe-pthread.h safe-semaphore.h diff --git a/helgrind/tests/trylock.stderr.exp b/helgrind/tests/trylock.stderr.exp new file mode 100644 index 0000000000..e3aea4bd4e --- /dev/null +++ b/helgrind/tests/trylock.stderr.exp @@ -0,0 +1,13 @@ + +Locking rwlock via pthread_rwlock_wrlock(). +Locking rwlock via pthread_rwlock_trywrlock(). +Locking rwlock via pthread_rwlock_timedwrlock(). +Locking rwlock via pthread_rwlock_rdlock(). +Locking rwlock via pthread_rwlock_tryrdlock(). +Locking rwlock via pthread_rwlock_timedrdlock(). +Attempt to lock for writing recursively (not allowed). +Locking mutex via pthread_mutex_trylock(). +Locking mutex via pthread_mutex_lock(). +Locking mutex via pthread_mutex_timedlock(). + +ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) diff --git a/helgrind/tests/trylock.vgtest b/helgrind/tests/trylock.vgtest new file mode 100644 index 0000000000..1d4f16d3b8 --- /dev/null +++ b/helgrind/tests/trylock.vgtest @@ -0,0 +1 @@ +prog: ../../drd/tests/trylock |
|
From: Paul F. <pa...@so...> - 2022-12-29 20:00:36
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=ab1eb2cb7473013e1458630372ee1fde2e4f66e9 commit ab1eb2cb7473013e1458630372ee1fde2e4f66e9 Author: Paul Floyd <pj...@wa...> Date: Thu Dec 29 20:59:25 2022 +0100 Update modified hg04 reference for DRD. Diff: --- drd/tests/hg04_race.stderr.exp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drd/tests/hg04_race.stderr.exp b/drd/tests/hg04_race.stderr.exp index 5b5969c995..4cc01a213f 100644 --- a/drd/tests/hg04_race.stderr.exp +++ b/drd/tests/hg04_race.stderr.exp @@ -1,8 +1,8 @@ Thread 3: Conflicting load by thread 3 at 0x........ size 4 - at 0x........: th (hg04_race.c:10) - by 0x........: vgDrd_thread_wrapper (drd_pthread_intercepts.c:?) + at 0x........: th10 (hg04_race.c:11) + by 0x........: th9 (hg04_race.c:17) Location 0x........ is 0 bytes inside global var "shared" declared at hg04_race.c:6 Other segment start (thread 2) @@ -11,8 +11,8 @@ Other segment end (thread 2) (thread finished, call stack no longer available) Conflicting store by thread 3 at 0x........ size 4 - at 0x........: th (hg04_race.c:10) - by 0x........: vgDrd_thread_wrapper (drd_pthread_intercepts.c:?) + at 0x........: th10 (hg04_race.c:11) + by 0x........: th9 (hg04_race.c:17) Location 0x........ is 0 bytes inside global var "shared" declared at hg04_race.c:6 Other segment start (thread 2) |
|
From: Philippe W. <phi...@so...> - 2022-12-29 15:37:58
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=a5b88a02d5750c464736ab1d4c66cedd4182c79e commit a5b88a02d5750c464736ab1d4c66cedd4182c79e Author: Philippe Waroquiers <phi...@sk...> Date: Thu Dec 29 15:56:36 2022 +0100 Add a test for helgrind --history-backtrace-size Extend hg04_race to have more entries in the conflicting stacktrace, and make another test hg04_race_h9 to test with one more entry than the default of 8. Diff: --- helgrind/tests/Makefile.am | 1 + helgrind/tests/hg04_race.c | 67 ++++++++++++++++++++++++++-- helgrind/tests/hg04_race.stderr.exp | 52 ++++++++++++++++------ helgrind/tests/hg04_race_h9.stderr.exp | 79 ++++++++++++++++++++++++++++++++++ helgrind/tests/hg04_race_h9.stdout.exp | 0 helgrind/tests/hg04_race_h9.vgtest | 3 ++ 6 files changed, 187 insertions(+), 15 deletions(-) diff --git a/helgrind/tests/Makefile.am b/helgrind/tests/Makefile.am index 2286e220f1..28f4c61912 100755 --- a/helgrind/tests/Makefile.am +++ b/helgrind/tests/Makefile.am @@ -34,6 +34,7 @@ EXTRA_DIST = \ hg02_deadlock.vgtest hg02_deadlock.stdout.exp hg02_deadlock.stderr.exp \ hg03_inherit.vgtest hg03_inherit.stdout.exp hg03_inherit.stderr.exp \ hg04_race.vgtest hg04_race.stdout.exp hg04_race.stderr.exp \ + hg04_race_h9.vgtest hg04_race_h9.stdout.exp hg04_race_h9.stderr.exp \ hg05_race2.vgtest hg05_race2.stdout.exp hg05_race2.stderr.exp \ hg06_readshared.vgtest hg06_readshared.stdout.exp \ hg06_readshared.stderr.exp \ diff --git a/helgrind/tests/hg04_race.c b/helgrind/tests/hg04_race.c index 111195bf90..760caf8860 100644 --- a/helgrind/tests/hg04_race.c +++ b/helgrind/tests/hg04_race.c @@ -5,18 +5,79 @@ static int shared; +__attribute__((noinline)) +static void th10(void) +{ + shared++; +} + +__attribute__((noinline)) +static void th9(void) +{ + th10(); +} + +__attribute__((noinline)) +static void th8(void) +{ + th9(); +} + +__attribute__((noinline)) +static void th7(void) +{ + th8(); +} + +__attribute__((noinline)) +static void th6(void) +{ + th7(); +} + +__attribute__((noinline)) +static void th5(void) +{ + th6(); +} + +__attribute__((noinline)) +static void th4(void) +{ + th5(); +} + +__attribute__((noinline)) +static void th3(void) +{ + th4(); +} + +__attribute__((noinline)) +static void th2(void) +{ + th3(); +} + + +__attribute__((noinline)) +static void th1(void) +{ + th2(); +} + static void *th(void *v) { - shared++; + th1(); - return 0; + return 0; } int main() { pthread_t a, b; - pthread_create(&a, NULL, th, NULL); + pthread_create(&a, NULL, th, NULL); sleep(1); /* force ordering */ pthread_create(&b, NULL, th, NULL); diff --git a/helgrind/tests/hg04_race.stderr.exp b/helgrind/tests/hg04_race.stderr.exp index 67f6573963..f66394bd13 100644 --- a/helgrind/tests/hg04_race.stderr.exp +++ b/helgrind/tests/hg04_race.stderr.exp @@ -4,28 +4,42 @@ Thread #x was created ... by 0x........: pthread_create@* (hg_intercepts.c:...) - by 0x........: main (hg04_race.c:21) + by 0x........: main (hg04_race.c:82) ---Thread-Announcement------------------------------------------ Thread #x was created ... by 0x........: pthread_create@* (hg_intercepts.c:...) - by 0x........: main (hg04_race.c:19) + by 0x........: main (hg04_race.c:80) ---------------------------------------------------------------- Possible data race during read of size 4 at 0x........ by thread #x Locks held: none - at 0x........: th (hg04_race.c:10) + at 0x........: th10 (hg04_race.c:11) + by 0x........: th9 (hg04_race.c:17) + by 0x........: th8 (hg04_race.c:23) + by 0x........: th7 (hg04_race.c:29) + by 0x........: th6 (hg04_race.c:35) + by 0x........: th5 (hg04_race.c:41) + by 0x........: th4 (hg04_race.c:47) + by 0x........: th3 (hg04_race.c:53) + by 0x........: th2 (hg04_race.c:59) + by 0x........: th1 (hg04_race.c:66) + by 0x........: th (hg04_race.c:71) by 0x........: mythread_wrapper (hg_intercepts.c:...) - ... This conflicts with a previous write of size 4 by thread #x Locks held: none - at 0x........: th (hg04_race.c:10) - by 0x........: mythread_wrapper (hg_intercepts.c:...) - ... + at 0x........: th10 (hg04_race.c:11) + by 0x........: th9 (hg04_race.c:17) + by 0x........: th8 (hg04_race.c:23) + by 0x........: th7 (hg04_race.c:29) + by 0x........: th6 (hg04_race.c:35) + by 0x........: th5 (hg04_race.c:41) + by 0x........: th4 (hg04_race.c:47) + by 0x........: th3 (hg04_race.c:53) Location 0x........ is 0 bytes inside global var "shared" declared at hg04_race.c:6 @@ -33,15 +47,29 @@ Locks held: none Possible data race during write of size 4 at 0x........ by thread #x Locks held: none - at 0x........: th (hg04_race.c:10) + at 0x........: th10 (hg04_race.c:11) + by 0x........: th9 (hg04_race.c:17) + by 0x........: th8 (hg04_race.c:23) + by 0x........: th7 (hg04_race.c:29) + by 0x........: th6 (hg04_race.c:35) + by 0x........: th5 (hg04_race.c:41) + by 0x........: th4 (hg04_race.c:47) + by 0x........: th3 (hg04_race.c:53) + by 0x........: th2 (hg04_race.c:59) + by 0x........: th1 (hg04_race.c:66) + by 0x........: th (hg04_race.c:71) by 0x........: mythread_wrapper (hg_intercepts.c:...) - ... This conflicts with a previous write of size 4 by thread #x Locks held: none - at 0x........: th (hg04_race.c:10) - by 0x........: mythread_wrapper (hg_intercepts.c:...) - ... + at 0x........: th10 (hg04_race.c:11) + by 0x........: th9 (hg04_race.c:17) + by 0x........: th8 (hg04_race.c:23) + by 0x........: th7 (hg04_race.c:29) + by 0x........: th6 (hg04_race.c:35) + by 0x........: th5 (hg04_race.c:41) + by 0x........: th4 (hg04_race.c:47) + by 0x........: th3 (hg04_race.c:53) Location 0x........ is 0 bytes inside global var "shared" declared at hg04_race.c:6 diff --git a/helgrind/tests/hg04_race_h9.stderr.exp b/helgrind/tests/hg04_race_h9.stderr.exp new file mode 100644 index 0000000000..6e692e749a --- /dev/null +++ b/helgrind/tests/hg04_race_h9.stderr.exp @@ -0,0 +1,79 @@ + +---Thread-Announcement------------------------------------------ + +Thread #x was created + ... + by 0x........: pthread_create@* (hg_intercepts.c:...) + by 0x........: main (hg04_race.c:82) + +---Thread-Announcement------------------------------------------ + +Thread #x was created + ... + by 0x........: pthread_create@* (hg_intercepts.c:...) + by 0x........: main (hg04_race.c:80) + +---------------------------------------------------------------- + +Possible data race during read of size 4 at 0x........ by thread #x +Locks held: none + at 0x........: th10 (hg04_race.c:11) + by 0x........: th9 (hg04_race.c:17) + by 0x........: th8 (hg04_race.c:23) + by 0x........: th7 (hg04_race.c:29) + by 0x........: th6 (hg04_race.c:35) + by 0x........: th5 (hg04_race.c:41) + by 0x........: th4 (hg04_race.c:47) + by 0x........: th3 (hg04_race.c:53) + by 0x........: th2 (hg04_race.c:59) + by 0x........: th1 (hg04_race.c:66) + by 0x........: th (hg04_race.c:71) + by 0x........: mythread_wrapper (hg_intercepts.c:...) + +This conflicts with a previous write of size 4 by thread #x +Locks held: none + at 0x........: th10 (hg04_race.c:11) + by 0x........: th9 (hg04_race.c:17) + by 0x........: th8 (hg04_race.c:23) + by 0x........: th7 (hg04_race.c:29) + by 0x........: th6 (hg04_race.c:35) + by 0x........: th5 (hg04_race.c:41) + by 0x........: th4 (hg04_race.c:47) + by 0x........: th3 (hg04_race.c:53) + by 0x........: th2 (hg04_race.c:59) + Location 0x........ is 0 bytes inside global var "shared" + declared at hg04_race.c:6 + +---------------------------------------------------------------- + +Possible data race during write of size 4 at 0x........ by thread #x +Locks held: none + at 0x........: th10 (hg04_race.c:11) + by 0x........: th9 (hg04_race.c:17) + by 0x........: th8 (hg04_race.c:23) + by 0x........: th7 (hg04_race.c:29) + by 0x........: th6 (hg04_race.c:35) + by 0x........: th5 (hg04_race.c:41) + by 0x........: th4 (hg04_race.c:47) + by 0x........: th3 (hg04_race.c:53) + by 0x........: th2 (hg04_race.c:59) + by 0x........: th1 (hg04_race.c:66) + by 0x........: th (hg04_race.c:71) + by 0x........: mythread_wrapper (hg_intercepts.c:...) + +This conflicts with a previous write of size 4 by thread #x +Locks held: none + at 0x........: th10 (hg04_race.c:11) + by 0x........: th9 (hg04_race.c:17) + by 0x........: th8 (hg04_race.c:23) + by 0x........: th7 (hg04_race.c:29) + by 0x........: th6 (hg04_race.c:35) + by 0x........: th5 (hg04_race.c:41) + by 0x........: th4 (hg04_race.c:47) + by 0x........: th3 (hg04_race.c:53) + by 0x........: th2 (hg04_race.c:59) + Location 0x........ is 0 bytes inside global var "shared" + declared at hg04_race.c:6 + + +ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0) diff --git a/helgrind/tests/hg04_race_h9.stdout.exp b/helgrind/tests/hg04_race_h9.stdout.exp new file mode 100644 index 0000000000..e69de29bb2 diff --git a/helgrind/tests/hg04_race_h9.vgtest b/helgrind/tests/hg04_race_h9.vgtest new file mode 100644 index 0000000000..528d7a19ac --- /dev/null +++ b/helgrind/tests/hg04_race_h9.vgtest @@ -0,0 +1,3 @@ +prog: hg04_race +vgopts: --read-var-info=yes --history-backtrace-size=9 +stderr_filter_args: hg04_race.c |
|
From: Philippe W. <phi...@so...> - 2022-12-29 12:19:00
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=3c916e4cbf82eace7b9721a95f0217211aeb05fb commit 3c916e4cbf82eace7b9721a95f0217211aeb05fb Author: Philippe Waroquiers <phi...@sk...> Date: Thu Dec 29 13:18:27 2022 +0100 Fix typo in NEWS. Diff: --- NEWS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 664c08a970..071f654b50 100644 --- a/NEWS +++ b/NEWS @@ -18,7 +18,7 @@ AMD64/macOS 10.13 and nanoMIPS/Linux. * Helgrind: - The option ---history-backtrace-size=<number> allows to configure the number of entries to record in the stack traces of "old" - accesses. Previous, this number was hardcoded to 8. + accesses. Previously, this number was hardcoded to 8. * ==================== FIXED BUGS ==================== |
|
From: Philippe W. <phi...@so...> - 2022-12-29 10:37:08
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=29252c77bbbcbc69eb94058677611a0e312eedf8 commit 29252c77bbbcbc69eb94058677611a0e312eedf8 Author: Philippe Waroquiers <phi...@sk...> Date: Thu Dec 29 11:11:01 2022 +0100 Add clo option the nr of entries in helgrind --history-level=full stack traces The number of such entries was hardcoded to 8. A new command line option -history-backtrace-size=number allows to set the (max) number of entries to record. Note that according perl perf/vg_perf --tools=helgrind --vg=. --vg=../trunk_untouched perf this change (unexpectedly) improves some tests: - Running tests in perf ---------------------------------------------- -- bigcode1 -- bigcode1 . :0.08s he: 2.0s (25.5x, -----) bigcode1 trunk_untouched:0.08s he: 2.1s (25.9x, -1.5%) -- bigcode2 -- bigcode2 . :0.08s he: 4.2s (52.2x, -----) bigcode2 trunk_untouched:0.08s he: 4.2s (52.0x, 0.5%) -- bz2 -- bz2 . :0.40s he: 6.5s (16.3x, -----) bz2 trunk_untouched:0.40s he: 7.4s (18.5x,-14.0%) -- fbench -- fbench . :0.15s he: 2.0s (13.2x, -----) fbench trunk_untouched:0.15s he: 2.3s (15.5x,-17.7%) -- ffbench -- ffbench . :0.16s he: 3.7s (23.2x, -----) ffbench trunk_untouched:0.16s he: 3.7s (23.4x, -0.8%) -- heap -- heap . :0.05s he: 5.1s (102.8x, -----) heap trunk_untouched:0.05s he: 5.2s (104.6x, -1.8%) -- heap_pdb4 -- heap_pdb4 . :0.07s he: 5.8s (82.9x, -----) heap_pdb4 trunk_untouched:0.07s he: 5.8s (83.3x, -0.5%) -- many-loss-records -- many-loss-records . :0.01s he: 1.0s (96.0x, -----) many-loss-records trunk_untouched:0.01s he: 0.9s (95.0x, 1.0%) -- many-xpts -- many-xpts . :0.04s he: 1.6s (38.8x, -----) many-xpts trunk_untouched:0.04s he: 1.5s (38.5x, 0.6%) -- memrw -- memrw . :0.06s he: 2.5s (41.2x, -----) memrw trunk_untouched:0.06s he: 2.5s (41.2x, 0.0%) -- sarp -- sarp . :0.02s he: 4.0s (198.0x, -----) sarp trunk_untouched:0.02s he: 3.9s (196.5x, 0.8%) -- tinycc -- tinycc . :0.10s he: 7.1s (70.7x, -----) tinycc trunk_untouched:0.10s he: 7.6s (75.8x, -7.2%) -- Finished tests in perf ---------------------------------------------- == 12 programs, 24 timings ================= Diff: --- NEWS | 7 +++ helgrind/docs/hg-manual.xml | 33 +++++++---- helgrind/hg_basics.h | 3 + helgrind/hg_main.c | 13 +++- helgrind/libhb_core.c | 140 +++++++++++++++++++++++++------------------- 5 files changed, 123 insertions(+), 73 deletions(-) diff --git a/NEWS b/NEWS index b538ad5241..664c08a970 100644 --- a/NEWS +++ b/NEWS @@ -13,6 +13,13 @@ AMD64/macOS 10.13 and nanoMIPS/Linux. * Make the address space limit on FreeBSD amd64 128Gbytes (the same as Linux and Solaris, it was 32Gbytes) +* ==================== TOOL CHANGES =================== + +* Helgrind: + - The option ---history-backtrace-size=<number> allows to configure + the number of entries to record in the stack traces of "old" + accesses. Previous, this number was hardcoded to 8. + * ==================== FIXED BUGS ==================== The following bugs have been fixed or resolved. Note that "n-i-bz" diff --git a/helgrind/docs/hg-manual.xml b/helgrind/docs/hg-manual.xml index c00be7bd0c..7082e91f7a 100644 --- a/helgrind/docs/hg-manual.xml +++ b/helgrind/docs/hg-manual.xml @@ -666,9 +666,9 @@ the point it was detected.</para> "<computeroutput>This conflicts with a previous write</computeroutput>". This shows a previous access which also accessed the stated address, and which is believed to be racing -against the access in the first call stack. Note that this second -call stack is limited to a maximum of 8 entries to limit the -memory usage.</para> +against the access in the first call stack. Note that this second call +stack is limited to a maximum of <varname>--history-backtrace-size</varname> +entries with a default value of 8 to limit the memory usage.</para> <para>Finally, Helgrind may attempt to give a description of the raced-on address in source level terms. In this example, it @@ -1117,13 +1117,13 @@ unlock(mx) unlock(mx) [default: full] ]]></option> </term> <listitem> - <para><option>--history-level=full</option> (the default) causes - Helgrind collects enough information about "old" accesses that - it can produce two stack traces in a race report -- both the - stack trace for the current access, and the trace for the - older, conflicting access. To limit memory usage, "old" accesses - stack traces are limited to a maximum of 8 entries, even if - <option>--num-callers</option> value is bigger.</para> + <para><option>--history-level=full</option> (the default) causes Helgrind + collects enough information about "old" accesses that it can produce two + stack traces in a race report -- both the stack trace for the current + access, and the trace for the older, conflicting access. To limit memory + usage, "old" accesses stack traces are limited to a maximum + of <varname>--history-backtrace-size</varname> entries (default 8) or + to <option>--num-callers</option> value if this value is smaller.</para> <para>Collecting such information is expensive in both speed and memory, particularly for programs that do many inter-thread synchronisation events (locks, unlocks, etc). Without such @@ -1150,6 +1150,19 @@ unlock(mx) unlock(mx) </listitem> </varlistentry> + <varlistentry id="opt.history-backtrace-size" + xreflabel="--history-backtrace-size"> + <term> + <option><![CDATA[--history-backtrace-size=<number> + [default: 8] ]]></option> + </term> + <listitem> + <para>When <varname>--history-level=full</varname> is selected, + <varname>--history-backtrace-size=number</varname> indicates how many + entries to record in "old" accesses stack traces.</para> + </listitem> + </varlistentry> + <varlistentry id="opt.delta-stacktrace" xreflabel="--delta-stacktrace"> <term> diff --git a/helgrind/hg_basics.h b/helgrind/hg_basics.h index 89c1bc0f81..1698fca151 100644 --- a/helgrind/hg_basics.h +++ b/helgrind/hg_basics.h @@ -91,6 +91,9 @@ extern Bool HG_(clo_cmp_race_err_addrs); very useful). */ extern UWord HG_(clo_history_level); +/* Controls how many IPs an history stack records. */ +extern UInt HG_(clo_history_backtrace_size); + /* For full history level, determines how the stack trace is computed. no : a stacktrace is always computed from scratch, typically using the unwind information. diff --git a/helgrind/hg_main.c b/helgrind/hg_main.c index 813c983a4c..26a37ead5e 100644 --- a/helgrind/hg_main.c +++ b/helgrind/hg_main.c @@ -5756,6 +5756,11 @@ static Bool hg_process_cmd_line_option ( const HChar* arg ) else if VG_XACT_CLO(arg, "--history-level=full", HG_(clo_history_level), 2); + else if VG_BINT_CLO(arg, "--history-backtrace-size", + HG_(clo_history_backtrace_size), 2, 500) {} + // 500 just in case someone with a lot of CPU and memory would like to use + // the same value for --num-callers and this. + else if VG_BOOL_CLO(arg, "--delta-stacktrace", HG_(clo_delta_stacktrace)) {} @@ -5765,9 +5770,9 @@ static Bool hg_process_cmd_line_option ( const HChar* arg ) /* "stuvwx" --> stuvwx (binary) */ else if VG_STR_CLO(arg, "--hg-sanity-flags", tmp_str) { Int j; - + if (6 != VG_(strlen)(tmp_str)) { - VG_(message)(Vg_UserMsg, + VG_(message)(Vg_UserMsg, "--hg-sanity-flags argument must have 6 digits\n"); return False; } @@ -5798,7 +5803,7 @@ static Bool hg_process_cmd_line_option ( const HChar* arg ) else if VG_BOOL_CLO(arg, "--ignore-thread-creation", HG_(clo_ignore_thread_creation)) {} - else + else return VG_(replacement_malloc_process_cmd_line_option)(arg); return True; @@ -5813,6 +5818,8 @@ static void hg_print_usage ( void ) " full: show both stack traces for a data race (can be very slow)\n" " approx: full trace for one thread, approx for the other (faster)\n" " none: only show trace for one thread in a race (fastest)\n" +" --history-backtrace-size=<number> record <number> callers for full\n" +" history level [8]\n" " --delta-stacktrace=no|yes [yes on linux amd64/x86]\n" " no : always compute a full history stacktrace from unwind info\n" " yes : derive a stacktrace from the previous stacktrace\n" diff --git a/helgrind/libhb_core.c b/helgrind/libhb_core.c index 683c685f24..7c0ea84503 100644 --- a/helgrind/libhb_core.c +++ b/helgrind/libhb_core.c @@ -284,7 +284,8 @@ typedef #define N_KWs_N_STACKs_PER_THREAD 62500 -#define N_FRAMES 8 +UInt HG_(clo_history_backtrace_size) = 8; + // (UInt) `echo "Reference Counted Execution Context" | md5sum` #define RCEC_MAGIC 0xab88abb2UL @@ -297,7 +298,9 @@ typedef UWord rc; UWord rcX; /* used for crosschecking */ UWord frames_hash; /* hash of all the frames */ - UWord frames[N_FRAMES]; + UWord frames[0]; + /* Variable-length array. + The size depends on HG_(clo_history_backtrace_size). */ } RCEC; @@ -305,7 +308,7 @@ struct _Thr { /* Current VTSs for this thread. They change as we go along. viR is the VTS to be used for reads, viW for writes. Usually they are the same, but can differ when we deal with reader-writer - locks. It is always the case that + locks. It is always the case that VtsID__cmpLEQ(viW,viR) == True that is, viW must be the same, or lagging behind, viR. */ VtsID viR; @@ -337,19 +340,24 @@ struct _Thr { Thread should be merged into a single structure. */ Thread* hgthread; + /* The ULongs (scalar Kws) in this accumulate in strictly + increasing order, without duplicates. This is important because + we need to be able to find a given scalar Kw in this array + later, by binary search. */ + XArray* /* ULong_n_EC */ local_Kws_n_stacks; + /* cached_rcec maintains the last RCEC that was retrieved for this thread. */ - RCEC cached_rcec; // cached_rcec value, not ref-counted. + RCEC cached_rcec; + // cached_rcec value, not ref-counted. + // As the last member of an RCEC is a variable length array, this must be + // the last element of the _Thr struct. + /* The shadow register vex_shadow1 SP register (SP_s1) is used to maintain the validity of the cached rcec. If SP_s1 is 0, then the cached rcec is invalid (cannot be used). If SP_S1 is != 0, then the cached rcec is valid. The valid cached rcec can be used to generate a new RCEC by changing just the last frame. */ - /* The ULongs (scalar Kws) in this accumulate in strictly - increasing order, without duplicates. This is important because - we need to be able to find a given scalar Kw in this array - later, by binary search. */ - XArray* /* ULong_n_EC */ local_Kws_n_stacks; }; @@ -4061,7 +4069,12 @@ static inline void set_cached_rcec_validity(Thr *thr, Bool valid) static Thr* Thr__new ( void ) { - Thr* thr = HG_(zalloc)( "libhb.Thr__new.1", sizeof(Thr) ); + Thr* thr = HG_(zalloc) + ( "libhb.Thr__new.1", + sizeof(Thr) + HG_(clo_history_backtrace_size) * sizeof(UWord)); + // We need to add the size of the frames in the cached_rcec (last member of + // _Thr). + thr->viR = VtsID_INVALID; thr->viW = VtsID_INVALID; thr->llexit_done = False; @@ -4308,7 +4321,7 @@ static Bool RCEC__differs_by_frames ( RCEC* ec1, RCEC* ec2 ) { tl_assert(ec2 && ec2->magic == RCEC_MAGIC); } if (ec1->frames_hash != ec2->frames_hash) return True; - for (i = 0; i < N_FRAMES; i++) { + for (i = 0; i < HG_(clo_history_backtrace_size); i++) { if (ec1->frames[i] != ec2->frames[i]) return True; } return False; @@ -4424,6 +4437,8 @@ static RCEC* ctxt__find_or_add ( RCEC* example ) copy = alloc_RCEC(); tl_assert(copy != example); *copy = *example; + for (Word i = 0; i < HG_(clo_history_backtrace_size); i++) + copy->frames[i] = example->frames[i]; copy->next = contextTab[hent]; contextTab[hent] = copy; stats__ctxt_tab_curr++; @@ -4457,16 +4472,17 @@ static Bool check_cached_rcec_ok (Thr* thr, Addr previous_frame0) { Bool ok = True; UInt i; - UWord frames[N_FRAMES]; - UWord sps[N_FRAMES]; - UWord fps[N_FRAMES]; + UWord frames[HG_(clo_history_backtrace_size)]; + UWord sps[HG_(clo_history_backtrace_size)]; + UWord fps[HG_(clo_history_backtrace_size)]; const DiEpoch cur_ep = VG_(current_DiEpoch)(); - for (i = 0; i < N_FRAMES; i++) + for (i = 0; i < HG_(clo_history_backtrace_size); i++) frames[i] = sps[i] = fps[i] = 0; - VG_(get_StackTrace)( thr->hgthread->coretid, &frames[0], N_FRAMES, + VG_(get_StackTrace)( thr->hgthread->coretid, &frames[0], + HG_(clo_history_backtrace_size), &sps[0], &fps[0], 0); - for (i = 0; i < N_FRAMES; i++) { + for (i = 0; i < HG_(clo_history_backtrace_size); i++) { if ( thr->cached_rcec.frames[i] != frames[i] ) { /* There are a bunch of "normal" reasons for which a stack derived from the cached rcec differs from frames. */ @@ -4506,16 +4522,20 @@ static Bool check_cached_rcec_ok (Thr* thr, Addr previous_frame0) unless asked to show below main. */ if (reason == NULL) { UInt fr_main; - Vg_FnNameKind fr_kind; - for (fr_main = 0; fr_main < N_FRAMES; fr_main++) { + Vg_FnNameKind fr_kind = Vg_FnNameNormal; + for (fr_main = 0; + fr_main < HG_(clo_history_backtrace_size); + fr_main++) { fr_kind = VG_(get_fnname_kind_from_IP) (cur_ep, frames[fr_main]); if (fr_kind == Vg_FnNameMain || fr_kind == Vg_FnNameBelowMain) break; } UInt kh_main; - Vg_FnNameKind kh_kind; - for (kh_main = 0; kh_main < N_FRAMES; kh_main++) { + Vg_FnNameKind kh_kind = Vg_FnNameNormal; + for (kh_main = 0; + kh_main < HG_(clo_history_backtrace_size); + kh_main++) { kh_kind = VG_(get_fnname_kind_from_IP) (cur_ep, thr->cached_rcec.frames[kh_main]); if (kh_kind == Vg_FnNameMain || kh_kind == Vg_FnNameBelowMain) @@ -4558,7 +4578,7 @@ static Bool check_cached_rcec_ok (Thr* thr, Addr previous_frame0) if (reason == NULL) { if ((i > 0 && sps[i] == sps[i-1] && fps[i] == fps[i-1]) - || (i < N_FRAMES-1 + || (i < HG_(clo_history_backtrace_size)-1 && sps[i] == sps[i+1] && fps[i] == fps[i+1])) { reason = "previous||next frame: identical sp and fp"; } @@ -4566,7 +4586,7 @@ static Bool check_cached_rcec_ok (Thr* thr, Addr previous_frame0) if (reason == NULL) { if ((i > 0 && fps[i] == fps[i-1]) - || (i < N_FRAMES-1 + || (i < HG_(clo_history_backtrace_size)-1 && fps[i] == fps[i+1])) { reason = "previous||next frame: identical fp"; } @@ -4585,7 +4605,7 @@ static Bool check_cached_rcec_ok (Thr* thr, Addr previous_frame0) So, if we find __run_exit_handlers, ignore the difference. */ if (reason == NULL) { const HChar *fnname; - for (UInt f = 0; f < N_FRAMES; f++) { + for (UInt f = 0; f < HG_(clo_history_backtrace_size); f++) { if (VG_(get_fnname)( cur_ep, frames[f], &fnname) && VG_(strcmp) ("__run_exit_handlers", fnname) == 0) { reason = "exit handlers"; @@ -4633,9 +4653,10 @@ static Bool check_cached_rcec_ok (Thr* thr, Addr previous_frame0) (void*)previous_frame0); VG_(pp_StackTrace)(cur_ep, &previous_frame0, 1); VG_(printf)("resulting cached stack trace:\n"); - VG_(pp_StackTrace)(cur_ep, thr->cached_rcec.frames, N_FRAMES); + VG_(pp_StackTrace)(cur_ep, thr->cached_rcec.frames, + HG_(clo_history_backtrace_size)); VG_(printf)("check stack trace:\n"); - VG_(pp_StackTrace)(cur_ep, frames, N_FRAMES); + VG_(pp_StackTrace)(cur_ep, frames, HG_(clo_history_backtrace_size)); VG_(show_sched_status) (False, // host_stacktrace False, // stack_usage @@ -4697,20 +4718,22 @@ static RCEC* get_RCEC ( Thr* thr ) stats__cached_rcec_updated++; } else { /* Compute a fresh stacktrace. */ - main_get_stacktrace( thr, &thr->cached_rcec.frames[0], N_FRAMES ); + main_get_stacktrace( thr, &thr->cached_rcec.frames[0], + HG_(clo_history_backtrace_size) ); if (DEBUG_CACHED_RCEC) { Bool save_show_below_main = VG_(clo_show_below_main); VG_(clo_show_below_main) = True; VG_(printf)("caching stack trace:\n"); VG_(pp_StackTrace)(VG_(current_DiEpoch)(), - &thr->cached_rcec.frames[0], N_FRAMES); + &thr->cached_rcec.frames[0], + HG_(clo_history_backtrace_size)); VG_(clo_show_below_main) = save_show_below_main; } stats__cached_rcec_fresh++; } hash = 0; - for (i = 0; i < N_FRAMES; i++) { + for (i = 0; i < HG_(clo_history_backtrace_size); i++) { hash ^= thr->cached_rcec.frames[i]; hash = ROLW(hash, 19); } @@ -5044,11 +5067,12 @@ Bool libhb_event_map_lookup ( /*OUT*/ExeContext** resEC, tl_assert(ref_rcec->magic == RCEC_MAGIC); tl_assert(ref_szB >= 1); /* Count how many non-zero frames we have. */ - maxNFrames = min_UInt(N_FRAMES, VG_(clo_backtrace_size)); + maxNFrames = min_UInt(HG_(clo_history_backtrace_size), + VG_(clo_backtrace_size)); for (n = 0; n < maxNFrames; n++) { if (0 == ref_rcec->frames[n]) break; } - *resEC = VG_(make_ExeContext_from_StackTrace)(ref_rcec->frames, + *resEC = VG_(make_ExeContext_from_StackTrace)(&ref_rcec->frames[0], n); *resThr = Thr__from_ThrID(ref->acc.tsw.thrid); *resSzB = ref_szB; @@ -5072,17 +5096,17 @@ void libhb_event_map_access_history ( Addr a, SizeT szB, Access_t fn ) OldRef *ref = lru.next; SizeT ref_szB; Int n; - + while (ref != &mru) { ref_szB = ref->acc.tsw.szB; if (cmp_nonempty_intervals(a, szB, ref->ga, ref_szB) == 0) { RCEC* ref_rcec = ref->acc.rcec; - for (n = 0; n < N_FRAMES; n++) { + for (n = 0; n < HG_(clo_history_backtrace_size); n++) { if (0 == ref_rcec->frames[n]) { break; } } - (*fn)(ref_rcec->frames, n, + (*fn)(&ref_rcec->frames[0], n, Thr__from_ThrID(ref->acc.tsw.thrid), ref->ga, ref_szB, @@ -5101,13 +5125,14 @@ static void event_map_init ( void ) Word i; /* Context (RCEC) pool allocator */ - rcec_pool_allocator = VG_(newPA) ( - sizeof(RCEC), - 1000 /* RCECs per pool */, - HG_(zalloc), - "libhb.event_map_init.1 (RCEC pools)", - HG_(free) - ); + rcec_pool_allocator + = VG_(newPA) ( + sizeof(RCEC) + 2 * HG_(clo_history_backtrace_size) * sizeof(UWord), + 1000 /* RCECs per pool */, + HG_(zalloc), + "libhb.event_map_init.1 (RCEC pools)", + HG_(free) + ); /* Context table */ tl_assert(!contextTab); @@ -6839,25 +6864,20 @@ void libhb_shutdown ( Bool show_stats ) stats__ctxt_tab_qs, stats__ctxt_tab_cmps ); #if 0 - VG_(printf)("sizeof(AvlNode) = %lu\n", sizeof(AvlNode)); - VG_(printf)("sizeof(WordBag) = %lu\n", sizeof(WordBag)); - VG_(printf)("sizeof(MaybeWord) = %lu\n", sizeof(MaybeWord)); - VG_(printf)("sizeof(CacheLine) = %lu\n", sizeof(CacheLine)); - VG_(printf)("sizeof(LineZ) = %lu\n", sizeof(LineZ)); - VG_(printf)("sizeof(LineF) = %lu\n", sizeof(LineF)); - VG_(printf)("sizeof(SecMap) = %lu\n", sizeof(SecMap)); - VG_(printf)("sizeof(Cache) = %lu\n", sizeof(Cache)); - VG_(printf)("sizeof(SMCacheEnt) = %lu\n", sizeof(SMCacheEnt)); - VG_(printf)("sizeof(CountedSVal) = %lu\n", sizeof(CountedSVal)); - VG_(printf)("sizeof(VTS) = %lu\n", sizeof(VTS)); - VG_(printf)("sizeof(ScalarTS) = %lu\n", sizeof(ScalarTS)); - VG_(printf)("sizeof(VtsTE) = %lu\n", sizeof(VtsTE)); - VG_(printf)("sizeof(MSMInfo) = %lu\n", sizeof(MSMInfo)); - - VG_(printf)("sizeof(struct _XArray) = %lu\n", sizeof(struct _XArray)); - VG_(printf)("sizeof(struct _WordFM) = %lu\n", sizeof(struct _WordFM)); - VG_(printf)("sizeof(struct _Thr) = %lu\n", sizeof(struct _Thr)); - VG_(printf)("sizeof(struct _SO) = %lu\n", sizeof(struct _SO)); + VG_(printf)("sizeof(CacheLine) = %zu\n", sizeof(CacheLine)); + VG_(printf)("sizeof(LineZ) = %zu\n", sizeof(LineZ)); + VG_(printf)("sizeof(LineF) = %zu\n", sizeof(LineF)); + VG_(printf)("sizeof(SecMap) = %zu\n", sizeof(SecMap)); + VG_(printf)("sizeof(Cache) = %zu\n", sizeof(Cache)); + VG_(printf)("sizeof(SMCacheEnt) = %zu\n", sizeof(SMCacheEnt)); + VG_(printf)("sizeof(CountedSVal) = %zu\n", sizeof(CountedSVal)); + VG_(printf)("sizeof(VTS) = %zu\n", sizeof(VTS)); + VG_(printf)("sizeof(ScalarTS) = %zu\n", sizeof(ScalarTS)); + VG_(printf)("sizeof(VtsTE) = %zu\n", sizeof(VtsTE)); + + VG_(printf)("sizeof(struct _Thr) = %zu\n", sizeof(struct _Thr)); + VG_(printf)("sizeof(RCEC) = %zu\n", sizeof(RCEC)); + VG_(printf)("sizeof(struct _SO) = %zu\n", sizeof(struct _SO)); #endif VG_(printf)("%s","<<< END libhb stats >>>\n"); |
|
From: Philippe W. <phi...@sk...> - 2022-12-27 22:27:56
|
This commit implements in python a set of GDB commands corresponding to the
Valgrind gdbserver monitor commands.
Basically, the idea is that one GDB command is defined for each valgrind gdbserver
subcommand and will generate and send a monitor command to valgrind.
The python code is auto-loaded by GDB as soon as GDB observes that the valgrind
preload core shared lib is loaded (e.g. vgpreload_core-amd64-linux.so).
This automatic loading is done thanks to the .debug_gdb_scripts section
added in vg_preloaded.c file.
Sadly, the auto-load only happens once valgrind has started to execute the code of ld
that loads this vg_preload file.
I have tried 2 approaches to have the python code auto-loaded when attaching at startup
to valgrind:
* have valgrind gdbserver reporting first to GDB that the executable file is
the tool executable (with a .debug_gdb_scripts section) and then reporting
the real (guest) executable file.
The drawback of this approach is that it triggers a warning/question in GDB
according to the GDB setting 'set exec-file-mismatch'.
* have valgrind gdbserver pretending to be multiprocess enabled, and report
a fake process using the tool executable with a .debug_gdb_scripts section.
The drawback of this is that this always creates a second inferior in GDB,
which will be confusing.
Possibly, we might complete the below message :
==2984378== (action at startup) vgdb me ...
==2984378==
==2984378== TO DEBUG THIS PROCESS USING GDB: start GDB like this
==2984378== /path/to/gdb /home/philippe/valgrind/littleprogs/some_mem
==2984378== and then give GDB the following command
==2984378== target remote | /home/philippe/valgrind/git/improve/Inst/libexec/valgrind/../../bin/vgdb --pid=2984378
==2984378== --pid is optional if only one valgrind process is running
with:
==2984378== GDB valgrind python specific commands will be auto-loaded when execution begins.
==2984378== Alternatively, you might load it before with the GDB command:
==2984378== source /abs/path/to/valgrind/install/libexec/valgrind/valgrind-monitor.py
We might also have the python code loading producing a message such as:
GDB Valgrind specific command loaded.
Type "help valgrind" for more information.
The following GDB setting traces the monitor commands sent by a GDB valgrind
command to the valgrind gdbserver:
set debug valgrind-execute-monitor on
How to use the new GDB valgrind commands?
-----------------------------------------
The usage of the GDB front end commands is compatible with the
monitor command as accepted today by Valgrind.
For example, the memcheck monitor command "xb' has the following usage:
xb <addr> [<len>]
With some piece of code:
'char some_mem [5];'
xb can be used the following way:
(gdb) print &some_mem
(gdb) $2 = (char (*)[5]) 0x1ffefffe8b
(gdb) monitor xb 0x1ffefffe8b 5
ff ff ff ff ff
0x4A43040: 0x00 0x00 0x00 0x00 0x00
(gdb)
The same action can be done with the new GDB 'memcheck xb' command:
(gdb) memcheck xb 0x1ffefffe8b 5
ff ff ff ff ff
0x1FFEFFFE8B: 0x00 0x00 0x00 0x00 0x00
(gdb)
At this point, you might ask yourself: "what is the interest ?".
Using GDB valgrind commands provides several advantages compared to
the valgrind gdbserver monitor commands.
Evaluation of arguments by GDB:
-------------------------------
For relevant arguments, the GDB command will evaluate its arguments using
the usual GDB evaluation logic, for example, instead of printing/copying
the address and size of 'some_mem', the following will work:
(gdb) memcheck xb &some_mem sizeof(some_mem)
ff ff ff ff ff
0x1FFEFFFE8B: 0x00 0x00 0x00 0x00 0x00
(gdb)
or:
(gdb) p some_mem
$4 = "\000\000\000\000"
(gdb) memcheck xb &$4
ff ff ff ff ff
0x1FFEFFFE8B: 0x00 0x00 0x00 0x00 0x00
(gdb)
This is both easier to use interactively and easier to use in GDB scripts,
as you can directly use variable names in the GDB valgrind commands.
Command completion by GDB:
--------------------------
The usual command completion in GDB will work for the GDB valgrind commands.
For example, typing TAB after the letter 'l' in:
(gdb) valgrind v.info l
will show the 2 "valgrind v.info" subcommands:
last_error location
(gdb) valgrind v.info l
Note that as usual, GDB will recognise a command as soon as it is unambiguous.
Usual help and apropos support by GDB:
--------------------------------------
The Valgrind gdbserver provides an online help using:
(gdb) monitor help
However, this gives the help for all monitor commands, and is not searchable.
GDB provides a better help and documentation search.
For example, the following commands can be used to get various help
or search the GDB Valgrind command online documentation:
help valgrind
help memcheck
help helgrind
help callgrind
help massif
to get help about the general valgrind commands or the tool specific commands.
Examples of searching the online documentation:
apropos valgrind.*location
apropos -v validity
apropos -v leak
User can define aliases for the valgrind commands:
--------------------------------------------------
The following aliases are predefined:
v and vg for valgrind
mc for memcheck
hg for helgrind
cg for callgrind
ms for massif
So, the following will be equivalent:
(gdb) valgrind v.info location &some_mem
(gdb) v v.i lo &some_mem
(gdb) alias Vl = valgrind v.info location
(gdb) Vl &some_mem
Implementation should be complete.
What is still missing is updating the valgrind user manual and the NEWS file.
---
coregrind/Makefile.am | 2 +
coregrind/m_gdbserver/valgrind-monitor-def.py | 841 ++++++++++++++++++
coregrind/m_gdbserver/valgrind-monitor.py | 32 +
coregrind/m_main.c | 12 +
coregrind/vg_preloaded.c | 13 +
5 files changed, 900 insertions(+)
create mode 100644 coregrind/m_gdbserver/valgrind-monitor-def.py
create mode 100644 coregrind/m_gdbserver/valgrind-monitor.py
diff --git a/coregrind/Makefile.am b/coregrind/Makefile.am
index 151f5c2f0..dda0689dd 100644
--- a/coregrind/Makefile.am
+++ b/coregrind/Makefile.am
@@ -766,6 +766,8 @@ GDBSERVER_XML_FILES = \
# so as to make sure these get copied into the install tree
vglibdir = $(pkglibexecdir)
vglib_DATA = $(GDBSERVER_XML_FILES)
+vglib_DATA += m_gdbserver/valgrind-monitor.py
+vglib_DATA += m_gdbserver/valgrind-monitor-def.py
# so as to make sure these get copied into the tarball
EXTRA_DIST += $(GDBSERVER_XML_FILES)
diff --git a/coregrind/m_gdbserver/valgrind-monitor-def.py b/coregrind/m_gdbserver/valgrind-monitor-def.py
new file mode 100644
index 000000000..9855126d2
--- /dev/null
+++ b/coregrind/m_gdbserver/valgrind-monitor-def.py
@@ -0,0 +1,841 @@
+# This file is part of Valgrind, a dynamic binary instrumentation
+# framework.
+
+# Copyright (C) 2022-2022 Philippe Waroquiers
+
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of the
+# License, or (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, see <http://www.gnu.org/licenses/>.
+
+# The GNU General Public License is contained in the file COPYING.
+
+"""
+This file defines a series of gdb commands and subcommands to help interfacing
+gdb with the Valgrind gdbserver.
+
+!!! This only works with GDB version >= 9.1, as some command names contains
+a dot character only allowed from this version onwards.
+
+Type "help valgrind" to get help about the top of the command hierarchy.
+"""
+
+from typing import Callable
+from enum import Enum
+import re
+
+class _Debug_Valgrind_Execute_Monitor(gdb.Parameter):
+ """Set valgrind monitor command execution debugging.
+Usage: set debug valgrind-execute-monitor [on|off]"""
+ def __init__(self):
+ super().__init__("debug valgrind-execute-monitor",
+ gdb.COMMAND_MAINTENANCE,
+ gdb.PARAM_BOOLEAN)
+
+Debug_Valgrind_Execute_Monitor = _Debug_Valgrind_Execute_Monitor()
+
+def gdb_execute_monitor(monitor_command : str, from_tty : bool) -> None:
+ """Execute the given monitor command."""
+ cmd = "monitor " + monitor_command
+ if Debug_Valgrind_Execute_Monitor.value:
+ print('[valgrind-execute-monitor] sending "' + cmd + '" to valgrind')
+ try:
+ gdb.execute (cmd, from_tty)
+ except Exception as inst:
+ if monitor_command == "v.kill" and str(inst).find('Remote connection closed') >= 0:
+ print('Remote connection closed')
+ else:
+ print('Error sending "' + monitor_command + '" to valgrind: '+ str(inst))
+
+class Valgrind_Command(gdb.Command):
+ """Parent class for all Valgrind commands."""
+ def invoke(self, arg_str : str, from_tty : bool) -> None:
+ """Generic Valgrind Command invoke method to override if needed."""
+ # print("generic invoke", self.mname)
+ if arg_str:
+ gdb_execute_monitor (self.mname + " " + arg_str, from_tty)
+ else:
+ gdb_execute_monitor (self.mname, from_tty)
+
+def Vinit(toolname : str,
+ mname : str,
+ command_class : Enum,
+ completer_class : Enum,
+ prefix : bool) -> Callable[[Valgrind_Command],
+ Valgrind_Command]:
+ """Class decorator to initialise and register a Valgrind_Command class.
+MNAME is the Valgrind monitor name string for this command.
+The gdb command is the concatenation of TOOLNAME and MNAME.
+TOOLNAME is valgrind for the general valgrind commands."""
+ def instantiate(GDB_Command : Valgrind_Command) -> Valgrind_Command:
+ def adhoc_init (self):
+ # print("initializing", GDB_Command)
+ if completer_class:
+ super(GDB_Command, self).__init__(name = toolname + " " + mname,
+ command_class = command_class,
+ completer_class = completer_class,
+ prefix = prefix)
+ else:
+ super(GDB_Command, self).__init__(name = toolname + " " + mname,
+ command_class = command_class,
+ prefix = prefix)
+ self.toolname=toolname
+ self.mname=mname
+ GDB_Command.__init__ = adhoc_init
+ GDB_Command() # register the command
+ return GDB_Command
+ return instantiate
+
+def build_name(command : Valgrind_Command) -> str:
+ """Returns the GDB full name for the given COMMAND."""
+ if command.mname:
+ return command.toolname + ' ' + command.mname
+ else:
+ return command.toolname
+
+def build_help(command : Valgrind_Command) -> str:
+ """Returns a string to ask help for the given COMMAND."""
+ return "help " + build_name(command)
+
+def build_type_help(command) -> str:
+ """Returns a string giving what to type to get helps about the given command"""
+ return 'Type "' + build_help(command) + '"'
+
+class Valgrind_Prefix_Command(Valgrind_Command):
+ """Parent class for all Valgrind prefix commands."""
+ def invoke(self, arg_str : str, from_tty : bool) -> None:
+ """Generic Valgrind prefix Command invoke method to override if needed."""
+ # print("generic prefix invoke", self.mname)
+ if arg_str:
+ # If it is not a recognised sub-command, raise an error.
+ raise gdb.GdbError(('Undefined ' + build_name (self)
+ + ' command: "' + arg_str + '".\n'
+ + build_type_help(self)))
+ else:
+ gdb.execute (build_help(self), from_tty)
+
+class Valgrind_Prefix_Exec_Command(Valgrind_Prefix_Command):
+ """Parent class for all Valgrind prefix commands that can be executed without subcommands."""
+ def invoke(self, arg_str : str, from_tty : bool) -> None:
+ """Invoke for a prefix command that can be executed."""
+ if arg_str:
+ super().invoke(arg_str, from_tty)
+ else:
+ gdb_execute_monitor (self.mname, from_tty)
+
+def eval_execute(command : Valgrind_Command,
+ arg_str : str,
+ arg_opt : bool, arg_descr : str, format_fn,
+ from_tty : bool) -> None:
+ """Evaluates ARG_STR, format the result with FORMAT_FN and
+executes the monitor command COMMAND.mname + FORMAT_FN(evaluated ARG_STR).
+ARG_OPT True indicates the argument is optional.
+ARG_DESCR is used in error messages."""
+ if arg_str:
+ eval_arg_str = gdb.parse_and_eval (arg_str)
+ gdb_execute_monitor (command.mname + " " + format_fn(eval_arg_str), from_tty)
+ elif arg_opt:
+ gdb_execute_monitor (command.mname, from_tty)
+ else:
+ raise gdb.GdbError(('Argument "' + arg_descr + '" required.\n'
+ + build_type_help(command)))
+
+def eval_execute_2(command : Valgrind_Command,
+ arg_str : str,
+ arg1_opt : bool, arg1_descr : str, format_fn1,
+ arg2_opt : bool, arg2_descr : str, format_fn2,
+ from_tty : bool) -> None:
+ """Like eval_execute but allowing 2 arguments to be extracted from ARG_STR).
+The second argument starts after the first space in ARG_STR."""
+ if arg1_opt and not arg2_opt:
+ raise gdb.GdbError(('Cannot have arg1_opt True and arg2_opt False'
+ + ' in definition of '
+ + build_name(command)))
+ if arg_str:
+ arg_str_v = arg_str.split(' ', 1);
+ eval_arg1_str = gdb.parse_and_eval (arg_str_v[0])
+ if len(arg_str_v) <= 1:
+ if arg2_opt:
+ gdb_execute_monitor (command.mname + " " + format_fn1(eval_arg1_str), from_tty)
+ else:
+ raise gdb.GdbError(('Argument 2 "' + arg2_descr + '" required.\n'
+ + build_type_help(command)))
+ else:
+ eval_arg2_str = gdb.parse_and_eval (arg_str_v[1])
+ gdb_execute_monitor (command.mname
+ + " " + format_fn1(eval_arg1_str)
+ + " " + format_fn1(eval_arg2_str),
+ from_tty)
+ elif arg1_opt and arg2_opt:
+ gdb_execute_monitor (command.mname, from_tty)
+ else:
+ raise gdb.GdbError(('Argument 1 "' + arg1_descr + '" required.\n'
+ + ('' if arg2_opt
+ else 'Argument 2 "' + arg2_descr + '" required.\n')
+ + build_type_help(command)))
+
+def def_alias(alias : str, command_name : str) -> None:
+ """Defines an alias ALIAS = COMMAND_NAME.
+Traps the error if ALIAS is already defined (so as to be able to source
+this file again)."""
+ d = "alias " + alias + ' = ' + command_name
+ try:
+ gdb.execute (d)
+ except Exception as inst:
+ print('"' + d + '" : '+ str(inst))
+
+class Valgrind_ADDR(Valgrind_Command):
+ """Common class for Valgrind commands taking ADDR arg."""
+ def invoke(self, arg_str : str, from_tty : bool) -> None:
+ eval_execute(self, arg_str,
+ False, "ADDR (address expression)", hex,
+ from_tty)
+
+class Valgrind_ADDR_opt(Valgrind_Command):
+ """Common class for Valgrind commands taking [ADDR] arg."""
+ def invoke(self, arg_str : str, from_tty : bool) -> None:
+ eval_execute(self, arg_str,
+ True, "ADDR (address expression)", hex,
+ from_tty)
+
+class Valgrind_ADDR_LEN_opt(Valgrind_Command):
+ """Common class for Valgrind commands taking ADDR and [LEN] args.
+For compatibility reason with the Valgrind gdbserver monitor command,
+we detect and accept usages such as 0x1234ABCD[10]."""
+ def invoke(self, arg_str : str, from_tty : bool) -> None:
+ if re.fullmatch("^0x[0123456789ABCDEFabcdef]+\[[^\[\]]+\]$", arg_str):
+ arg_str = arg_str.replace("[", " ")
+ arg_str = arg_str.replace("]", " ")
+ eval_execute_2(self, arg_str,
+ False, "ADDR (address expression)", hex,
+ True, "LEN (integer length expression)", str,
+ from_tty)
+
+############# The rest of this file defines first the valgrind general commands
+# then the tool specific commands.
+# The commands are defined in the same order as produced by
+# (gdb) monitor help debug
+
+############# valgrind general commands.
+
+###### Top of the hierarchy of the valgrind general commands.
+@Vinit("valgrind", "", gdb.COMMAND_SUPPORT, gdb.COMPLETE_COMMAND, True)
+class Valgrind_Monitor_Command(Valgrind_Prefix_Command):
+ """Front end GDB command for Valgrind gdbserver monitor commands.
+Usage: valgrind VALGRIND_MONITOR_COMMAND [ARG...]
+VALGRIND_MONITOR_COMMAND is a valgrind subcommand, matching a
+gdbserver Valgrind monitor command.
+ARG... are optional arguments. They depend on the VALGRIND_MONITOR_COMMAND.)
+
+Type "help memcheck" for memcheck specific commands.
+Type "help helgrind" for helgrind specific commands.
+Type "help callgrind" for callgrind specific commands.
+Type "help massif" for massif specific commands.
+"""
+
+def_alias("vg", "valgrind")
+def_alias("v", "valgrind") # To avoid 'v' reported as ambiguous for 'vg' and 'valgrind' !
+
+@Vinit("valgrind", "help", gdb.COMMAND_SUPPORT, gdb.COMPLETE_COMMAND, True)
+class Valgrind_Help_Command(Valgrind_Prefix_Exec_Command):
+ """Ask Valgrind gdbserver to output the help for its monitor commands.
+Usage: valgrind help
+This shows the help string reported by the Valgrind gdbserver.
+Type "help valgrind" to get help about the GDB front end commands interfacing
+to the Valgrind gdbserver monitor commands.
+"""
+ def invoke(self, arg_str : str, from_tty : bool) -> None:
+ """Invoke for a prefix command that can be executed."""
+ if arg_str:
+ super().invoke(arg_str, from_tty)
+ else:
+ gdb_execute_monitor (self.mname, from_tty)
+
+@Vinit("valgrind", "help debug", gdb.COMMAND_SUPPORT, gdb.COMPLETE_NONE, False)
+class Valgrind_Help_Debug_Command(Valgrind_Command):
+ """Ask Valgrind gdbserver to output the help for its monitor commands (including debugging commands).
+Usage: valgrind help debug
+This shows the help string reported by the Valgrind gdbserver.
+Type "help valgrind" to get help about the GDB front end commands interfacing
+to the Valgrind gdbserver monitor commands.
+"""
+
+@Vinit("valgrind", "v.wait", gdb.COMMAND_OBSCURE, gdb.COMPLETE_EXPRESSION, False)
+class Valgrind_Wait_Command(Valgrind_Command):
+ """Have Valgrind gdbserver sleeping for MS (default 0) milliseconds.
+Usage: valgrind v.wait [MS]
+MS is an integer expression evaluated by GDB.
+"""
+ def invoke(self, arg_str : str, from_tty: bool) -> None:
+ eval_execute(self, arg_str,
+ True, "MS (integer expression in milliseconds)", str,
+ from_tty)
+
+@Vinit("valgrind", "v.info", gdb.COMMAND_STATUS, gdb.COMPLETE_COMMAND, True)
+class Valgrind_Info_Command(Valgrind_Prefix_Command):
+ """Get various information about Valgrind gdbserver.
+Usage: valgrind v.info WHAT [ARG...]
+WHAT is the v.info subcommand, specifying the type of information requested.
+ARG are optional arguments, depending on the WHAT subcommand.
+"""
+
+@Vinit("valgrind", "v.info all_errors", gdb.COMMAND_STATUS, gdb.COMPLETE_NONE, False)
+class Valgrind_Info_All_Errors_Command(Valgrind_Command):
+ """Show all errors found so far by Valgrind.
+Usage: valgrind v.info all_errors
+"""
+
+@Vinit("valgrind", "v.info last_error", gdb.COMMAND_STATUS, gdb.COMPLETE_NONE, False)
+class Valgrind_Info_Last_Error_Command(Valgrind_Command):
+ """Show last error found by Valgrind.
+Usage: valgrind v.info last_error
+"""
+
+@Vinit("valgrind", "v.info location", gdb.COMMAND_DATA, gdb.COMPLETE_EXPRESSION, False)
+class Valgrind_Info_Location_Command(Valgrind_ADDR):
+ """Show information known by Valgrind about location ADDR.
+Usage: valgrind v.info location ADDR
+ADDR is an address expression evaluated by GDB.
+"""
+
+@Vinit("valgrind", "v.info n_errs_found", gdb.COMMAND_STATUS, gdb.COMPLETE_NONE, False)
+class Valgrind_Info_N_Errs_Found_Command(Valgrind_Command):
+ """Show the nr of errors found so far by Valgrind and the given MSG.
+Usage: valgrind v.info n_errs_found [MSG]
+"""
+
+@Vinit("valgrind", "v.info open_fds", gdb.COMMAND_DATA, gdb.COMPLETE_NONE, False)
+class Valgrind_Info_Open_Fds_Command(Valgrind_Command):
+ """Show open file descriptors tracked by Valgrind (only if --track-fds=yes).
+Usage: valgrind v.info open_fds
+"""
+
+@Vinit("valgrind", "v.kill", gdb.COMMAND_RUNNING, gdb.COMPLETE_NONE, False)
+class Valgrind_Kill_Command(Valgrind_Command):
+ """Instruct valgrind gdbserver to kill the valgrind process.
+Usage: valgrind v.kill
+"""
+
+@Vinit("valgrind", "v.clo", gdb.COMMAND_RUNNING, gdb.COMPLETE_NONE, False)
+class Valgrind_Clo_Command(Valgrind_Command):
+ """Change one or more Valgrind dynamic command line options.
+Usage: valgrind v.clo [VALGRIND_OPTION]...
+VALGRIND_OPTION is the command line option to change.
+Example: (gdb) valgrind v.clo --stats=yes --show-below-main=yes
+
+Without VALGRIND_OPTION, shows the dynamically changeable options.
+"""
+
+@Vinit("valgrind", "v.set", gdb.COMMAND_STATUS, gdb.COMPLETE_COMMAND, True)
+class Valgrind_Set_Command(Valgrind_Prefix_Command):
+ """Modify various setting of Valgrind gdbserver.
+Usage: valgrind v.set WHAT [ARG]...
+WHAT is the v.set subcommand, specifying the setting to change.
+ARG are optional arguments, depending on the WHAT subcommand.
+"""
+
+@Vinit("valgrind", "v.set gdb_output", gdb.COMMAND_STATUS, gdb.COMPLETE_NONE, False)
+class Valgrind_Set_Gdb_Output_Command(Valgrind_Command):
+ """Set Valgrind output to gdb.
+Usage: valgrind v.set gdb_output
+"""
+
+@Vinit("valgrind", "v.set log_output", gdb.COMMAND_STATUS, gdb.COMPLETE_NONE, False)
+class Valgrind_Set_Log_Output_Command(Valgrind_Command):
+ """Set Valgrind output to Valgrind log.
+Usage: valgrind v.set log_output
+"""
+
+@Vinit("valgrind", "v.set mixed_output", gdb.COMMAND_STATUS, gdb.COMPLETE_NONE, False)
+class Valgrind_Set_Mixed_Output_Command(Valgrind_Command):
+ """Set Valgrind output to Valgrind log, interactive output to gdb.
+Usage: valgrind v.set mixed_output
+"""
+
+@Vinit("valgrind", "v.set merge-recursive-frames", gdb.COMMAND_STATUS, gdb.COMPLETE_EXPRESSION, False)
+class Valgrind_Set_Merge_Recursive_Frames_Command(Valgrind_Command):
+ """Set the number of frames for recursive calls merging in Valgrind stacktraces.
+Usage: valgrind v.set merge-recursive-frames NUM
+NUM is an integer expression evaluated by GDB.
+"""
+ def invoke(self, arg_str : str, from_tty : bool) -> None:
+ eval_execute(self, arg_str,
+ False, "NUM (number of frames for recursive calls merging)",
+ str,
+ from_tty)
+
+@Vinit("valgrind", "v.set vgdb-error", gdb.COMMAND_RUNNING, gdb.COMPLETE_EXPRESSION, False)
+class Valgrind_Set_Vgdb_Error_Command(Valgrind_Command):
+ """Set the number of errors at which Valgrind gdbserver gives control to gdb.
+Usage: valgrind v.set vgdb-error NUM
+NUM is an integer expression evaluated by GDB.
+"""
+ def invoke(self, arg_str : str, from_tty : bool) -> None:
+ eval_execute(self, arg_str,
+ False, "NUM (number of errors)",
+ str,
+ from_tty)
+
+@Vinit("valgrind", "v.do", gdb.COMMAND_MAINTENANCE, gdb.COMPLETE_COMMAND, True)
+class Valgrind_Do_Command(Valgrind_Prefix_Command):
+ """Ask Valgrind gdbserver to do an internal/maintenance action.
+Usage: valgrind v.do WHAT
+WHAT is the valgrind v.do subcommand, specifying the type of action requested.
+"""
+
+@Vinit("valgrind", "v.do expensive_sanity_check_general", gdb.COMMAND_MAINTENANCE, gdb.COMPLETE_NONE, False)
+class Valgrind_Do_Expensive_Sanity_Check_General_Command(Valgrind_Command):
+ """Do an expensive Valgrind sanity check now.
+Usage: valgrind v.do expensive_sanity_check_general
+"""
+
+@Vinit("valgrind", "v.info gdbserver_status", gdb.COMMAND_MAINTENANCE, gdb.COMPLETE_NONE, False)
+class Valgrind_Info_Gdbserver_Status_Command(Valgrind_Command):
+ """Show gdbserver status.
+Usage: valgrind v.info gdbserver_status
+"""
+
+@Vinit("valgrind", "v.info memory", gdb.COMMAND_MAINTENANCE, gdb.COMPLETE_COMMAND, True)
+class Valgrind_Info_Memory_Status_Command(Valgrind_Prefix_Exec_Command):
+ """Show valgrind heap memory stats.
+Usage: valgrind v.info memory
+"""
+
+@Vinit("valgrind", "v.info memory aspacemgr", gdb.COMMAND_MAINTENANCE, gdb.COMPLETE_NONE, False)
+class Valgrind_Info_Memory_Aspacemgr_Command(Valgrind_Command):
+ """Show Valgrind heap memory stats and show Valgrind segments on log output.
+Usage: valgrind v.info memory aspacemgr
+"""
+
+@Vinit("valgrind", "v.info exectxt", gdb.COMMAND_MAINTENANCE, gdb.COMPLETE_NONE, False)
+class Valgrind_Info_Exectxt_Command(Valgrind_Command):
+ """Show stacktraces and stats of all execontexts record by Valgrind.
+Usage: valgrind v.info exectxt
+"""
+
+@Vinit("valgrind", "v.info scheduler", gdb.COMMAND_MAINTENANCE, gdb.COMPLETE_NONE, False)
+class Valgrind_Info_Scheduler_Command(Valgrind_Command):
+ """Show Valgrind thread state and stacktrace.
+Usage: valgrind v.info scheduler
+"""
+
+@Vinit("valgrind", "v.info stats", gdb.COMMAND_MAINTENANCE, gdb.COMPLETE_NONE, False)
+class Valgrind_Info_Stats_Command(Valgrind_Command):
+ """Show various Valgrind and tool stats.
+Usage: valgrind v.info stats
+"""
+
+@Vinit("valgrind", "v.info unwind", gdb.COMMAND_MAINTENANCE, gdb.COMPLETE_EXPRESSION, False)
+class Valgrind_Info_Unwind_Command(Valgrind_ADDR_LEN_opt):
+ """Show unwind debug info for ADDR .. ADDR+LEN.
+Usage: valgrind v.info unwind ADDR [LEN]
+ADDR is an address expression evaluated by GDB.
+LEN is an integer expression evaluated by GDB.
+"""
+
+@Vinit("valgrind", "v.set debuglog", gdb.COMMAND_MAINTENANCE, gdb.COMPLETE_EXPRESSION, False)
+class Valgrind_Set_Debuglog_Command(Valgrind_Command):
+ """Set Valgrind debug log level to LEVEL.
+Usage: valgrind v.set LEVEL
+LEVEL is an integer expression evaluated by GDB.
+"""
+ def invoke(self, arg_str : str, from_tty : bool) -> None:
+ eval_execute(self, arg_str,
+ False, "LEVEL (valgrind debug log level)",
+ str,
+ from_tty)
+@Vinit("valgrind", "v.set hostvisibility", gdb.COMMAND_MAINTENANCE, gdb.COMPLETE_COMMAND, True)
+class Valgrind_Set_Hostvisibility_Command(Valgrind_Prefix_Exec_Command):
+ """Set visibility of the internal Valgrind 'host' state.
+Without arguments, enables the host visibility.
+Host visibility allows to examine with GDB the internal status and memory
+of Valgrind.
+Usage: valgrind v.set hostvisibility
+"""
+
+@Vinit("valgrind", "v.set hostvisibility yes", gdb.COMMAND_MAINTENANCE, gdb.COMPLETE_NONE, False)
+class Valgrind_Set_Hostvisibility_Yes_Command(Valgrind_Command):
+ """Enable visibility of the internal Valgrind 'host' state.
+Usage: valgrind v.set hostvisibility yes
+See "help v.set hostvisibility".
+"""
+
+@Vinit("valgrind", "v.set hostvisibility no", gdb.COMMAND_MAINTENANCE, gdb.COMPLETE_NONE, False)
+class Valgrind_Set_Hostvisibility_No_Command(Valgrind_Command):
+ """Disable visibility of the internal Valgrind 'host' state.
+Usage: valgrind v.set hostvisibility no
+See "help v.set hostvisibility".
+"""
+
+def base2(value : int) -> str:
+ """Image of value in base 2 prefixed with 0b."""
+ "0b" + "{0:b}".format(value)
+
+@Vinit("valgrind", "v.translate", gdb.COMMAND_MAINTENANCE, gdb.COMPLETE_EXPRESSION, False)
+class Valgrind_Translate_Command(Valgrind_Command):
+ """Show the translation of instructions at ADDR with TRACEFLAGS.
+Usage: valgrind v.translate ADDR [TRACEFLAG]
+For TRACEFLAG values, type in shell "valgrind --help-debug".
+An additional flag 0b100000000 allows one to show gdbserver instrumentation.
+ADDR is an address expression evaluated by GDB.
+TRACEFLAG is an integer expression (used as a bitmask) evaluated by GDB.
+"""
+ def invoke(self, arg_str : str, from_tty : bool) -> None:
+ eval_execute_2(self, arg_str,
+ False, "ADDR (address expression)", hex,
+ True, "TRACEFLAGS (bit mask expression)", base2,
+ from_tty)
+
+############# memcheck commands.
+
+###### Top of the hierarchy of the memcheck commands.
+@Vinit("memcheck", "", gdb.COMMAND_SUPPORT, gdb.COMPLETE_COMMAND, True)
+class Memcheck_Command(Valgrind_Prefix_Command):
+ """Front end GDB command for Valgrind memcheck gdbserver monitor commands.
+Usage: memcheck MEMCHECK_MONITOR_COMMAND [ARG...]
+MEMCHECK_MONITOR_COMMAND is a memcheck subcommand, matching
+a gdbserver Valgrind memcheck monitor command.
+ARG... are optional arguments. They depend on the MEMCHECK_MONITOR_COMMAND.
+"""
+
+def_alias("mc", "memcheck")
+
+@Vinit("memcheck", "xtmemory", gdb.COMMAND_DATA, gdb.COMPLETE_FILENAME, False)
+class Memcheck_Xtmemory_Command(Valgrind_Command):
+ """Dump xtree memory profile in FILENAME (default xtmemory.kcg.%p.%n).
+Usage: memcheck xtmemory [FILENAME]
+
+Example: (gdb) memcheck xtmemory my_program_xtree.kcg
+"""
+
+@Vinit("memcheck", "xb", gdb.COMMAND_DATA, gdb.COMPLETE_EXPRESSION, False)
+class Memcheck_Xb_Command(Valgrind_ADDR_LEN_opt):
+ """Print validity bits for LEN (default 1) bytes at ADDR.
+ bit values 0 = valid, 1 = invalid, __ = unaddressable byte
+Prints the bytes values below the corresponding validity bits
+in a layout similar to the gdb command 'x /LENxb ADDR
+Usage: memcheck xb ADDR [LEN]
+ADDR is an address expression evaluated by GDB.
+LEN is an integer expression evaluated by GDB.
+
+Example: (gdb) memcheck xb &p sizeof(p)
+"""
+
+@Vinit("memcheck", "get_vbits", gdb.COMMAND_DATA, gdb.COMPLETE_EXPRESSION, False)
+class Memcheck_Get_Vbits_Command(Valgrind_ADDR_LEN_opt):
+ """Print validity bits for LEN (default 1) bytes at ADDR.
+ bit values 0 = valid, 1 = invalid, __ = unaddressable byte
+Usage: memcheck get_vbits ADDR [LEN]
+ADDR is an address expression evaluated by GDB.
+LEN is an integer expression evaluated by GDB.
+
+Example: (gdb) memcheck get_vbits &p sizeof(p)
+
+Note: the command 'memcheck xb ADDR [LEN]' prints the value
+and validity bits of ADDR [LEN] bytes in an easier to read format.
+"""
+
+@Vinit("memcheck", "make_memory", gdb.COMMAND_DATA, gdb.COMPLETE_COMMAND, True)
+class Memcheck_Make_Memory_Command(Valgrind_Prefix_Command):
+ """Prefix command to change memory accessibility."""
+
+@Vinit("memcheck", "make_memory noaccess", gdb.COMMAND_DATA, gdb.COMPLETE_EXPRESSION, False)
+class Memcheck_Make_Memory_Noaccess_Command(Valgrind_ADDR_LEN_opt):
+ """Mark LEN (default 1) bytes at ADDR as noaccess.
+Usage: memcheck make_memory noaccess ADDR [LEN]
+ADDR is an address expression evaluated by GDB.
+LEN is an integer expression evaluated by GDB.
+
+Example: (gdb) memcheck make_memory noaccess &p sizeof(p)
+"""
+
+@Vinit("memcheck", "make_memory undefined", gdb.COMMAND_DATA, gdb.COMPLETE_EXPRESSION, False)
+class Memcheck_Make_Memory_Undefined_Command(Valgrind_ADDR_LEN_opt):
+ """Mark LEN (default 1) bytes at ADDR as undefined.
+Usage: memcheck make_memory undefined ADDR [LEN]
+ADDR is an address expression evaluated by GDB.
+LEN is an integer expression evaluated by GDB.
+
+Example: (gdb) memcheck make_memory undefined &p sizeof(p)
+"""
+
+@Vinit("memcheck", "make_memory defined", gdb.COMMAND_DATA, gdb.COMPLETE_EXPRESSION, False)
+class Memcheck_Make_Memory_Defined_Command(Valgrind_ADDR_LEN_opt):
+ """Mark LEN (default 1) bytes at ADDR as defined.
+Usage: memcheck make_memory defined ADDR [LEN]
+ADDR is an address expression evaluated by GDB.
+LEN is an integer expression evaluated by GDB.
+
+Example: (gdb) memcheck make_memory defined &p sizeof(p)
+"""
+
+@Vinit("memcheck", "make_memory Definedifaddressable", gdb.COMMAND_DATA, gdb.COMPLETE_EXPRESSION, False)
+class Memcheck_Make_Memory_Definedifaddressable_Command(Valgrind_ADDR_LEN_opt):
+ """Mark LEN (default 1) bytes at ADDR as Definedifaddressable.
+Usage: memcheck make_memory Definedifaddressable ADDR [LEN]
+ADDR is an address expression evaluated by GDB.
+LEN is an integer expression evaluated by GDB.
+
+Example: (gdb) memcheck make_memory Definedifaddressable &p sizeof(p)
+"""
+
+@Vinit("memcheck", "check_memory", gdb.COMMAND_DATA, gdb.COMPLETE_COMMAND, True)
+class Memcheck_Check_Memory_Command(Valgrind_Prefix_Command):
+ """Command to check memory accessibility."""
+
+@Vinit("memcheck", "check_memory addressable", gdb.COMMAND_DATA, gdb.COMPLETE_EXPRESSION, False)
+class Memcheck_Check_Memory_Addressable_Command(Valgrind_ADDR_LEN_opt):
+ """Check that LEN (default 1) bytes at ADDR are addressable.
+Usage: memcheck check_memory addressable ADDR [LEN]
+ADDR is an address expression evaluated by GDB.
+LEN is an integer expression evaluated by GDB.
+
+Example: (gdb) memcheck check_memory addressable &p sizeof(p)
+"""
+
+@Vinit("memcheck", "check_memory defined", gdb.COMMAND_DATA, gdb.COMPLETE_EXPRESSION, False)
+class Memcheck_Check_Memory_Defined_Command(Valgrind_ADDR_LEN_opt):
+ """Check that LEN (default 1) bytes at ADDR are defined.
+Usage: memcheck check_memory defined ADDR [LEN]
+ADDR is an address expression evaluated by GDB.
+LEN is an integer expression evaluated by GDB.
+
+Example: (gdb) memcheck check_memory defined &p sizeof(p)
+"""
+
+@Vinit("memcheck", "leak_check", gdb.COMMAND_DATA, gdb.COMPLETE_NONE, False)
+class Memcheck_Leak_Check_Command(Valgrind_Command):
+ """Execute a memcheck leak search.
+Usage: leak_check [full*|summary|xtleak]
+ [kinds KIND1,KIND2,...|reachable|possibleleak*|definiteleak]
+ [heuristics HEUR1,HEUR2,...]
+ [increased*|changed|any]
+ [unlimited*|limited MAX_LOSS_RECORDS_OUTPUT]
+ * = defaults
+
+full: outputs stacktraces of all leaks followed by a summary.
+summary: outputs only the leak summary.
+xtleak: produce an xtree full leak result in xtleak.kcg.%p.%n
+
+KIND indicates which kind of leaks to report, and is one of:
+ definite indirect possible reachable all none
+
+HEUR indicates an heuristic to activate when doing leak search and is one of:
+ stdstring length64 newarray multipleinheritance all none*
+
+increased: only outputs the leak loss records with an increase since last leak search.
+changed: also outputs the leak loss records with a decrease.
+any: also outputs the leak loss records that did not change.
+
+unlimited: outputs all matching loss records.
+limited: outputs only the first matching MAX_LOSS_RECORDS_OUTPUT.
+
+Examples: (gdb) memcheck leak_check
+ (gdb) memcheck leak_check summary any
+ (gdb) memcheck leak_check full kinds indirect,possible
+ (gdb) memcheck leak_check full reachable any limited 100
+"""
+
+ def complete(self, text, word):
+ # print('/' + text + ' ' + word + '/\n')
+ leak_check_mode = ["full", "summary", "xtleak"]
+ leak_kind = ["kinds", "reachable", "possibleleak", "definiteleak"]
+ leak_heuristic = ["heuristics"]
+ leak_check_delta_mode = ["increased", "changed", "any"]
+ leak_check_loss_record_limit = ["unlimited", "limited"]
+ kwd_lists = [leak_check_mode, leak_kind, leak_heuristic, leak_check_delta_mode,
+ leak_check_loss_record_limit]
+ # Build the list of still allowed keywords.
+ # We append all the keywords of a list unless we find already one
+ # existing word in text that starts with the first letter of a keyword
+ # of the list. Checking the first letter is ok (currently!)
+ # as all keywords of leak_check monitor command starts with a different letter.
+ keywords = []
+ command_words = text.split()
+ # command_words.pop(0) # we do not match with the command itself.
+ for kwd_list in kwd_lists:
+ list_ok = True
+ # print('list:/' + str(kwd_list) + '/')
+ for kwd in kwd_list:
+ for command_word in command_words:
+ # print('word:/' + command_word + '/' + kwd)
+ if kwd[0] == command_word[0]:
+ # print("setting to false")
+ list_ok = False
+ if kwd.startswith(word) and word != kwd and kwd not in command_words:
+ # print('/' + word + '/' + kwd + '/')
+ keywords.append(kwd)
+ if list_ok:
+ for kwd in kwd_list:
+ keywords.append(kwd)
+ result = []
+ for keyword in keywords:
+ if keyword.startswith(word):
+ result.append(keyword)
+ return result
+
+@Vinit("memcheck", "block_list", gdb.COMMAND_DATA, gdb.COMPLETE_NONE, False)
+class Memcheck_Block_List_Command(Valgrind_Command):
+ """Show the list of blocks for a leak search loss record.
+Usage: memcheck block_list LOSS_RECORD_NR|LOSS_RECORD_NR_FROM..LOSS_RECORD_NR_TO
+ unlimited*|limited MAX_BLOCKS
+ [heuristics HEUR1,HEUR2,...]
+ * = defaults
+
+After a leak search, use block_list to show the list of blocks matching a loss
+record or matching a range of loss records.
+
+unlimited: outputs all blocks matching the selected loss records.
+limited: outputs only the first matching MAX_BLOCKS.
+
+Use heuristics to only output the blocks found via one of the given heuristics,
+where HEUR is one of:
+ stdstring length64 newarray multipleinheritance all none*
+ """
+
+@Vinit("memcheck", "who_points_at", gdb.COMMAND_DATA, gdb.COMPLETE_EXPRESSION, False)
+class Memcheck_Who_Points_At_Command(Valgrind_ADDR_LEN_opt):
+ """Show places pointing inside LEN (default 1) bytes at ADDR.
+Usage: memcheck who_points_at ADDR [MEN]
+With LEN 1, only shows "start pointers" pointing exactly to ADDR.
+With LEN > 1, will also show "interior pointers"
+ADDR is an address expression evaluated by GDB.
+LEN is an integer expression evaluated by GDB.
+"""
+
+############# helgrind commands.
+
+###### Top of the hierarchy of the helgrind commands.
+@Vinit("helgrind", "", gdb.COMMAND_SUPPORT, gdb.COMPLETE_COMMAND, True)
+class Helgrind_Command(Valgrind_Prefix_Command):
+ """Front end GDB command for Valgrind helgrind gdbserver monitor commands.
+Usage: helgrind HELGRIND_MONITOR_COMMAND [ARG...]
+HELGRIND_MONITOR_COMMAND is a helgrind subcommand, matching
+a gdbserver Valgrind helgrind monitor command.
+ARG... are optional arguments. They depend on the HELGRIND_MONITOR_COMMAND.
+"""
+
+def_alias("hg", "helgrind")
+
+@Vinit("helgrind", "info", gdb.COMMAND_STATUS, gdb.COMPLETE_COMMAND, True)
+class Helgrind_Info_Command(Valgrind_Prefix_Command):
+ """Get various information about helgrind tool status.
+Usage: helgrind info WHAT
+WHAT is the helgrind info subcommand, specifying the type of information requested.
+"""
+
+@Vinit("helgrind", "info locks", gdb.COMMAND_DATA, gdb.COMPLETE_EXPRESSION, False)
+class Helgrind_Info_Locks_Command(Valgrind_ADDR_opt):
+ """Show the status of one or all locks recorded by helgrind.
+Usage: helgrind info locks [ADDR]
+ADDR is an address expression evaluated by GDB.
+When ADDR is provided, shows the status of the lock located at ADDR,
+otherwise shows the status of all locks.
+"""
+
+@Vinit("helgrind", "accesshistory", gdb.COMMAND_DATA, gdb.COMPLETE_EXPRESSION, False)
+class Helgrind_Accesshistory_Command(Valgrind_ADDR_LEN_opt):
+ """Show access history recorded for LEN (default 1) bytes at ADDR.
+Usage: helgrind accesshistory ADDR [LEN]
+ADDR is an address expression evaluated by GDB.
+LEN is an integer expression evaluated by GDB.
+
+Example: (gdb) helgrind accesshistory &p sizeof(p)
+"""
+
+@Vinit("helgrind", "xtmemory", gdb.COMMAND_DATA, gdb.COMPLETE_FILENAME, False)
+class Helgrind_Xtmemory_Command(Valgrind_Command):
+ """Dump xtree memory profile in FILENAME (default xtmemory.kcg.%p.%n).
+Usage: helgrind xtmemory [FILENAME]
+
+Example: (gdb) helgrind xtmemory my_program_xtree.kcg
+"""
+
+############# callgrind commands.
+
+###### Top of the hierarchy of the callgrind commands.
+@Vinit("callgrind", "", gdb.COMMAND_SUPPORT, gdb.COMPLETE_COMMAND, True)
+class Callgrind_Command(Valgrind_Prefix_Command):
+ """Front end GDB command for Valgrind callgrind gdbserver monitor commands.
+Usage: callgrind CALLGRIND_MONITOR_COMMAND [ARG...]
+CALLGRIND_MONITOR_COMMAND is a callgrind subcommand, matching
+a gdbserver Valgrind callgrind monitor command.
+ARG... are optional arguments. They depend on the CALLGRIND_MONITOR_COMMAND.
+"""
+
+def_alias("cg", "callgrind")
+
+@Vinit("callgrind", "dump", gdb.COMMAND_DATA, gdb.COMPLETE_COMMAND, False)
+class Callgrind_Dump_Command(Valgrind_Command):
+ """Dump the callgrind counters.
+Usage: callgrind dump [DUMP_HINT]
+DUMP_HINT is a message stored in the resulting callgrind dump file.
+"""
+
+@Vinit("callgrind", "zero", gdb.COMMAND_DATA, gdb.COMPLETE_COMMAND, False)
+class Callgrind_Zero_Command(Valgrind_Command):
+ """Set the callgrind counters to zero.
+Usage: callgrind zero
+"""
+
+@Vinit("callgrind", "status", gdb.COMMAND_STATUS, gdb.COMPLETE_NONE, False)
+class Callgrind_Status_Command(Valgrind_Command):
+ """Show the status of callgrind.
+Usage: callgrind status
+"""
+
+@Vinit("callgrind", "instrumentation", gdb.COMMAND_STATUS, gdb.COMPLETE_COMMAND, False)
+class Callgrind_Instrumentation_Command(Valgrind_Command):
+ """Get or set the callgrind instrumentation state.
+Usage: callgrind instrumentation [on|off]
+Without argument, shows the current state of instrumentation,
+otherwise changes the instrumentation state to the given argument.
+"""
+
+############# massif commands.
+
+###### Top of the hierarchy of the massif commands.
+@Vinit("massif", "", gdb.COMMAND_SUPPORT, gdb.COMPLETE_COMMAND, True)
+class Massif_Command(Valgrind_Prefix_Command):
+ """Front end GDB command for Valgrind massif gdbserver monitor commands.
+Usage: massif MASSIF_MONITOR_COMMAND [ARG...]
+MASSIF_MONITOR_COMMAND is a massif subcommand, matching
+a gdbserver Valgrind massif monitor command.
+ARG... are optional arguments. They depend on the MASSIF_MONITOR_COMMAND.
+"""
+
+def_alias("ms", "massif")
+
+@Vinit("massif", "snapshot", gdb.COMMAND_DATA, gdb.COMPLETE_FILENAME, False)
+class Massif_Dump_Command(Valgrind_Command):
+ """Take a massif snapshot in FILENAME (default massif.vgdb.out).
+Usage: massif snapshot [FILENAME]
+"""
+
+@Vinit("massif", "detailed_snapshot", gdb.COMMAND_DATA, gdb.COMPLETE_FILENAME, False)
+class Massif_Dump_Command(Valgrind_Command):
+ """Take a massif detailed snapshot in FILENAME (default massif.vgdb.out).
+Usage: massif detailed_snapshot [FILENAME]
+"""
+
+@Vinit("massif", "all_snapshots", gdb.COMMAND_DATA, gdb.COMPLETE_FILENAME, False)
+class Massif_Dump_Command(Valgrind_Command):
+ """Save all snapshot(s) taken so far in FILENAME (default massif.vgdb.out).
+Usage: massif all_snapshots [FILENAME]
+"""
+
+@Vinit("massif", "xtmemory", gdb.COMMAND_DATA, gdb.COMPLETE_FILENAME, False)
+class Massic_Xtmemory_Command(Valgrind_Command):
+ """Dump xtree memory profile in FILENAME (default xtmemory.kcg.%p.%n).
+Usage: massif xtmemory [FILENAME]
+
+Example: (gdb) massif xtmemory my_program_xtree.kcg
+"""
diff --git a/coregrind/m_gdbserver/valgrind-monitor.py b/coregrind/m_gdbserver/valgrind-monitor.py
new file mode 100644
index 000000000..a1feaab53
--- /dev/null
+++ b/coregrind/m_gdbserver/valgrind-monitor.py
@@ -0,0 +1,32 @@
+# This file is part of Valgrind, a dynamic binary instrumentation
+# framework.
+
+# Copyright (C) 2022-2022 Philippe Waroquiers
+
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of the
+# License, or (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, see <http://www.gnu.org/licenses/>.
+
+# The GNU General Public License is contained in the file COPYING.
+
+"""
+Loads valgrind-monitor-def.py if not yet loaded.
+The purpose of this file is to avoid re-defining the python commands
+by reloading valgrind-monitor-def.py, as such redefinition causes a
+segmentation violation in GDB <= 13.
+"""
+
+import os
+
+if gdb.convenience_variable("_valgrind-monitor-def-loaded") == None:
+ gdb.set_convenience_variable ("_valgrind-monitor-def-loaded", 1)
+ gdb.execute("source " + os.path.dirname(__file__) + "/valgrind-monitor-def.py")
diff --git a/coregrind/m_main.c b/coregrind/m_main.c
index 2b4a8748f..362648ab8 100644
--- a/coregrind/m_main.c
+++ b/coregrind/m_main.c
@@ -68,6 +68,18 @@
#include "pub_core_clreq.h"
#endif
+/* Instruct GDB via a .debug_gdb_scripts section to load the valgrind and tool
+ front-end commands. */
+/* Note: The "MS" section flags are to remove duplicates. */
+#define DEFINE_GDB_PY_SCRIPT(script_name) \
+ asm("\
+.pushsection \".debug_gdb_scripts\", \"MS\",@progbits,1\n\
+.byte 1 /* Python */\n\
+.asciz \"" script_name "\"\n\
+.popsection \n\
+");
+
+DEFINE_GDB_PY_SCRIPT(VG_LIBDIR "/valgrind-monitor.py")
/*====================================================================*/
/*=== Command-line: variables, processing, etc ===*/
diff --git a/coregrind/vg_preloaded.c b/coregrind/vg_preloaded.c
index 3809811ae..75a3b7ed0 100644
--- a/coregrind/vg_preloaded.c
+++ b/coregrind/vg_preloaded.c
@@ -49,6 +49,19 @@
#include <features.h>
#endif
+/* Instruct GDB via a .debug_gdb_scripts section to load the valgrind and tool
+ front-end commands. */
+/* Note: The "MS" section flags are to remove duplicates. */
+#define DEFINE_GDB_PY_SCRIPT(script_name) \
+ asm("\
+.pushsection \".debug_gdb_scripts\", \"MS\",@progbits,1\n\
+.byte 1 /* Python */\n\
+.asciz \"" script_name "\"\n\
+.popsection \n\
+");
+
+DEFINE_GDB_PY_SCRIPT(VG_LIBDIR "/valgrind-monitor.py")
+
#if defined(VGO_linux) || defined(VGO_solaris) || defined(VGO_freebsd)
/* ---------------------------------------------------------------------
--
2.30.2
|
|
From: Paul F. <pa...@so...> - 2022-12-26 10:09:13
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=9acdd79b6947b3ddd3cdfa3f3d5afc7b8c8bee33 commit 9acdd79b6947b3ddd3cdfa3f3d5afc7b8c8bee33 Author: Paul Floyd <pj...@wa...> Date: Mon Dec 26 11:06:32 2022 +0100 Disable some memcheck tests on FreeBSD Fail due to differences in DWARF varinfo generated by clang compared to GCC. No fix in perspective. Diff: --- memcheck/tests/origin5-bz2.vgtest | 1 + memcheck/tests/varinfo2.vgtest | 1 + memcheck/tests/varinfo6.vgtest | 1 + 3 files changed, 3 insertions(+) diff --git a/memcheck/tests/origin5-bz2.vgtest b/memcheck/tests/origin5-bz2.vgtest index 5f9f573125..40fe6bb5a5 100644 --- a/memcheck/tests/origin5-bz2.vgtest +++ b/memcheck/tests/origin5-bz2.vgtest @@ -1,3 +1,4 @@ +prereq: ! ../../tests/os_test freebsd prog: origin5-bz2 vgopts: -q --track-origins=yes args: x diff --git a/memcheck/tests/varinfo2.vgtest b/memcheck/tests/varinfo2.vgtest index 0f73065462..6a86e6e531 100644 --- a/memcheck/tests/varinfo2.vgtest +++ b/memcheck/tests/varinfo2.vgtest @@ -1,3 +1,4 @@ +prereq: ! ../../tests/os_test freebsd prog: varinfo2 vgopts: --read-var-info=yes -q stderr_filter: filter_varinfo3 diff --git a/memcheck/tests/varinfo6.vgtest b/memcheck/tests/varinfo6.vgtest index 8855247a47..41984b19ba 100644 --- a/memcheck/tests/varinfo6.vgtest +++ b/memcheck/tests/varinfo6.vgtest @@ -1,2 +1,3 @@ +prereq: ! ../../tests/os_test freebsd prog: varinfo6 vgopts: --read-var-info=yes -q |
|
From: Paul F. <pa...@so...> - 2022-12-26 08:07:29
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=4dcfc05c20b508d8418309af61c403a6381e8a08 commit 4dcfc05c20b508d8418309af61c403a6381e8a08 Author: Paul Floyd <pj...@wa...> Date: Mon Dec 26 09:04:17 2022 +0100 Fixes related to Bug 392331 1. Added C++17 check to configure.ac 2. Needed Linux version of suppression 3. Added a filter for pthread_cond_signal Diff: --- configure.ac | 20 ++++++++++++++++++++ helgrind/tests/Makefile.am | 4 +++- helgrind/tests/bug392331.supp | 20 +++++++++++++++++++- helgrind/tests/bug392331.vgtest | 1 + helgrind/tests/bug392331_supp.vgtest | 1 + helgrind/tests/filter_stderr.in | 3 +++ helgrind/tests/tc20_verifywrap.stderr.exp | 2 +- helgrind/tests/tc20_verifywrap.stderr.exp-glibc-2.18 | 2 +- helgrind/tests/tc20_verifywrap.stderr.exp-glibc-2.21 | 2 +- helgrind/tests/tc20_verifywrap.stderr.exp-mips32 | 2 +- helgrind/tests/tc20_verifywrap.stderr.exp-mips32-b | 2 +- helgrind/tests/tc20_verifywrap.stderr.exp-s390x | 2 +- helgrind/tests/tc20_verifywrap.stderr.exp-solaris | 2 +- 13 files changed, 54 insertions(+), 9 deletions(-) diff --git a/configure.ac b/configure.ac index 5ae9377119..467c98e023 100755 --- a/configure.ac +++ b/configure.ac @@ -2009,6 +2009,26 @@ AC_MSG_RESULT([no]) # clang 3.3 cannot process <thread> from e.g. # gcc (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3 +AC_MSG_CHECKING([that C++ compiler can compile C++17 code]) +AC_LANG(C++) +safe_CXXFLAGS=$CXXFLAGS +CXXFLAGS=-std=c++17 + +AC_COMPILE_IFELSE([AC_LANG_SOURCE([ +int x; +])], +[ +ac_have_cxx_17=yes +AC_MSG_RESULT([yes]) +], [ +ac_have_cxx_17=no +AC_MSG_RESULT([no]) +]) +CXXFLAGS=$safe_CXXFLAGS +AC_LANG(C) + +AM_CONDITIONAL(HAVE_CXX17, test x$ac_have_cxx_17 = xyes) + AC_MSG_CHECKING([that C++ compiler can include <thread> header file]) AC_LANG(C++) safe_CXXFLAGS=$CXXFLAGS diff --git a/helgrind/tests/Makefile.am b/helgrind/tests/Makefile.am index 926a367c7e..2286e220f1 100755 --- a/helgrind/tests/Makefile.am +++ b/helgrind/tests/Makefile.am @@ -142,7 +142,6 @@ noinst_HEADERS = safe-pthread.h safe-semaphore.h # should be conditionally compiled like tc20_verifywrap is. check_PROGRAMS = \ annotate_hbefore \ - bug392331 \ cond_init_destroy \ cond_timedwait_invalid \ cond_timedwait_test \ @@ -242,6 +241,9 @@ annotate_hbefore_CFLAGS = $(AM_CFLAGS) endif bug322621_SOURCES = bug322621.cpp +if HAVE_CXX17 +check_PROGRAMS += bug392331 bug392331_SOURCES = bug392331.cpp bug392331_CXXFLAGS = $(AM_CXXFLAGS) -std=c++17 +endif diff --git a/helgrind/tests/bug392331.supp b/helgrind/tests/bug392331.supp index 8262d142e1..6b8c5e1174 100644 --- a/helgrind/tests/bug392331.supp +++ b/helgrind/tests/bug392331.supp @@ -1,7 +1,25 @@ { - Check that Dubious suppression works + Check that Dubious suppression works FreeBSD Helgrind:Dubious fun:pthread_cond_signal_WRK fun:pthread_cond_signal fun:_ZNSt3__118condition_variable10notify_oneEv } +{ + Check that Dubious suppression works Linux standalone + Helgrind:Dubious + fun:pthread_cond_signal_WRK + fun:pthread_cond_signal@* + fun:__gthread_cond_signal + fun:UnknownInlinedFun + fun:_ZNSt18condition_variable10notify_oneEv +} +# for some very strange reason the suppression is different +# when running under regtest +{ + Check that Dubious suppression works Linux regtest + Helgrind:Dubious + fun:pthread_cond_signal_WRK + fun:pthread_cond_signal@* + fun:_ZNSt18condition_variable10notify_oneEv +} diff --git a/helgrind/tests/bug392331.vgtest b/helgrind/tests/bug392331.vgtest index 6c4aff6bf1..c160dcd40e 100644 --- a/helgrind/tests/bug392331.vgtest +++ b/helgrind/tests/bug392331.vgtest @@ -1,2 +1,3 @@ +prereq: test -e bug392331 vgopts: -q prog: bug392331 diff --git a/helgrind/tests/bug392331_supp.vgtest b/helgrind/tests/bug392331_supp.vgtest index 611b4ca814..64fc729607 100644 --- a/helgrind/tests/bug392331_supp.vgtest +++ b/helgrind/tests/bug392331_supp.vgtest @@ -1,2 +1,3 @@ +prereq: test -e bug392331 vgopts: -q --suppressions=bug392331.supp prog: bug392331 diff --git a/helgrind/tests/filter_stderr.in b/helgrind/tests/filter_stderr.in index 9953b6527f..e7fecf5916 100755 --- a/helgrind/tests/filter_stderr.in +++ b/helgrind/tests/filter_stderr.in @@ -60,6 +60,9 @@ $SED \ # Some arches return ENOSYS instead of EINVAL for undefined futex operations. $SED -e "s/with error code 38 (ENOSYS: Function not implemented)/with error code 22 (EINVAL: Invalid argument)/" | +# filter differences in pthread_cond_signal +$SED -e "s/pthread_cond_signal@\*/pthread_cond_signal/" | + $dir/../../helgrind/tests/filter_helgrind "$@" exit 0 diff --git a/helgrind/tests/tc20_verifywrap.stderr.exp b/helgrind/tests/tc20_verifywrap.stderr.exp index 372daeab76..e5e128d837 100644 --- a/helgrind/tests/tc20_verifywrap.stderr.exp +++ b/helgrind/tests/tc20_verifywrap.stderr.exp @@ -124,7 +124,7 @@ Thread #x's call to pthread_cond_wait failed Thread #x: pthread_cond_{signal,broadcast}: dubious: associated lock is not held by any thread at 0x........: pthread_cond_signal_WRK (hg_intercepts.c:...) - by 0x........: pthread_cond_signal@* (hg_intercepts.c:...) + by 0x........: pthread_cond_signal (hg_intercepts.c:...) by 0x........: main (tc20_verifywrap.c:167) diff --git a/helgrind/tests/tc20_verifywrap.stderr.exp-glibc-2.18 b/helgrind/tests/tc20_verifywrap.stderr.exp-glibc-2.18 index b823d4000c..8b691ab838 100644 --- a/helgrind/tests/tc20_verifywrap.stderr.exp-glibc-2.18 +++ b/helgrind/tests/tc20_verifywrap.stderr.exp-glibc-2.18 @@ -116,7 +116,7 @@ Thread #x's call to pthread_cond_wait failed Thread #x: pthread_cond_{signal,broadcast}: dubious: associated lock is not held by any thread at 0x........: pthread_cond_signal_WRK (hg_intercepts.c:...) - by 0x........: pthread_cond_signal@* (hg_intercepts.c:...) + by 0x........: pthread_cond_signal (hg_intercepts.c:...) by 0x........: main (tc20_verifywrap.c:167) diff --git a/helgrind/tests/tc20_verifywrap.stderr.exp-glibc-2.21 b/helgrind/tests/tc20_verifywrap.stderr.exp-glibc-2.21 index 2a2ee9b5d2..cef930f2ad 100644 --- a/helgrind/tests/tc20_verifywrap.stderr.exp-glibc-2.21 +++ b/helgrind/tests/tc20_verifywrap.stderr.exp-glibc-2.21 @@ -124,7 +124,7 @@ Thread #x's call to pthread_cond_wait failed Thread #x: pthread_cond_{signal,broadcast}: dubious: associated lock is not held by any thread at 0x........: pthread_cond_signal_WRK (hg_intercepts.c:...) - by 0x........: pthread_cond_signal@* (hg_intercepts.c:...) + by 0x........: pthread_cond_signal (hg_intercepts.c:...) by 0x........: main (tc20_verifywrap.c:167) diff --git a/helgrind/tests/tc20_verifywrap.stderr.exp-mips32 b/helgrind/tests/tc20_verifywrap.stderr.exp-mips32 index be73900790..7aecc1df2d 100644 --- a/helgrind/tests/tc20_verifywrap.stderr.exp-mips32 +++ b/helgrind/tests/tc20_verifywrap.stderr.exp-mips32 @@ -124,7 +124,7 @@ Thread #x's call to pthread_cond_wait failed Thread #x: pthread_cond_{signal,broadcast}: dubious: associated lock is not held by any thread at 0x........: pthread_cond_signal_WRK (hg_intercepts.c:...) - by 0x........: pthread_cond_signal@* (hg_intercepts.c:...) + by 0x........: pthread_cond_signal (hg_intercepts.c:...) by 0x........: main (tc20_verifywrap.c:167) diff --git a/helgrind/tests/tc20_verifywrap.stderr.exp-mips32-b b/helgrind/tests/tc20_verifywrap.stderr.exp-mips32-b index d3f17d1506..d5bb6f83d8 100644 --- a/helgrind/tests/tc20_verifywrap.stderr.exp-mips32-b +++ b/helgrind/tests/tc20_verifywrap.stderr.exp-mips32-b @@ -124,7 +124,7 @@ Thread #x's call to pthread_cond_wait failed Thread #x: pthread_cond_{signal,broadcast}: dubious: associated lock is not held by any thread at 0x........: pthread_cond_signal_WRK (hg_intercepts.c:...) - by 0x........: pthread_cond_signal@* (hg_intercepts.c:...) + by 0x........: pthread_cond_signal (hg_intercepts.c:...) by 0x........: main (tc20_verifywrap.c:167) diff --git a/helgrind/tests/tc20_verifywrap.stderr.exp-s390x b/helgrind/tests/tc20_verifywrap.stderr.exp-s390x index f19215efb5..7737447ba4 100644 --- a/helgrind/tests/tc20_verifywrap.stderr.exp-s390x +++ b/helgrind/tests/tc20_verifywrap.stderr.exp-s390x @@ -126,7 +126,7 @@ Thread #x's call to pthread_cond_wait failed Thread #x: pthread_cond_{signal,broadcast}: dubious: associated lock is not held by any thread at 0x........: pthread_cond_signal_WRK (hg_intercepts.c:...) - by 0x........: pthread_cond_signal@* (hg_intercepts.c:...) + by 0x........: pthread_cond_signal (hg_intercepts.c:...) by 0x........: main (tc20_verifywrap.c:167) diff --git a/helgrind/tests/tc20_verifywrap.stderr.exp-solaris b/helgrind/tests/tc20_verifywrap.stderr.exp-solaris index 891b504908..64edaaca2f 100644 --- a/helgrind/tests/tc20_verifywrap.stderr.exp-solaris +++ b/helgrind/tests/tc20_verifywrap.stderr.exp-solaris @@ -116,7 +116,7 @@ Thread #x's call to pthread_cond_wait failed Thread #x: pthread_cond_{signal,broadcast}: dubious: associated lock is not held by any thread at 0x........: pthread_cond_signal_WRK (hg_intercepts.c:...) - by 0x........: pthread_cond_signal@* (hg_intercepts.c:...) + by 0x........: pthread_cond_signal (hg_intercepts.c:...) by 0x........: main (tc20_verifywrap.c:167) |
|
From: Paul F. <pa...@so...> - 2022-12-25 21:33:09
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=67bb7eeec920ffcc2edef5fdf48db04e653f10b9 commit 67bb7eeec920ffcc2edef5fdf48db04e653f10b9 Author: Paul Floyd <pj...@wa...> Date: Sun Dec 25 22:31:55 2022 +0100 Fix suppression file inconsistency from previous commit for Bug 392331 Diff: --- helgrind/tests/{bug392331.suppr => bug392331.supp} | 0 helgrind/tests/bug392331_supp.vgtest | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/helgrind/tests/bug392331.suppr b/helgrind/tests/bug392331.supp similarity index 100% rename from helgrind/tests/bug392331.suppr rename to helgrind/tests/bug392331.supp diff --git a/helgrind/tests/bug392331_supp.vgtest b/helgrind/tests/bug392331_supp.vgtest index 8e0fc7a38c..611b4ca814 100644 --- a/helgrind/tests/bug392331_supp.vgtest +++ b/helgrind/tests/bug392331_supp.vgtest @@ -1,2 +1,2 @@ -vgopts: -q --suppressions=bug392331.suppr +vgopts: -q --suppressions=bug392331.supp prog: bug392331 |