From: Florian Krohm Date: Tue, 7 Oct 2014 14:28:52 +0000 (+0000) Subject: Merge revisions 14230, 14602, and 14604 from the BUF_REMOVAL branch to trunk. X-Git-Tag: svn/VALGRIND_3_11_0~938 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5929994d48a5f91ca65428f3d189d797d383f87a;p=thirdparty%2Fvalgrind.git Merge revisions 14230, 14602, and 14604 from the BUF_REMOVAL branch to trunk. The change eliminates the fixed size buffers in gen_suppression and show_used_suppressions. This is achieved by changing the return type from VG_TDICT_CALL(tool_get_extra_suppression_info and VG_TDICT_CALL(tool_print_extra_suppression_use from Bool to SizeT. A return value of 0 indicates that nothing (except the terminating '\0' which is always inserted) was written to the buffer. This corresponds to the previous False return value. A return value which is equal to the buffer size (that was passed in as function argument) indicates that the buffer was not large enough. The caller then resizes the buffer and retries. Otherwise, the buffer was large enough. Regtested with a resize value of 1. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@14606 --- diff --git a/coregrind/m_errormgr.c b/coregrind/m_errormgr.c index 0de1529fcb..f2766e9722 100644 --- a/coregrind/m_errormgr.c +++ b/coregrind/m_errormgr.c @@ -362,8 +362,6 @@ static void printSuppForIp_nonXML(UInt n, Addr ip, void* textV) */ static void gen_suppression(Error* err) { - HChar xtra[256]; /* assumed big enough (is overrun-safe) */ - Bool anyXtra; const HChar* name; ExeContext* ec; XArray* /* HChar */ text; @@ -394,12 +392,21 @@ static void gen_suppression(Error* err) VG_(xaprintf)(text, " <%s>\n", dummy_name); VG_(xaprintf)(text, " %s:%s\n", VG_(details).name, name); - VG_(memset)(xtra, 0, sizeof(xtra)); - anyXtra = VG_TDICT_CALL(tool_get_extra_suppression_info, - err, xtra, sizeof(xtra)); - vg_assert(xtra[sizeof(xtra)-1] == 0); + HChar *xtra = NULL; + SizeT xtra_size = 0; + SizeT num_written; - if (anyXtra) + do { + xtra_size += 256; + xtra = VG_(realloc)("errormgr.gen_suppression.2", xtra,xtra_size); + num_written = VG_TDICT_CALL(tool_get_extra_suppression_info, + err, xtra, xtra_size); + } while (num_written == xtra_size); // resize buffer and retry + + // Ensure buffer is properly terminated + vg_assert(xtra[num_written] == '\0'); + + if (num_written) VG_(xaprintf)(text, " %s\n", xtra); // Print stack trace elements @@ -432,7 +439,7 @@ static void gen_suppression(Error* err) VG_(printf_xml)(" %s\n", dummy_name); VG_(printf_xml)( " %pS:%pS\n", VG_(details).name, name); - if (anyXtra) + if (num_written) VG_(printf_xml)(" %pS\n", xtra); // Print stack trace elements @@ -454,6 +461,7 @@ static void gen_suppression(Error* err) } VG_(deleteXA)(text); + VG_(free)(xtra); } @@ -932,19 +940,28 @@ static Bool show_used_suppressions ( void ) " \n", su->count, su->sname ); } else { - HChar xtra[256]; /* assumed big enough (is overrun-safe) */ - Bool anyXtra; + HChar *xtra = NULL; + Int xtra_size = 0; + SizeT num_written; // blank line before the first shown suppression, if any if (!any_supp) VG_(dmsg)("\n"); - VG_(memset)(xtra, 0, sizeof(xtra)); - anyXtra = VG_TDICT_CALL(tool_print_extra_suppression_use, - su, xtra, sizeof(xtra)); - vg_assert(xtra[sizeof(xtra)-1] == 0); + + do { + xtra_size += 256; + xtra = VG_(realloc)("errormgr.sus.1", xtra, xtra_size); + num_written = VG_TDICT_CALL(tool_print_extra_suppression_use, + su, xtra, xtra_size); + } while (num_written == xtra_size); // resize buffer and retry + + // Ensure buffer is properly terminated + vg_assert(xtra[num_written] == '\0'); + VG_(dmsg)("used_suppression: %6d %s %s:%d%s%s\n", su->count, su->sname, VG_(clo_suppressions)[su->clo_suppressions_i], su->sname_lineno, - anyXtra ? " " : "", xtra); + num_written ? " " : "", xtra); + VG_(free)(xtra); } any_supp = True; } diff --git a/coregrind/m_libcprint.c b/coregrind/m_libcprint.c index e367767921..cdeabb2b92 100644 --- a/coregrind/m_libcprint.c +++ b/coregrind/m_libcprint.c @@ -227,6 +227,17 @@ UInt VG_(sprintf) ( HChar* buf, const HChar *format, ... ) /* --------- snprintf --------- */ +/* The return value of VG_(snprintf) and VG_(vsnprintf) differs from + what is defined in C99. Let S be the size of the buffer as given in + the 2nd argument. + Return value R: + R < S: The output string was successfully written to the buffer. + It is null-terminated and R == strlen( output string ) + R == S: The supplied buffer was too small to hold the output string. + The first S-1 characters of the output string were written + to the buffer followed by the terminating null character. +*/ + typedef struct { HChar* buf; diff --git a/coregrind/m_tooliface.c b/coregrind/m_tooliface.c index 4b1c96eb29..e96a9a136e 100644 --- a/coregrind/m_tooliface.c +++ b/coregrind/m_tooliface.c @@ -236,8 +236,8 @@ void VG_(needs_tool_errors)( Bool (*read_extra) (Int, HChar**, SizeT*, Int*, Supp*), Bool (*matches) (Error*, Supp*), const HChar* (*name) (Error*), - Bool (*get_xtra_si)(Error*,/*OUT*/HChar*,Int), - Bool (*print_xtra_su)(Supp*,/*OUT*/HChar*,Int), + SizeT (*get_xtra_si)(Error*,/*OUT*/HChar*,Int), + SizeT (*print_xtra_su)(Supp*,/*OUT*/HChar*,Int), void (*update_xtra_su)(Error*, Supp*) ) { diff --git a/coregrind/pub_core_tooliface.h b/coregrind/pub_core_tooliface.h index 65311d8468..585170be0f 100644 --- a/coregrind/pub_core_tooliface.h +++ b/coregrind/pub_core_tooliface.h @@ -128,8 +128,8 @@ typedef struct { Supp*); Bool (*tool_error_matches_suppression) (Error*, Supp*); const HChar* (*tool_get_error_name) (Error*); - Bool (*tool_get_extra_suppression_info) (Error*,/*OUT*/HChar*,Int); - Bool (*tool_print_extra_suppression_use) (Supp*,/*OUT*/HChar*,Int); + SizeT (*tool_get_extra_suppression_info) (Error*,/*OUT*/HChar*,Int); + SizeT (*tool_print_extra_suppression_use) (Supp*,/*OUT*/HChar*,Int); void (*tool_update_extra_suppression_use) (Error*, Supp*); // VG_(needs).superblock_discards diff --git a/drd/drd_error.c b/drd/drd_error.c index 7e6b5e1201..1d8f0e35ce 100644 --- a/drd/drd_error.c +++ b/drd/drd_error.c @@ -600,17 +600,21 @@ static const HChar* drd_get_error_name(Error* e) * define any 'extra' suppression information. */ static -Bool drd_get_extra_suppression_info(Error* e, - /*OUT*/HChar* buf, Int nBuf) +SizeT drd_get_extra_suppression_info(Error* e, + /*OUT*/HChar* buf, Int nBuf) { - return False; + tl_assert(nBuf >= 1); + buf[0] = '\0'; + return 0; } static -Bool drd_print_extra_suppression_use(Supp* su, - /*OUT*/HChar* buf, Int nBuf) +SizeT drd_print_extra_suppression_use(Supp* su, + /*OUT*/HChar* buf, Int nBuf) { - return False; + tl_assert(nBuf >= 1); + buf[0] = '\0'; + return 0; } static diff --git a/exp-sgcheck/pc_common.c b/exp-sgcheck/pc_common.c index 741d54ab93..27dd2f2173 100644 --- a/exp-sgcheck/pc_common.c +++ b/exp-sgcheck/pc_common.c @@ -777,26 +777,29 @@ const HChar* pc_get_error_name ( Error* err ) } } -Bool pc_get_extra_suppression_info ( Error* err, - /*OUT*/HChar* buf, Int nBuf ) +SizeT pc_get_extra_suppression_info ( Error* err, + /*OUT*/HChar* buf, Int nBuf ) { ErrorKind ekind = VG_(get_error_kind )(err); tl_assert(buf); - tl_assert(nBuf >= 16); // stay sane + tl_assert(nBuf >= 1); + if (XE_SysParam == ekind) { const HChar* errstr = VG_(get_error_string)(err); tl_assert(errstr); - VG_(snprintf)(buf, nBuf-1, "%s", errstr); - return True; + return VG_(snprintf)(buf, nBuf, "%s", errstr); } else { - return False; + buf[0] = '\0'; + return 0; } } -Bool pc_print_extra_suppression_use ( Supp* su, - /*OUT*/HChar* buf, Int nBuf ) +SizeT pc_print_extra_suppression_use ( Supp* su, + /*OUT*/HChar* buf, Int nBuf ) { - return False; + tl_assert(nBuf >= 1); + buf[0] = '\0'; + return 0; } void pc_update_extra_suppression_use (Error* err, Supp* su) diff --git a/exp-sgcheck/pc_common.h b/exp-sgcheck/pc_common.h index f783d4b3e1..f0d3a86dd8 100644 --- a/exp-sgcheck/pc_common.h +++ b/exp-sgcheck/pc_common.h @@ -56,9 +56,9 @@ Bool pc_read_extra_suppression_info ( Int fd, HChar** bufpp, SizeT* nBufp, Int* lineno, Supp* su ); Bool pc_error_matches_suppression (Error* err, Supp* su); const HChar* pc_get_error_name ( Error* err ); -Bool pc_get_extra_suppression_info ( Error* err, +SizeT pc_get_extra_suppression_info ( Error* err, /*OUT*/HChar* buf, Int nBuf ); -Bool pc_print_extra_suppression_use ( Supp* su, +SizeT pc_print_extra_suppression_use ( Supp* su, /*OUT*/HChar* buf, Int nBuf ); void pc_update_extra_suppression_use (Error* err, Supp* su); diff --git a/helgrind/hg_errors.c b/helgrind/hg_errors.c index 93ea58d39b..fc33bedc2b 100644 --- a/helgrind/hg_errors.c +++ b/helgrind/hg_errors.c @@ -1308,18 +1308,22 @@ Bool HG_(error_matches_suppression) ( Error* err, Supp* su ) } } -Bool HG_(get_extra_suppression_info) ( Error* err, +SizeT HG_(get_extra_suppression_info) ( Error* err, /*OUT*/HChar* buf, Int nBuf ) { + tl_assert(nBuf >= 1); /* Do nothing */ - return False; + buf[0] = '\0'; + return 0; } -Bool HG_(print_extra_suppression_use) ( Supp* su, +SizeT HG_(print_extra_suppression_use) ( Supp* su, /*OUT*/HChar* buf, Int nBuf ) { + tl_assert(nBuf >= 1); /* Do nothing */ - return False; + buf[0] = '\0'; + return 0; } void HG_(update_extra_suppression_use) ( Error* err, Supp* su ) diff --git a/helgrind/hg_errors.h b/helgrind/hg_errors.h index 03a6086bd9..76f2145934 100644 --- a/helgrind/hg_errors.h +++ b/helgrind/hg_errors.h @@ -44,9 +44,9 @@ Bool HG_(read_extra_suppression_info) ( Int fd, HChar** bufpp, SizeT* nBufp, Int* lineno, Supp* su ); Bool HG_(error_matches_suppression) ( Error* err, Supp* su ); const HChar* HG_(get_error_name) ( Error* err ); -Bool HG_(get_extra_suppression_info) ( Error* err, +SizeT HG_(get_extra_suppression_info) ( Error* err, /*OUT*/HChar* buf, Int nBuf ); -Bool HG_(print_extra_suppression_use) ( Supp* su, +SizeT HG_(print_extra_suppression_use) ( Supp* su, /*OUT*/HChar* buf, Int nBuf ); void HG_(update_extra_suppression_use) ( Error* err, Supp* su ); diff --git a/include/pub_tool_tooliface.h b/include/pub_tool_tooliface.h index 4349c1bb7a..ad503b00e1 100644 --- a/include/pub_tool_tooliface.h +++ b/include/pub_tool_tooliface.h @@ -335,21 +335,19 @@ extern void VG_(needs_tool_errors) ( // This should print into buf[0..nBuf-1] any extra info for the // error, for --gen-suppressions, but not including any leading - // spaces nor a trailing newline. When called, buf[0 .. nBuf-1] - // will be zero filled, and it is expected and checked that the - // last element is still zero after the call. In other words the - // tool may not overrun the buffer, and this is checked for. If - // there is any info printed in the buffer, return True, otherwise - // do nothing, and return False. This function is the inverse of - // VG_(tdict).tool_read_extra_suppression_info(). - Bool (*print_extra_suppression_info)(Error* err, - /*OUT*/HChar* buf, Int nBuf), + // spaces nor a trailing newline. The string needs to be null + // terminated. If the buffer is large enough to hold the string + // including the terminating null character the function shall + // return the value that strlen would return for the string. + // If the buffer is too small the function shall return nBuf. + SizeT (*print_extra_suppression_info)(Error* err, + /*OUT*/HChar* buf, Int nBuf), // This is similar to print_extra_suppression_info, but is used // to print information such as additional statistical counters // as part of the used suppression list produced by -v. - Bool (*print_extra_suppression_use)(Supp* su, - /*OUT*/HChar* buf, Int nBuf), + SizeT (*print_extra_suppression_use)(Supp* su, + /*OUT*/HChar* buf, Int nBuf), // Called by error mgr once it has been established that err // is suppressed by su. update_extra_suppression_use typically diff --git a/memcheck/mc_errors.c b/memcheck/mc_errors.c index 2efa2b6ab8..1f031c6232 100644 --- a/memcheck/mc_errors.c +++ b/memcheck/mc_errors.c @@ -1511,51 +1511,51 @@ const HChar* MC_(get_error_name) ( Error* err ) } } -Bool MC_(get_extra_suppression_info) ( Error* err, - /*OUT*/HChar* buf, Int nBuf ) +SizeT MC_(get_extra_suppression_info) ( Error* err, + /*OUT*/HChar* buf, Int nBuf ) { ErrorKind ekind = VG_(get_error_kind )(err); tl_assert(buf); - tl_assert(nBuf >= 16); // stay sane + tl_assert(nBuf >= 1); + if (Err_RegParam == ekind || Err_MemParam == ekind) { const HChar* errstr = VG_(get_error_string)(err); tl_assert(errstr); - VG_(snprintf)(buf, nBuf-1, "%s", errstr); - return True; + return VG_(snprintf)(buf, nBuf, "%s", errstr); } else if (Err_Leak == ekind) { MC_Error* extra = VG_(get_error_extra)(err); - VG_(snprintf) - (buf, nBuf-1, "match-leak-kinds: %s", + return VG_(snprintf) (buf, nBuf, "match-leak-kinds: %s", pp_Reachedness_for_leak_kinds(extra->Err.Leak.lr->key.state)); - return True; } else if (Err_FishyValue == ekind) { MC_Error* extra = VG_(get_error_extra)(err); - VG_(snprintf) - (buf, nBuf-1, "%s(%s)", extra->Err.FishyValue.function_name, - extra->Err.FishyValue.argument_name); - return True; + return VG_(snprintf) (buf, nBuf, "%s(%s)", + extra->Err.FishyValue.function_name, + extra->Err.FishyValue.argument_name); } else { - return False; + buf[0] = '\0'; + return 0; } } -Bool MC_(print_extra_suppression_use) ( Supp *su, - /*OUT*/HChar *buf, Int nBuf ) +SizeT MC_(print_extra_suppression_use) ( Supp *su, + /*OUT*/HChar *buf, Int nBuf ) { + tl_assert(nBuf >= 1); + if (VG_(get_supp_kind)(su) == LeakSupp) { MC_LeakSuppExtra *lse = (MC_LeakSuppExtra*) VG_(get_supp_extra) (su); if (lse->leak_search_gen == MC_(leak_search_gen) && lse->blocks_suppressed > 0) { - VG_(snprintf) (buf, nBuf-1, - "suppressed: %'lu bytes in %'lu blocks", - lse->bytes_suppressed, - lse->blocks_suppressed); - return True; - } else - return False; - } else - return False; + return VG_(snprintf) (buf, nBuf, + "suppressed: %'lu bytes in %'lu blocks", + lse->bytes_suppressed, + lse->blocks_suppressed); + } + } + + buf[0] = '\0'; + return 0; } void MC_(update_extra_suppression_use) ( Error* err, Supp* su) diff --git a/memcheck/mc_include.h b/memcheck/mc_include.h index 39e03824a0..26ad25e1fd 100644 --- a/memcheck/mc_include.h +++ b/memcheck/mc_include.h @@ -405,10 +405,10 @@ Bool MC_(read_extra_suppression_info) ( Int fd, HChar** buf, Bool MC_(error_matches_suppression) ( Error* err, Supp* su ); -Bool MC_(get_extra_suppression_info) ( Error* err, - /*OUT*/HChar* buf, Int nBuf ); -Bool MC_(print_extra_suppression_use) ( Supp* su, +SizeT MC_(get_extra_suppression_info) ( Error* err, /*OUT*/HChar* buf, Int nBuf ); +SizeT MC_(print_extra_suppression_use) ( Supp* su, + /*OUT*/HChar* buf, Int nBuf ); void MC_(update_extra_suppression_use) ( Error* err, Supp* su ); const HChar* MC_(get_error_name) ( Error* err );