*/
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;
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
VG_(printf_xml)(" <sname>%s</sname>\n", dummy_name);
VG_(printf_xml)(
" <skind>%pS:%pS</skind>\n", VG_(details).name, name);
- if (anyXtra)
+ if (num_written)
VG_(printf_xml)(" <skaux>%pS</skaux>\n", xtra);
// Print stack trace elements
}
VG_(deleteXA)(text);
+ VG_(free)(xtra);
}
" </pair>\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;
}
/* --------- 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;
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*)
)
{
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
* 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
}
}
-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)
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);
}
}
-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 )
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 );
// 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
}
}
-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)
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 );