Index: Makefile.am =================================================================== RCS file: /cvsroot/valgrind/valgrind/Makefile.am,v retrieving revision 1.40 diff -u -3 -p -r1.40 Makefile.am --- Makefile.am 1 Mar 2003 01:26:55 -0000 1.40 +++ Makefile.am 18 Mar 2003 19:13:36 -0000 @@ -1,5 +1,5 @@ -AUTOMAKE_OPTIONS = 1.5 +AUTOMAKE_OPTIONS = 1.4-p2 SUBDIRS = coregrind . docs tests include auxprogs \ addrcheck \ Index: addrcheck/ac_main.c =================================================================== RCS file: /cvsroot/valgrind/valgrind/addrcheck/ac_main.c,v retrieving revision 1.29 diff -u -3 -p -r1.29 ac_main.c --- addrcheck/ac_main.c 17 Feb 2003 10:09:19 -0000 1.29 +++ addrcheck/ac_main.c 18 Mar 2003 19:13:37 -0000 @@ -1153,7 +1153,8 @@ static void ac_detect_memory_leaks ( voi MC_(get_where), MC_(clo_leak_resolution), MC_(clo_show_reachable), - (UInt)LeakSupp + (UInt)LeakSupp, + (UInt)LeakErr ); } Index: coregrind/vg_default.c =================================================================== RCS file: /cvsroot/valgrind/valgrind/coregrind/vg_default.c,v retrieving revision 1.9 diff -u -3 -p -r1.9 vg_default.c --- coregrind/vg_default.c 14 Nov 2002 12:42:44 -0000 1.9 +++ coregrind/vg_default.c 18 Mar 2003 19:13:38 -0000 @@ -134,6 +134,18 @@ Bool SK_(error_matches_suppression)(Erro non_fund_panic("SK_(error_matches_suppression)"); } +__attribute__ ((weak)) +Char* SK_(get_error_name)(Error* err) +{ + non_fund_panic("SK_(get_error_name)"); +} + +__attribute__ ((weak)) +void SK_(print_extra_suppression_info)(Error* err) +{ + non_fund_panic("SK_(print_extra_suppression_info)"); +} + /* --------------------------------------------------------------------- For throwing out basic block level info when code is invalidated Index: coregrind/vg_errcontext.c =================================================================== RCS file: /cvsroot/valgrind/valgrind/coregrind/vg_errcontext.c,v retrieving revision 1.29 diff -u -3 -p -r1.29 vg_errcontext.c --- coregrind/vg_errcontext.c 28 Jan 2003 19:59:35 -0000 1.29 +++ coregrind/vg_errcontext.c 18 Mar 2003 19:13:38 -0000 @@ -123,13 +123,12 @@ static void pp_Error ( Error* err, Bool /* Figure out if we want to attach for GDB for this error, possibly by asking the user. */ -static -Bool vg_is_GDB_attach_requested ( void ) +Bool VG_(is_action_requested) ( Char* action, Bool* clo ) { Char ch, ch2; Int res; - if (VG_(clo_GDB_attach) == False) + if (*clo == False) return False; VG_(message)(Vg_UserMsg, ""); @@ -137,8 +136,8 @@ Bool vg_is_GDB_attach_requested ( void ) again: VG_(printf)( "==%d== " - "---- Attach to GDB ? --- [Return/N/n/Y/y/C/c] ---- ", - VG_(getpid)() + "---- %s ? --- [Return/N/n/Y/y/C/c] ---- ", + VG_(getpid)(), action ); res = VG_(read)(0 /*stdin*/, &ch, 1); @@ -152,15 +151,15 @@ Bool vg_is_GDB_attach_requested ( void ) if (res != 1) goto ioerror; if (ch2 != '\n') goto again; - /* No, don't want to attach. */ + /* No, don't want to do action. */ if (ch == 'n' || ch == 'N') return False; - /* Yes, want to attach. */ + /* Yes, want to do action. */ if (ch == 'y' || ch == 'Y') return True; - /* No, don't want to attach, and don't ask again either. */ + /* No, don't want to do action, and don't ask again either. */ vg_assert(ch == 'c' || ch == 'C'); ioerror: - VG_(clo_GDB_attach) = False; + *clo = False; return False; } @@ -209,6 +208,48 @@ void construct_error ( Error* err, Threa vg_assert(err->tid >= 0 && err->tid < VG_N_THREADS); } +void VG_(gen_suppression)(Error* err) +{ + UInt i; + UChar buf[M_VG_ERRTXT]; + ExeContext* ec = VG_(get_error_where)(err); + Int stop_at = VG_(clo_backtrace_size); + Char* name = SK_(get_error_name)(err); + + if (NULL == name) { + VG_(message)(Vg_UserMsg, "(error cannot be suppressed by the skin)"); + return; + } + + if (stop_at > 3) stop_at = 3; /* At most three names */ + vg_assert(stop_at > 0); + + VG_(printf)("{\n"); + VG_(printf)(" \n"); + VG_(printf)(" %s:%s\n", VG_(details).name, name); + SK_(print_extra_suppression_info)(err); + + /* This loop condensed from VG_(mini_stack_dump)() */ + i = 0; + do { + Addr eip = ec->eips[i]; + if (i > 0) + eip--; /* point to calling line */ + + if ( VG_(get_fnname_nodemangle) (eip, buf, M_VG_ERRTXT) ) { + VG_(printf)(" fun:%s\n", buf); + } else if ( VG_(get_objname)(eip, buf, M_VG_ERRTXT) ) { + VG_(printf)(" obj:%s\n", buf); + } else { + VG_(printf)(" ???:??? " + "# unknown, suppression will not work, sorry)\n"); + } + i++; + } while (i < stop_at && ec->eips[i] != 0); + + VG_(printf)("}\n"); +} + /* Top-level entry point to the error management subsystem. All detected errors are notified here; this routine decides if/when the user should see the error. */ @@ -337,9 +378,13 @@ void VG_(maybe_record_error) ( ThreadSta is_first_shown_context = False; vg_n_errs_shown++; /* Perhaps we want a GDB attach at this point? */ - if (vg_is_GDB_attach_requested()) { + if (VG_(is_action_requested)( "Attach to GDB", & VG_(clo_GDB_attach) )) { VG_(swizzle_esp_then_start_GDB)( err.m_eip, err.m_esp, err.m_ebp); + } + if (VG_(is_action_requested)( "Print suppression", + & VG_(clo_gen_suppressions) )) { + VG_(gen_suppression)(p); } } else { vg_n_errs_suppressed++; Index: coregrind/vg_include.h =================================================================== RCS file: /cvsroot/valgrind/valgrind/coregrind/vg_include.h,v retrieving revision 1.114 diff -u -3 -p -r1.114 vg_include.h --- coregrind/vg_include.h 15 Mar 2003 20:01:19 -0000 1.114 +++ coregrind/vg_include.h 18 Mar 2003 19:13:38 -0000 @@ -171,6 +171,8 @@ typedef extern Bool VG_(clo_error_limit); /* Enquire about whether to attach to GDB at errors? default: NO */ extern Bool VG_(clo_GDB_attach); +/* Enquire about generating a suppression for each error? default: NO */ +extern Bool VG_(clo_gen_suppressions); /* Sanity-check level: 0 = none, 1 (default), > 1 = expensive. */ extern Int VG_(sanity_level); /* Automatically attempt to demangle C++ names? default: YES */ @@ -1206,6 +1208,9 @@ extern void VG_(get_objname_fnname) ( Ad make it global. */ extern Supp* VG_(get_suppressions) ( void ); +extern Bool VG_(is_action_requested) ( Char* action, Bool* clo ); + +extern void VG_(gen_suppression) ( Error* err ); /* --------------------------------------------------------------------- Exports of vg_procselfmaps.c Index: coregrind/vg_main.c =================================================================== RCS file: /cvsroot/valgrind/valgrind/coregrind/vg_main.c,v retrieving revision 1.77 diff -u -3 -p -r1.77 vg_main.c --- coregrind/vg_main.c 24 Feb 2003 10:21:45 -0000 1.77 +++ coregrind/vg_main.c 18 Mar 2003 19:13:38 -0000 @@ -457,6 +457,7 @@ UInt VG_(num_scheduling_events_MAJOR) = /* Define, and set defaults. */ Bool VG_(clo_error_limit) = True; Bool VG_(clo_GDB_attach) = False; +Bool VG_(clo_gen_suppressions) = False; Int VG_(sanity_level) = 1; Int VG_(clo_verbosity) = 1; Bool VG_(clo_demangle) = True; @@ -553,6 +554,7 @@ static void usage ( void ) " -q --quiet run silently; only print error msgs\n" " -v --verbose be more verbose, incl counts of errors\n" " --gdb-attach=no|yes start GDB when errors detected? [no]\n" +" --gen-suppressions=no|yes print suppressions for errors detected [no]\n" " --demangle=no|yes automatically demangle C++ names? [yes]\n" " --num-callers= show callers in stack traces [4]\n" " --error-limit=no|yes stop showing new errors if too many? [yes]\n" @@ -830,6 +832,11 @@ static void process_cmd_line_options ( v VG_(clo_GDB_attach) = True; else if (STREQ(argv[i], "--gdb-attach=no")) VG_(clo_GDB_attach) = False; + + else if (STREQ(argv[i], "--gen-suppressions=yes")) + VG_(clo_gen_suppressions) = True; + else if (STREQ(argv[i], "--gen-suppressions=no")) + VG_(clo_gen_suppressions) = False; else if (STREQ(argv[i], "--demangle=yes")) VG_(clo_demangle) = True; Index: coregrind/vg_memory.c =================================================================== RCS file: /cvsroot/valgrind/valgrind/coregrind/vg_memory.c,v retrieving revision 1.32 diff -u -3 -p -r1.32 vg_memory.c --- coregrind/vg_memory.c 15 Mar 2003 20:01:21 -0000 1.32 +++ coregrind/vg_memory.c 18 Mar 2003 19:13:38 -0000 @@ -797,7 +797,7 @@ Bool leaksupp_matches_callers(Supp* su, skin-specific value. */ static Bool is_suppressible_leak ( ExeContext* allocated_at, - UInt /*CoreErrorKind*/ leakSupp ) + UInt /*CoreSuppKind*/ leakSupp ) { Int i; @@ -824,7 +824,7 @@ Bool is_suppressible_leak ( ExeContext* /* See if the leak record any suppression. */ for (su = VG_(get_suppressions)(); su != NULL; su = su->next) { - if (VG_(get_supp_kind)(su) == (CoreErrorKind)leakSupp + if (VG_(get_supp_kind)(su) == (CoreSuppKind)leakSupp && leaksupp_matches_callers(su, caller_obj, caller_fun)) { return True; } @@ -847,7 +847,8 @@ void VG_(generic_detect_memory_leaks) ( ExeContext* get_where ( ShadowChunk* ), VgRes leak_resolution, Bool show_reachable, - UInt /*CoreErrorKind*/ leakSupp + UInt /*CoreSuppKind*/ leakSupp, + UInt /*CoreErrKind*/ leakErr ) { Int i; @@ -998,6 +999,21 @@ void VG_(generic_detect_memory_leaks) ( ); VG_(pp_ExeContext)(p_min->allocated_at); p_min->num_blocks = 0; + + /* Hack alert: because we don't deal with Error structs for leak errors, + we have to fake one up if generating the suppression. We only + fill in the necessary fields. Yuk. */ + if (VG_(is_action_requested)( "Print suppression", + & VG_(clo_gen_suppressions) )) { + Error fake_error; + fake_error.where = p_min->allocated_at; + fake_error.ekind = leakErr; + fake_error.addr = 0x0; + fake_error.string = NULL; + fake_error.extra = NULL; + + VG_(gen_suppression)( & fake_error ); + } } VG_(message)(Vg_UserMsg, ""); Index: coregrind/vg_symtab2.c =================================================================== RCS file: /cvsroot/valgrind/valgrind/coregrind/vg_symtab2.c,v retrieving revision 1.36 diff -u -3 -p -r1.36 vg_symtab2.c --- coregrind/vg_symtab2.c 28 Jan 2003 20:40:55 -0000 1.36 +++ coregrind/vg_symtab2.c 18 Mar 2003 19:13:38 -0000 @@ -2238,7 +2238,6 @@ Bool VG_(get_filename_linenum)( Addr a, return True; } - /* Print a mini stack dump, showing the current location. */ void VG_(mini_stack_dump) ( ExeContext* ec ) { @@ -2272,10 +2271,9 @@ void VG_(mini_stack_dump) ( ExeContext* n = 0; if (i > 0) eip--; /* point to calling line */ - know_fnname = get_fnname (True, eip, buf_fn, M_VG_ERRTXT, True, False); + know_fnname = VG_(get_fnname) (eip, buf_fn, M_VG_ERRTXT); know_objname = VG_(get_objname)(eip, buf_obj, M_VG_ERRTXT); - know_srcloc = VG_(get_filename_linenum)(eip, - buf_srcloc, M_VG_ERRTXT, + know_srcloc = VG_(get_filename_linenum)(eip, buf_srcloc, M_VG_ERRTXT, &lineno); if (i == 0) APPEND(" at ") else APPEND(" by "); Index: coregrind/docs/coregrind_core.html =================================================================== RCS file: /cvsroot/valgrind/valgrind/coregrind/docs/coregrind_core.html,v retrieving revision 1.2 diff -u -3 -p -r1.2 coregrind_core.html --- coregrind/docs/coregrind_core.html 18 Nov 2002 00:07:28 -0000 1.2 +++ coregrind/docs/coregrind_core.html 18 Mar 2003 19:13:38 -0000 @@ -72,7 +72,10 @@ interested, Valgrind allows you to selec recording them in a suppressions file which is read when Valgrind starts up. The build mechanism attempts to select suppressions which give reasonable behaviour for the libc and XFree86 versions detected -on your machine. +on your machine. To make it easier to write suppressions, you can use +the --gen-suppressions=yes option which tells Valgrind to +print out a suppression for each error that appears, which you can +then copy into a suppressions file.

Different skins report different kinds of errors. The suppression @@ -189,7 +192,7 @@ does about where that stream is sent to. for technical reasons, valgrind's core itself can't use the GNU C library, and this makes it difficult to do hostname-to-IP lookups.

- Writing to a network socket it pretty useless if you don't have + Writing to a network socket is pretty useless if you don't have something listening at the other end. We provide a simple listener program, valgrind-listener, which accepts connections on the specified port and copies whatever it is sent @@ -453,6 +456,31 @@ follows: socket, I guess this option doesn't make any sense. Caveat emptor.

+

  • --gen-suppressions=no [the default]
    + --gen-suppressions=yes +

    When enabled, Valgrind will pause after every error shown, + and print the line +
    + ---- Print suppression ? --- [Return/N/n/Y/y/C/c] ---- +

    + The prompt's behaviour is the same as for the --gdb-attach + option. +

    + If you choose to, Valgrind will print out a suppression for this error. + You can then cut and paste it into a suppression file if you don't want + to hear about the error in the future. +

    + This option is particularly useful with C++ programs, as it prints out + the suppressions with mangled names, as required. +

    + Note that the suppressions printed are as specific as possible. You + may want to common up similar ones, eg. by adding wildcards to function + names. Also, sometimes two different errors are suppressed by the same + suppression, in which case Valgrind will output the suppression more than + once, but you only need to have one copy in your suppression file (but + having more than one won't cause problems). +


  • +

  • --alignment=<number> [default: 4]

    By default valgrind's malloc, realloc, etc, return 4-byte aligned addresses. These are suitable for @@ -620,6 +648,12 @@ follows: unexpectedly in the write() system call, you may find the --trace-syscalls=yes --trace-sched=yes flags useful. +

    +

  • lax-ioctls Be very lax about ioctl handling; the only + assumption is that the size is correct. Doesn't require the full + buffer to be initialized when writing. Without this, using some + device drivers with a large number of strange ioctl commands becomes + very tiresome.

  • @@ -685,6 +719,13 @@ shouldn't need to use them in the normal

    +

  • --trace-codegen=XXXXX [default: 00000] +

    Enable/disable tracing of code generation. Code can be printed + at five different stages of translation; each X element + must be 0 or 1. +


  • +

    +

  • --stop-after=<number> [default: infinity, more or less]

    After <number> basic blocks have been executed, shut down @@ -707,7 +748,12 @@ shouldn't need to use them in the normal

    2.7  The Client Request mechanism

    (NOTE 20021117: this subsection is illogical here now; it jumbles up -core and skin issues. To be fixed.). +core and skin issues. To be fixed.) + +(NOTE 20030318: the most important correction is that +valgrind.h should not be included in your program, but +instead memcheck.h (for the Memcheck and Addrcheck skins) +or helgrind.h (for Helgrind).)

    Valgrind has a trapdoor mechanism via which the client program can @@ -927,7 +973,7 @@ build problems.

    2.11  If you have problems

    Mail me (jseward@acm.org). -

    See Section 4 for the known limitations of +

    See this section for the known limitations of Valgrind, and for a list of programs which are known not to work on it. Index: helgrind/hg_main.c =================================================================== RCS file: /cvsroot/valgrind/valgrind/helgrind/hg_main.c,v retrieving revision 1.45 diff -u -3 -p -r1.45 hg_main.c --- helgrind/hg_main.c 15 Dec 2002 02:00:41 -0000 1.45 +++ helgrind/hg_main.c 18 Mar 2003 19:13:39 -0000 @@ -2609,6 +2609,19 @@ Bool SK_(error_matches_suppression)(Erro return True; } +extern Char* SK_(get_error_name) ( Error* err ) +{ + if (EraserErr == VG_(get_error_kind)(err)) { + return "Eraser"; + } else { + return NULL; /* Other errors types can't be suppressed */ + } +} + +extern void SK_(print_extra_suppression_info) ( Error* err ) +{ + /* Do nothing */ +} static void eraser_pre_mutex_lock(ThreadId tid, void* void_mutex) { Index: include/vg_skin.h =================================================================== RCS file: /cvsroot/valgrind/valgrind/include/vg_skin.h,v retrieving revision 1.48 diff -u -3 -p -r1.48 vg_skin.h --- include/vg_skin.h 24 Feb 2003 10:49:07 -0000 1.48 +++ include/vg_skin.h 18 Mar 2003 19:13:39 -0000 @@ -1271,7 +1271,8 @@ extern void VG_(generic_detect_memory_le ExeContext* get_where ( ShadowChunk* ), VgRes leak_resolution, Bool show_reachable, - UInt /*CoreErrorKind*/ leakSupp + UInt /*CoreSuppKind*/ leakSupp, + UInt /*CoreErrorKind*/ leakErr ); @@ -1556,8 +1557,15 @@ extern Bool SK_(read_extra_suppression_i /* This should just check the kinds match and maybe some stuff in the `string' and `extra' field if appropriate (using VG_(get_supp_*)() to get the relevant suppression parts). */ -extern Bool SK_(error_matches_suppression)(Error* err, Supp* su); +extern Bool SK_(error_matches_suppression) ( Error* err, Supp* su ); +/* This should return the suppression name, for --gen-suppressions, or NULL + if that error type cannot be suppressed. */ +extern Char* SK_(get_error_name) ( Error* err ); + +/* This should print any extra info for the error, for --gen-suppressions, + including the newline. */ +extern void SK_(print_extra_suppression_info) ( Error* err ); /* ------------------------------------------------------------------ */ /* VG_(needs).basic_block_discards */ Index: memcheck/mc_common.c =================================================================== RCS file: /cvsroot/valgrind/valgrind/memcheck/mc_common.c,v retrieving revision 1.6 diff -u -3 -p -r1.6 mc_common.c --- memcheck/mc_common.c 28 Dec 2002 12:55:48 -0000 1.6 +++ memcheck/mc_common.c 18 Mar 2003 19:13:39 -0000 @@ -417,6 +417,46 @@ Bool SK_(error_matches_suppression)(Erro # undef STREQ +Char* SK_(get_error_name) ( Error* err ) +{ + Char* s; + switch (VG_(get_error_kind)(err)) { + case ParamErr: return "Param"; + case UserErr: return NULL; /* Can't suppress User errors */ + case FreeMismatchErr: return "Free"; + case FreeErr: return "Free"; + case AddrErr: + switch ( ((MemCheckError*)VG_(get_error_extra)(err))->size ) { + case 1: return "Addr1"; + case 2: return "Addr2"; + case 4: return "Addr4"; + case 8: return "Addr8"; + default: VG_(skin_panic)("unexpected size for Addr"); + } + + case ValueErr: + switch ( ((MemCheckError*)VG_(get_error_extra)(err))->size ) { + case 0: return "Cond"; + case 1: return "Value1"; + case 2: return "Value2"; + case 4: return "Value4"; + case 8: return "Value8"; + default: VG_(skin_panic)("unexpected size for Value"); + } + case CoreMemErr: return "CoreMem"; + case LeakErr: return "Leak"; + default: VG_(skin_panic)("get_error_name: unexpected type"); + } + VG_(printf)(s); +} + +void SK_(print_extra_suppression_info) ( Error* err ) +{ + if (ParamErr == VG_(get_error_kind)(err)) { + VG_(printf)(" %s\n", VG_(get_error_string)(err)); + } +} + /*------------------------------------------------------------*/ /*--- Crude profiling machinery. ---*/ /*------------------------------------------------------------*/ Index: memcheck/mc_common.h =================================================================== RCS file: /cvsroot/valgrind/valgrind/memcheck/mc_common.h,v retrieving revision 1.4 diff -u -3 -p -r1.4 mc_common.h --- memcheck/mc_common.h 28 Dec 2002 12:55:48 -0000 1.4 +++ memcheck/mc_common.h 18 Mar 2003 19:13:39 -0000 @@ -87,7 +87,8 @@ typedef CoreMemErr, AddrErr, ParamErr, UserErr, /* behaves like an anonymous ParamErr */ - FreeErr, FreeMismatchErr + FreeErr, FreeMismatchErr, + LeakErr } MemCheckErrorKind; Index: memcheck/mc_main.c =================================================================== RCS file: /cvsroot/valgrind/valgrind/memcheck/mc_main.c,v retrieving revision 1.26 diff -u -3 -p -r1.26 mc_main.c --- memcheck/mc_main.c 26 Dec 2002 01:53:45 -0000 1.26 +++ memcheck/mc_main.c 18 Mar 2003 19:13:39 -0000 @@ -1332,7 +1332,8 @@ void MC_(detect_memory_leaks) ( void ) MC_(get_where), MC_(clo_leak_resolution), MC_(clo_show_reachable), - (UInt)LeakSupp + (UInt)LeakSupp, + (UInt)LeakErr ); } Index: memcheck/docs/mc_main.html =================================================================== RCS file: /cvsroot/valgrind/valgrind/memcheck/docs/mc_main.html,v retrieving revision 1.3 diff -u -3 -p -r1.3 mc_main.html --- memcheck/docs/mc_main.html 16 Mar 2003 01:12:16 -0000 1.3 +++ memcheck/docs/mc_main.html 18 Mar 2003 19:13:39 -0000 @@ -138,7 +138,7 @@ Memcheck is Valgrind-1.0.X checking mech -

    3.3  Explaination of error messages from Memcheck

    +

    3.3  Explanation of error messages from Memcheck

    Despite considerable sophistication under the hood, Memcheck can only really detect two kinds of errors, use of illegal addresses, and use @@ -146,7 +146,7 @@ of undefined values. Nevertheless, this discover all sorts of memory-management nasties in your code. This section presents a quick summary of what error messages mean. The precise behaviour of the error-checking machinery is described in -Section 4. +this section.

    3.3.1  Illegal read / Illegal write errors