This commit moves some skin-specific stuff out of core, and generally
neatens other things up.

Also, it adds the --gen-suppressions option for automatically generating
suppressions for each error.

Note that it changes the core/skin interface:
SK_(dup_extra_and_update)() is replaced by SK_(update_extra)(), and
SK_(get_error_name)() and SK_(print_extra_suppression_info)() are added.


-----------------------------------------------------------------------------
details
-----------------------------------------------------------------------------
Removed ac_common.c -- it just #included another .c file;  moved the
#include into ac_main.c.

Introduced "mac_" prefixes for files shared between Addrcheck and Memcheck,
to make it clearer which code is shared.  Also using a "MAC_" prefix for
functions and variables and types that are shared.  Addrcheck doesn't see
the "MC_" prefix at all.

Factored out almost-identical mc_describe_addr() and describe_addr()
(AddrCheck's version) into MAC_(describe_addr)().

Got rid of the "pp_ExeContext" closure passed to SK_(pp_SkinError)(), it
wasn't really necessary.

Introduced MAC_(pp_shared_SkinError)() for the error printing code shared by
Addrcheck and Memcheck.  Fixed some bogus stuff in Addrcheck error messages
about "uninitialised bytes" (there because of an imperfect conversion from
Memcheck).

Moved the leak checker out of core (vg_memory.c), into mac_leakcheck.c.
 - This meant the hacky way of recording Leak errors, which was different to
   normal errors, could be changed to something better:  introduced a
   function VG_(unique_error)(), which unlike VG_(maybe_record_error)() just
   prints the error (unless suppressed) but doesn't record it.  Used for
   leaks;  a much better solution all round as it allowed me to remove a lot
   of almost-identical code from leak handling (is_suppressible_leak(),
   leaksupp_matches_callers()).

 - As part of this, changed the horrible SK_(dup_extra_and_update) into the
   slightly less horrible SK_(update_extra), which returns the size of the
   `extra' part for the core to duplicate.

 - Also renamed it from VG_(generic_detect_memory_leaks)() to
   MAC_(do_detect_memory_leaks).  In making the code nicer w.r.t suppressions
   and error reporting, I tied it a bit more closely to Memcheck/Addrcheck,
   and got rid of some of the args.  It's not really "generic" any more, but
   then it never really was.  (This could be undone, but there doesn't seem
   to be much point.)

STREQ and STREQN were #defined in several places, and in two different ways.
Made global macros VG_STREQ, VG_CLO_STREQ and VG_CLO_STREQN in vg_skin.h.

Added the --gen-suppressions code.  This required adding the functions
SK_(get_error_name)() and SK_(print_extra_suppression_info)() for skins that
use the error handling need.

Added documentation for --gen-suppressions, and fixed some other minor document
problems.

Various other minor related changes too.


git-svn-id: svn://svn.valgrind.org/valgrind/trunk@1517 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/memcheck/mc_main.c b/memcheck/mc_main.c
index c5d9ef0..46ae522 100644
--- a/memcheck/mc_main.c
+++ b/memcheck/mc_main.c
@@ -586,12 +586,12 @@
    if (!ok) {
       switch (part) {
       case Vg_CoreSysCall:
-         MC_(record_param_error) ( tst, bad_addr, /*isWrite =*/True, s );
+         MAC_(record_param_error) ( tst, bad_addr, /*isWrite =*/True, s );
          break;
 
       case Vg_CorePThread:
       case Vg_CoreSignal:
-         MC_(record_core_mem_error)( tst, /*isWrite=*/True, s );
+         MAC_(record_core_mem_error)( tst, /*isWrite=*/True, s );
          break;
 
       default:
@@ -617,17 +617,17 @@
    if (!ok) {
       switch (part) {
       case Vg_CoreSysCall:
-         MC_(record_param_error) ( tst, bad_addr, /*isWrite =*/False, s );
+         MAC_(record_param_error) ( tst, bad_addr, /*isWrite =*/False, s );
          break;
       
       case Vg_CorePThread:
-         MC_(record_core_mem_error)( tst, /*isWrite=*/False, s );
+         MAC_(record_core_mem_error)( tst, /*isWrite=*/False, s );
          break;
 
       /* 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)( tst, bad_addr );
+         MAC_(record_jump_error)( tst, bad_addr );
          break;
 
       default:
@@ -650,7 +650,7 @@
    sk_assert(part == Vg_CoreSysCall);
    ok = mc_check_readable_asciiz ( (Addr)str, &bad_addr );
    if (!ok) {
-      MC_(record_param_error) ( tst, bad_addr, /*is_writable =*/False, s );
+      MAC_(record_param_error) ( tst, bad_addr, /*is_writable =*/False, s );
    }
 
    VGP_POPCC(VgpCheckMem);
@@ -897,10 +897,10 @@
       error arose in the first place from an invalid address. 
    */
    /* VG_(printf)("%p (%d %d %d %d)\n", a, a0ok, a1ok, a2ok, a3ok); */
-   if (!MC_(clo_partial_loads_ok) 
+   if (!MAC_(clo_partial_loads_ok) 
        || ((a & 3) != 0)
        || (!a0ok && !a1ok && !a2ok && !a3ok)) {
-      MC_(record_address_error)( a, 4, False );
+      MAC_(record_address_error)( a, 4, False );
       return (VGM_BYTE_VALID << 24) | (VGM_BYTE_VALID << 16) 
              | (VGM_BYTE_VALID << 8) | VGM_BYTE_VALID;
    }
@@ -913,7 +913,7 @@
       (which is the default), and the address is 4-aligned.  
       If not, Case 2 will have applied.
    */
-   sk_assert(MC_(clo_partial_loads_ok));
+   sk_assert(MAC_(clo_partial_loads_ok));
    {
       UInt vw = VGM_WORD_INVALID;
       vw <<= 8; vw |= (a3ok ? vb3 : VGM_BYTE_INVALID);
@@ -943,7 +943,7 @@
 
    /* If an address error has happened, report it. */
    if (aerr)
-      MC_(record_address_error)( a, 4, True );
+      MAC_(record_address_error)( a, 4, True );
 }
 
 static UInt mc_rd_V2_SLOWLY ( Addr a )
@@ -962,7 +962,7 @@
 
    /* If an address error has happened, report it. */
    if (aerr) {
-      MC_(record_address_error)( a, 2, False );
+      MAC_(record_address_error)( a, 2, False );
       vw = (VGM_BYTE_INVALID << 24) | (VGM_BYTE_INVALID << 16) 
            | (VGM_BYTE_VALID << 8) | (VGM_BYTE_VALID);
    }
@@ -984,7 +984,7 @@
 
    /* If an address error has happened, report it. */
    if (aerr)
-      MC_(record_address_error)( a, 2, True );
+      MAC_(record_address_error)( a, 2, True );
 }
 
 static UInt mc_rd_V1_SLOWLY ( Addr a )
@@ -1001,7 +1001,7 @@
 
    /* If an address error has happened, report it. */
    if (aerr) {
-      MC_(record_address_error)( a, 1, False );
+      MAC_(record_address_error)( a, 1, False );
       vw = (VGM_BYTE_INVALID << 24) | (VGM_BYTE_INVALID << 16) 
            | (VGM_BYTE_INVALID << 8) | (VGM_BYTE_VALID);
    }
@@ -1020,7 +1020,7 @@
 
    /* If an address error has happened, report it. */
    if (aerr)
-      MC_(record_address_error)( a, 1, True );
+      MAC_(record_address_error)( a, 1, True );
 }
 
 
@@ -1250,7 +1250,7 @@
    }
 
    if (aerr) {
-      MC_(record_address_error)( addr, size, False );
+      MAC_(record_address_error)( addr, size, False );
    } else {
      if (verr)
         MC_(record_value_error)( size );
@@ -1280,7 +1280,7 @@
       }
    }
    if (aerr) {
-      MC_(record_address_error)( addr, size, True );
+      MAC_(record_address_error)( addr, size, True );
    }
 }
 
@@ -1329,14 +1329,7 @@
    skin. */
 void MC_(detect_memory_leaks) ( void )
 {
-   VG_(generic_detect_memory_leaks) ( 
-      mc_is_valid_64k_chunk,
-      mc_is_valid_address,
-      MC_(get_where),
-      MC_(clo_leak_resolution),
-      MC_(clo_show_reachable),
-      (UInt)LeakSupp
-   );
+   MAC_(do_detect_memory_leaks) ( mc_is_valid_64k_chunk, mc_is_valid_address );
 }
 
 
@@ -1489,23 +1482,25 @@
    *eflags_value  = VGM_EFLAGS_VALID;
 }
 
+Bool  MC_(clo_avoid_strlen_errors)    = True;
+Bool  MC_(clo_cleanup)                = True;
+
 Bool SK_(process_cmd_line_option)(Char* arg)
 {
-#  define STREQ(s1,s2)     (0==VG_(strcmp_ws)((s1),(s2)))
-#  define STREQN(nn,s1,s2) (0==VG_(strncmp_ws)((s1),(s2),(nn)))
-
-   if (STREQ(arg, "--avoid-strlen-errors=yes"))
+   if (VG_CLO_STREQ(arg, "--avoid-strlen-errors=yes"))
       MC_(clo_avoid_strlen_errors) = True;
-   else if (STREQ(arg, "--avoid-strlen-errors=no"))
+   else if (VG_CLO_STREQ(arg, "--avoid-strlen-errors=no"))
       MC_(clo_avoid_strlen_errors) = False;
 
+   else if (VG_CLO_STREQ(arg, "--cleanup=yes"))
+      MC_(clo_cleanup) = True;
+   else if (VG_CLO_STREQ(arg, "--cleanup=no"))
+      MC_(clo_cleanup) = False;
+
    else
-      return MC_(process_common_cmd_line_option)(arg);
+      return MAC_(process_common_cmd_line_option)(arg);
 
    return True;
-
-#undef STREQ
-#undef STREQN
 }
 
 Char* SK_(usage)(void)
@@ -1556,12 +1551,12 @@
    VG_(track_new_mem_brk)          ( & MC_(make_writable) );
    VG_(track_new_mem_mmap)         ( & mc_set_perms );
    
-   VG_(track_new_mem_stack_4)      ( & MC_(new_mem_stack_4)  );
-   VG_(track_new_mem_stack_8)      ( & MC_(new_mem_stack_8)  );
-   VG_(track_new_mem_stack_12)     ( & MC_(new_mem_stack_12) );
-   VG_(track_new_mem_stack_16)     ( & MC_(new_mem_stack_16) );
-   VG_(track_new_mem_stack_32)     ( & MC_(new_mem_stack_32) );
-   VG_(track_new_mem_stack)        ( & MC_(new_mem_stack)    );
+   VG_(track_new_mem_stack_4)      ( & MAC_(new_mem_stack_4)  );
+   VG_(track_new_mem_stack_8)      ( & MAC_(new_mem_stack_8)  );
+   VG_(track_new_mem_stack_12)     ( & MAC_(new_mem_stack_12) );
+   VG_(track_new_mem_stack_16)     ( & MAC_(new_mem_stack_16) );
+   VG_(track_new_mem_stack_32)     ( & MAC_(new_mem_stack_32) );
+   VG_(track_new_mem_stack)        ( & MAC_(new_mem_stack)    );
 
    VG_(track_copy_mem_heap)        ( & mc_copy_address_range_state );
    VG_(track_copy_mem_remap)       ( & mc_copy_address_range_state );
@@ -1575,15 +1570,15 @@
    VG_(track_die_mem_brk)          ( & MC_(make_noaccess) );
    VG_(track_die_mem_munmap)       ( & MC_(make_noaccess) ); 
 
-   VG_(track_die_mem_stack_4)      ( & MC_(die_mem_stack_4)  );
-   VG_(track_die_mem_stack_8)      ( & MC_(die_mem_stack_8)  );
-   VG_(track_die_mem_stack_12)     ( & MC_(die_mem_stack_12) );
-   VG_(track_die_mem_stack_16)     ( & MC_(die_mem_stack_16) );
-   VG_(track_die_mem_stack_32)     ( & MC_(die_mem_stack_32) );
-   VG_(track_die_mem_stack)        ( & MC_(die_mem_stack)    );
+   VG_(track_die_mem_stack_4)      ( & MAC_(die_mem_stack_4)  );
+   VG_(track_die_mem_stack_8)      ( & MAC_(die_mem_stack_8)  );
+   VG_(track_die_mem_stack_12)     ( & MAC_(die_mem_stack_12) );
+   VG_(track_die_mem_stack_16)     ( & MAC_(die_mem_stack_16) );
+   VG_(track_die_mem_stack_32)     ( & MAC_(die_mem_stack_32) );
+   VG_(track_die_mem_stack)        ( & MAC_(die_mem_stack)    );
    
-   VG_(track_bad_free)             ( & MC_(record_free_error) );
-   VG_(track_mismatched_free)      ( & MC_(record_freemismatch_error) );
+   VG_(track_bad_free)             ( & MAC_(record_free_error) );
+   VG_(track_mismatched_free)      ( & MAC_(record_freemismatch_error) );
 
    VG_(track_pre_mem_read)         ( & mc_check_is_readable );
    VG_(track_pre_mem_read_asciiz)  ( & mc_check_is_readable_asciiz );
@@ -1610,8 +1605,11 @@
    VGP_(register_profile_event) ( VgpCheckMem, "check-mem-perms" );
    VGP_(register_profile_event) ( VgpESPAdj,   "adjust-ESP" );
 
+   /* Additional block description for VG_(describe_addr)() */
+   MAC_(describe_addr_supp) = MC_(client_perm_maybe_describe);
+
    init_shadow_memory();
-   MC_(init_prof_mem)();
+   MAC_(init_prof_mem)();
 }
 
 void SK_(post_clo_init) ( void )
@@ -1623,16 +1621,16 @@
    VG_(print_malloc_stats)();
 
    if (VG_(clo_verbosity) == 1) {
-      if (!MC_(clo_leak_check))
+      if (!MAC_(clo_leak_check))
          VG_(message)(Vg_UserMsg, 
              "For a detailed leak analysis,  rerun with: --leak-check=yes");
 
       VG_(message)(Vg_UserMsg, 
                    "For counts of detected errors, rerun with: -v");
    }
-   if (MC_(clo_leak_check)) MC_(detect_memory_leaks)();
+   if (MAC_(clo_leak_check)) MC_(detect_memory_leaks)();
 
-   MC_(done_prof_mem)();
+   MAC_(done_prof_mem)();
 
    if (0) {
       VG_(message)(Vg_DebugMsg,