|
From: Nicholas N. <nj...@cs...> - 2005-03-04 04:45:18
|
CVS commit by nethercote:
Change the default --num-callers value from 4 to 12.
To support this, suppressions can now have an arbitrary number of lines in
their stack trace. Well, the maximum is a compile-time constant (currently 24,
which seems big enough), but it's no longer hard-wired to 4.
M +0 -3 coregrind/core.h 1.96
M +114 -114 coregrind/vg_errcontext.c 1.71
M +1 -1 coregrind/vg_main.c 1.260
M +4 -0 memcheck/tests/errs1.stderr.exp 1.6
M +4 -0 memcheck/tests/suppfree.stderr.exp 1.6
--- valgrind/coregrind/core.h #1.95:1.96
@@ -156,7 +156,4 @@ typedef struct _ThreadState ThreadState;
#define VG_N_RESERVED_FDS (10)
-/* Max number of callers for context in a suppression. */
-#define VG_N_SUPP_CALLERS 4
-
/* Useful macros */
/* a - alignment - must be a power of 2 */
--- valgrind/coregrind/vg_errcontext.c #1.70:1.71
@@ -127,8 +127,12 @@ typedef
CoreSuppKind;
+/* Max number of callers for context in a suppression. */
+#define VG_MAX_SUPP_CALLERS 24
+
/* For each caller specified for a suppression, record the nature of
the caller name. Not of interest to tools. */
typedef
enum {
+ NoName, /* Error case */
ObjName, /* Name is of an shared object file. */
FunName /* Name is of a function. */
@@ -136,4 +140,11 @@ typedef
SuppLocTy;
+typedef
+ struct {
+ SuppLocTy ty;
+ Char* name;
+ }
+ SuppLoc;
+
/* Suppressions. Tools can get/set tool-relevant parts with functions
declared in include/tool.h. Extensible via the 'extra' field.
@@ -144,8 +155,10 @@ struct _Supp {
Int count; // The number of times this error has been suppressed.
Char* sname; // The name by which the suppression is referred to.
- /* First two (name of fn where err occurs, and immediate caller)
- * are mandatory; extra two are optional. */
- SuppLocTy caller_ty[VG_N_SUPP_CALLERS];
- Char* caller [VG_N_SUPP_CALLERS];
+
+ // Length of 'callers'
+ Int n_callers;
+ // Array of callers, for matching stack traces. First one (name of fn
+ // where err occurs) is mandatory; rest are optional.
+ SuppLoc* callers;
/* The tool-specific part */
@@ -323,6 +336,6 @@ static void gen_suppression(Error* err)
Int stop_at = VG_(clo_backtrace_size);
- /* At most VG_N_SUPP_CALLERS names */
- if (stop_at > VG_N_SUPP_CALLERS) stop_at = VG_N_SUPP_CALLERS;
+ /* At most VG_MAX_SUPP_CALLERS names */
+ if (stop_at > VG_MAX_SUPP_CALLERS) stop_at = VG_MAX_SUPP_CALLERS;
vg_assert(stop_at > 0);
@@ -350,5 +363,5 @@ static void gen_suppression(Error* err)
if (i > 0)
eip -= MIN_INSTR_SIZE; // point to calling line
- if ( VG_(get_fnname_nodemangle) (eip, buf, M_VG_ERRTXT) ) {
+ if ( VG_(get_fnname) (eip, buf, M_VG_ERRTXT) ) {
// Stop after "main"; if main() is recursive, stop after last main().
@@ -735,14 +748,14 @@ Bool VG_(get_line) ( Int fd, Char* buf,
Returns False if failed.
*/
-static Bool setLocationTy ( Char** p_caller, SuppLocTy* p_ty )
+static Bool setLocationTy ( SuppLoc* p )
{
- if (VG_(strncmp)(*p_caller, "fun:", 4) == 0) {
- (*p_caller) += 4;
- *p_ty = FunName;
+ if (VG_(strncmp)(p->name, "fun:", 4) == 0) {
+ p->name += 4;
+ p->ty = FunName;
return True;
}
- if (VG_(strncmp)(*p_caller, "obj:", 4) == 0) {
- (*p_caller) += 4;
- *p_ty = ObjName;
+ if (VG_(strncmp)(p->name, "obj:", 4) == 0) {
+ p->name += 4;
+ p->ty = ObjName;
return True;
}
@@ -776,8 +789,10 @@ static void load_one_suppressions_file (
# define N_BUF 200
Int fd, i;
- Bool eof, too_many_contexts = False;
+ Bool eof;
Char buf[N_BUF+1];
Char* tool_names;
Char* supp_name;
+ Char* err_str = NULL;
+ SuppLoc tmp_callers[VG_MAX_SUPP_CALLERS];
fd = VG_(open)( filename, VKI_O_RDONLY, 0 );
@@ -788,4 +803,6 @@ static void load_one_suppressions_file (
}
+#define BOMB(S) { err_str = S; goto syntax_error; }
+
while (True) {
/* Assign and initialise the two suppression halves (core and tool) */
@@ -793,5 +810,11 @@ static void load_one_suppressions_file (
supp = VG_(arena_malloc)(VG_AR_CORE, sizeof(Supp));
supp->count = 0;
- for (i = 0; i < VG_N_SUPP_CALLERS; i++) supp->caller[i] = NULL;
+
+ // Initialise temporary reading-in buffer.
+ for (i = 0; i < VG_MAX_SUPP_CALLERS; i++) {
+ tmp_callers[i].ty = NoName;
+ tmp_callers[i].name = NULL;
+ }
+
supp->string = supp->extra = NULL;
@@ -799,19 +822,21 @@ static void load_one_suppressions_file (
if (eof) break;
- if (!VG_STREQ(buf, "{")) goto syntax_error;
+ if (!VG_STREQ(buf, "{")) BOMB("expected '{' or end-of-file");
eof = VG_(get_line) ( fd, buf, N_BUF );
- if (eof || VG_STREQ(buf, "}")) goto syntax_error;
+
+ if (eof || VG_STREQ(buf, "}")) BOMB("unexpected '}'");
+
supp->sname = VG_(arena_strdup)(VG_AR_CORE, buf);
eof = VG_(get_line) ( fd, buf, N_BUF );
- if (eof) goto syntax_error;
+ if (eof) BOMB("unexpected end-of-file");
- /* Check it has the "skin1,skin2,...:supp" form (look for ':') */
+ /* Check it has the "tool1,tool2,...:supp" form (look for ':') */
i = 0;
while (True) {
if (buf[i] == ':') break;
- if (buf[i] == '\0') goto syntax_error;
+ if (buf[i] == '\0') BOMB("malformed 'tool1,tool2,...:supp' line");
i++;
}
@@ -821,29 +846,27 @@ static void load_one_suppressions_file (
supp_name = & buf[i+1];
- /* Is it a core suppression? */
if (VG_(needs).core_errors && tool_name_present("core", tool_names))
{
+ // A core suppression
if (VG_STREQ(supp_name, "PThread"))
supp->skind = PThreadSupp;
else
- goto syntax_error;
+ BOMB("unknown core suppression type");
}
-
- /* Is it a tool suppression? */
else if (VG_(needs).skin_errors &&
tool_name_present(VG_(details).name, tool_names))
{
- if (SK_(recognised_suppression)(supp_name, supp))
- {
+ // A tool suppression
+ if (SK_(recognised_suppression)(supp_name, supp)) {
/* Do nothing, function fills in supp->skind */
- } else
- goto syntax_error;
+ } else {
+ BOMB("unknown tool suppression type");
+ }
}
-
else {
- /* Ignore rest of suppression */
+ // Ignore rest of suppression
while (True) {
eof = VG_(get_line) ( fd, buf, N_BUF );
- if (eof) goto syntax_error;
+ if (eof) BOMB("unexpected end-of-file");
if (VG_STREQ(buf, "}"))
break;
@@ -854,29 +877,43 @@ static void load_one_suppressions_file (
if (VG_(needs).skin_errors &&
!SK_(read_extra_suppression_info)(fd, buf, N_BUF, supp))
- goto syntax_error;
+ {
+ BOMB("bad or missing extra suppression info");
+ }
- /* "i > 0" ensures at least one caller read. */
- for (i = 0; i <= VG_N_SUPP_CALLERS; i++) {
+ i = 0;
+ while (True) {
eof = VG_(get_line) ( fd, buf, N_BUF );
- if (eof) goto syntax_error;
- if (i > 0 && VG_STREQ(buf, "}"))
+ if (eof)
+ BOMB("unexpected end-of-file");
+ if (VG_STREQ(buf, "}")) {
+ if (i > 0) {
break;
- if (i == VG_N_SUPP_CALLERS)
+ } else {
+ BOMB("missing stack trace");
+ }
+ }
+ if (i == VG_MAX_SUPP_CALLERS)
+ BOMB("too many callers in stack trace");
+ if (i > 0 && i >= VG_(clo_backtrace_size))
break;
- supp->caller[i] = VG_(arena_strdup)(VG_AR_CORE, buf);
- if (!setLocationTy(&(supp->caller[i]), &(supp->caller_ty[i])))
- goto syntax_error;
+ tmp_callers[i].name = VG_(arena_strdup)(VG_AR_CORE, buf);
+ if (!setLocationTy(&(tmp_callers[i])))
+ BOMB("location should start with 'fun:' or 'obj:'");
+ i++;
}
- /* make sure to grab the '}' if the num callers is >=
- VG_N_SUPP_CALLERS */
+ // If the num callers is >= VG_(clo_backtrace_size), ignore any extra
+ // lines and grab the '}'.
if (!VG_STREQ(buf, "}")) {
- // Don't just ignore extra lines -- abort. (Someone complained
- // about silent ignoring of lines in bug #77922.)
- //do {
- // eof = VG_(get_line) ( fd, buf, N_BUF );
- //} while (!eof && !VG_STREQ(buf, "}"));
- too_many_contexts = True;
- goto syntax_error;
+ do {
+ eof = VG_(get_line) ( fd, buf, N_BUF );
+ } while (!eof && !VG_STREQ(buf, "}"));
+ }
+
+ // Copy tmp_callers[] into supp->callers[]
+ supp->n_callers = i;
+ supp->callers = VG_(arena_malloc)(VG_AR_CORE, i*sizeof(SuppLoc));
+ for (i = 0; i < supp->n_callers; i++) {
+ supp->callers[i] = tmp_callers[i];
}
@@ -888,24 +925,12 @@ static void load_one_suppressions_file (
syntax_error:
- if (eof) {
- VG_(message)(Vg_UserMsg,
- "FATAL: in suppressions file `%s': unexpected EOF",
- filename );
- } else if (too_many_contexts) {
- VG_(message)(Vg_UserMsg,
- "FATAL: in suppressions file: `%s': at %s:",
- filename, buf );
- VG_(message)(Vg_UserMsg,
- "too many lines (limit of %d contexts in suppressions)",
- VG_N_SUPP_CALLERS);
- } else {
VG_(message)(Vg_UserMsg,
- "FATAL: in suppressions file: `%s': syntax error on: %s",
- filename, buf );
- }
+ "FATAL: in suppressions file `%s': %s", filename, err_str );
+
VG_(close)(fd);
VG_(message)(Vg_UserMsg, "exiting now.");
VG_(exit)(1);
+# undef BOMB
# undef N_BUF
}
@@ -925,17 +950,5 @@ void VG_(load_suppressions) ( void )
}
-/* Return the name of an erring fn in a way which is useful
- for comparing against the contents of a suppressions file.
- Doesn't demangle the fn name, because we want to refer to
- mangled names in the suppressions file.
-*/
-static void get_objname_fnname ( Addr a, Char* obj_buf, Int n_obj_buf,
- Char* fun_buf, Int n_fun_buf )
-{
- (void)VG_(get_objname) ( a, obj_buf, n_obj_buf );
- (void)VG_(get_fnname_nodemangle)( a, fun_buf, n_fun_buf );
-}
-
-static __inline__
+static
Bool supp_matches_error(Supp* su, Error* err)
{
@@ -956,20 +969,26 @@ Bool supp_matches_error(Supp* su, Error*
}
-static __inline__
-Bool supp_matches_callers(Supp* su, Char caller_obj[][M_VG_ERRTXT],
- Char caller_fun[][M_VG_ERRTXT])
+static
+Bool supp_matches_callers(Error* err, Supp* su)
{
Int i;
+ Char caller_name[M_VG_ERRTXT];
- for (i = 0; i < VG_N_SUPP_CALLERS && su->caller[i] != NULL; i++) {
- switch (su->caller_ty[i]) {
- case ObjName: if (VG_(string_match)(su->caller[i],
- caller_obj[i])) break;
- return False;
- case FunName: if (VG_(string_match)(su->caller[i],
- caller_fun[i])) break;
- return False;
+ for (i = 0; i < su->n_callers; i++) {
+ Addr a = err->where->ips[i];
+ vg_assert(su->callers[i].name != NULL);
+ switch (su->callers[i].ty) {
+ case ObjName:
+ (void)VG_(get_objname)(a, caller_name, M_VG_ERRTXT);
+ break;
+
+ case FunName:
+ // Nb: mangled names used in suppressions
+ (void)VG_(get_fnname)(a, caller_name, M_VG_ERRTXT);
+ break;
default: VG_(skin_panic)("supp_matches_callers");
}
+ if (!VG_(string_match)(su->callers[i].name, caller_name))
+ return False;
}
@@ -984,30 +1003,11 @@ Bool supp_matches_callers(Supp* su, Char
static Supp* is_suppressible_error ( Error* err )
{
- Int i;
-
- static Char caller_obj[VG_N_SUPP_CALLERS][M_VG_ERRTXT];
- static Char caller_fun[VG_N_SUPP_CALLERS][M_VG_ERRTXT];
-
Supp* su;
- /* get_objname_fnname() writes the function name and object name if
- it finds them in the debug info. So the strings in the suppression
- file should match these.
- */
-
- /* Initialise these strs so they are always safe to compare, even
- if get_objname_fnname doesn't write anything to them. */
- for (i = 0; i < VG_N_SUPP_CALLERS; i++)
- caller_obj[i][0] = caller_fun[i][0] = 0;
-
- for (i = 0; i < VG_N_SUPP_CALLERS && i < VG_(clo_backtrace_size); i++) {
- get_objname_fnname ( err->where->ips[i], caller_obj[i], M_VG_ERRTXT,
- caller_fun[i], M_VG_ERRTXT );
- }
-
/* See if the error context matches any suppression. */
for (su = vg_suppressions; su != NULL; su = su->next) {
if (supp_matches_error(su, err) &&
- supp_matches_callers(su, caller_obj, caller_fun)) {
+ supp_matches_callers(err, su))
+ {
return su;
}
@@ -1017,4 +1017,4 @@ static Supp* is_suppressible_error ( Err
/*--------------------------------------------------------------------*/
-/*--- end vg_errcontext.c ---*/
+/*--- end ---*/
/*--------------------------------------------------------------------*/
--- valgrind/coregrind/vg_main.c #1.259:1.260
@@ -1457,5 +1457,5 @@ Bool VG_(clo_trace_sched) = False;
Bool VG_(clo_trace_pthreads) = False;
Int VG_(clo_dump_error) = 0;
-Int VG_(clo_backtrace_size) = 4;
+Int VG_(clo_backtrace_size) = 12;
Char* VG_(clo_weird_hacks) = NULL;
Bool VG_(clo_run_libc_freeres) = True;
--- valgrind/memcheck/tests/errs1.stderr.exp #1.5:1.6
@@ -9,4 +9,6 @@
by 0x........: yyy (errs1.c:13)
by 0x........: xxx (errs1.c:14)
+ by 0x........: www (errs1.c:15)
+ by 0x........: main (errs1.c:17)
Invalid write of size 1
@@ -20,2 +22,4 @@
by 0x........: yyy (errs1.c:13)
by 0x........: xxx (errs1.c:14)
+ by 0x........: www (errs1.c:15)
+ by 0x........: main (errs1.c:17)
--- valgrind/memcheck/tests/suppfree.stderr.exp #1.5:1.6
@@ -4,4 +4,6 @@
by 0x........: ccc (suppfree.c:12)
by 0x........: bbb (suppfree.c:17)
+ by 0x........: aaa (suppfree.c:22)
+ by 0x........: main (suppfree.c:28)
Address 0x........ is 0 bytes inside a block of size 10 free'd
at 0x........: free (vg_replace_malloc.c:...)
@@ -9,2 +11,4 @@
by 0x........: ccc (suppfree.c:12)
by 0x........: bbb (suppfree.c:17)
+ by 0x........: aaa (suppfree.c:22)
+ by 0x........: main (suppfree.c:28)
|