]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Support for xtree memory profiling and xtmemory gdbsrv monitor command in memcheck
authorPhilippe Waroquiers <philippe.waroquiers@skynet.be>
Fri, 11 Nov 2016 14:36:36 +0000 (14:36 +0000)
committerPhilippe Waroquiers <philippe.waroquiers@skynet.be>
Fri, 11 Nov 2016 14:36:36 +0000 (14:36 +0000)
* memcheck will produce xtree memory profiling according to the options
  --xtree-memory.
* addition of the xtmemory gdbserver monitor command.

(this is the second real xtree functional difference)

git-svn-id: svn://svn.valgrind.org/valgrind/trunk@16128

gdbserver_tests/mchelp.stdoutB.exp
memcheck/mc_include.h
memcheck/mc_main.c
memcheck/mc_malloc_wrappers.c

index 6d6bdb146b443de04e6c242a7a4019a8f397d1a0..742181f2c563264338a8ffba955e2cab0182a8cd 100644 (file)
@@ -52,6 +52,8 @@ memcheck monitor commands:
         shows places pointing inside <len> (default 1) bytes at <addr>
         (with len 1, only shows "start pointers" pointing exactly to <addr>,
          with len > 1, will also show "interior pointers")
+  xtmemory [<filename>]
+        dump xtree memory profile in <filename> (default xtmemory.kcg)
 general valgrind monitor commands:
   help [debug]            : monitor command help. With debug: + debugging commands
   v.wait [<ms>]           : sleep <ms> (default 0) then continue
@@ -121,4 +123,6 @@ memcheck monitor commands:
         shows places pointing inside <len> (default 1) bytes at <addr>
         (with len 1, only shows "start pointers" pointing exactly to <addr>,
          with len > 1, will also show "interior pointers")
+  xtmemory [<filename>]
+        dump xtree memory profile in <filename> (default xtmemory.kcg)
 monitor command request to kill this process
index d36ea0ba1eba4c8fa1e1b34374831a5a3f0bd947..fc2d4b7823d1064f04ddf6cb28820d741de4079d 100644 (file)
@@ -144,6 +144,8 @@ void MC_(make_mem_undefined_w_otag)( Addr a, SizeT len, UInt otag );
 void MC_(make_mem_defined)         ( Addr a, SizeT len );
 void MC_(copy_address_range_state) ( Addr src, Addr dst, SizeT len );
 
+void MC_(xtmemory_report) ( const HChar* filename, Bool fini );
+
 void MC_(print_malloc_stats) ( void );
 /* nr of free operations done */
 SizeT MC_(get_cmalloc_n_frees) ( void );
index 30fa0084e96ff9fb19ea748776da69558b87ecb4..1303b934b402b0db32c4ea4d35f014ab09ab4a3d 100644 (file)
@@ -47,6 +47,9 @@
 #include "pub_tool_replacemalloc.h"
 #include "pub_tool_tooliface.h"
 #include "pub_tool_threadstate.h"
+#include "pub_tool_xarray.h"
+#include "pub_tool_xtree.h"
+#include "pub_tool_xtmemory.h"
 
 #include "mc_include.h"
 #include "memcheck.h"   /* for client requests */
@@ -6400,6 +6403,8 @@ static void print_monitor_help ( void )
 "        shows places pointing inside <len> (default 1) bytes at <addr>\n"
 "        (with len 1, only shows \"start pointers\" pointing exactly to <addr>,\n"
 "         with len > 1, will also show \"interior pointers\")\n"
+"  xtmemory [<filename>]\n"
+"        dump xtree memory profile in <filename> (default xtmemory.kcg)\n"
 "\n");
 }
 
@@ -6515,7 +6520,7 @@ static Bool handle_gdb_monitor_command (ThreadId tid, HChar *req)
       command. This ensures a shorter abbreviation for the user. */
    switch (VG_(keyword_id) 
            ("help get_vbits leak_check make_memory check_memory "
-            "block_list who_points_at xb", 
+            "block_list who_points_at xb xtmemory", 
             wcmd, kwd_report_duplicated_matches)) {
    case -2: /* multiple matches */
       return True;
@@ -6874,6 +6879,13 @@ static Bool handle_gdb_monitor_command (ThreadId tid, HChar *req)
       return True;
    }
 
+   case  8: { /* xtmemory */
+      HChar* filename;
+      filename = VG_(strtok_r) (NULL, " ", &ssaveptr);
+      MC_(xtmemory_report)(filename, False);
+      return True;
+   }
+
    default: 
       tl_assert(0);
       return False;
@@ -7889,6 +7901,17 @@ static void mc_post_clo_init ( void )
    /* Do not check definedness of guest state if --undef-value-errors=no */
    if (MC_(clo_mc_level) >= 2)
       VG_(track_pre_reg_read) ( mc_pre_reg_read );
+
+   if (VG_(clo_xtree_memory) == Vg_XTMemory_Full) {
+      if (MC_(clo_keep_stacktraces) == KS_none
+          || MC_(clo_keep_stacktraces) == KS_free)
+         VG_(fmsg_bad_option)("--keep-stacktraces",
+                              "To use --xtree-memory=full, you must"
+                              " keep at least the alloc stacktrace\n");
+      // Activate full xtree memory profiling.
+      VG_(XTMemory_Full_init)(VG_(XT_filter_1top_and_maybe_below_main));
+   }
+   
 }
 
 static void print_SM_info(const HChar* type, Int n_SMs)
@@ -7997,6 +8020,7 @@ static void mc_print_stats (void)
 
 static void mc_fini ( Int exitcode )
 {
+   MC_(xtmemory_report) (VG_(clo_xtree_memory_file), True);
    MC_(print_malloc_stats)();
 
    if (MC_(clo_leak_check) != LC_Off) {
index f4881785241ff5b1bca5029379889284ee3fffbc..e11fb23850ed13205fb351f4a63e163ac20cfca7 100644 (file)
 #include "pub_tool_libcbase.h"
 #include "pub_tool_libcassert.h"
 #include "pub_tool_libcprint.h"
+#include "pub_tool_libcproc.h"
 #include "pub_tool_mallocfree.h"
 #include "pub_tool_options.h"
 #include "pub_tool_replacemalloc.h"
 #include "pub_tool_threadstate.h"
 #include "pub_tool_tooliface.h"     // Needed for mc_include.h
 #include "pub_tool_stacktrace.h"    // For VG_(get_and_pp_StackTrace)
+#include "pub_tool_xarray.h"
+#include "pub_tool_xtree.h"
+#include "pub_tool_xtmemory.h"
 
 #include "mc_include.h"
 
@@ -303,20 +307,33 @@ void  MC_(set_allocated_at) (ThreadId tid, MC_Chunk* mc)
       default: tl_assert (0);
    }
    mc->where[0] = VG_(record_ExeContext) ( tid, 0/*first_ip_delta*/ );
+   if (UNLIKELY(VG_(clo_xtree_memory) == Vg_XTMemory_Full))
+       VG_(XTMemory_Full_alloc)(mc->szB, mc->where[0]);
 }
 
 void  MC_(set_freed_at) (ThreadId tid, MC_Chunk* mc)
 {
-   UInt pos;
+   Int pos;
+   ExeContext* ec_free;
+
    switch (MC_(clo_keep_stacktraces)) {
       case KS_none:            return;
-      case KS_alloc:           return;
+      case KS_alloc:           pos = -1; break;
       case KS_free:            pos = 0; break;
       case KS_alloc_then_free: pos = 0; break;
       case KS_alloc_and_free:  pos = 1; break;
       default: tl_assert (0);
    }
-   mc->where[pos] = VG_(record_ExeContext) ( tid, 0/*first_ip_delta*/ );
+   /* We need the execontext for the free operation, either to store
+      it in the mc chunk and/or for full xtree memory profiling.
+      Note: we are guaranteed to find the ec_alloc in mc->where[0], as
+      mc_post_clo_init verifies the consistency of --xtree-memory and
+      --keep-stacktraces. */
+   ec_free = VG_(record_ExeContext) ( tid, 0/*first_ip_delta*/ );
+   if (UNLIKELY(VG_(clo_xtree_memory) == Vg_XTMemory_Full))
+       VG_(XTMemory_Full_free)(mc->szB, mc->where[0], ec_free);
+   if (pos >= 0)
+      mc->where[pos] = ec_free;
 }
 
 UInt MC_(n_where_pointers) (void)
@@ -651,6 +668,9 @@ void MC_(handle_resizeInPlace)(ThreadId tid, Addr p,
    if (oldSizeB == newSizeB)
       return;
 
+   if (UNLIKELY(VG_(clo_xtree_memory) == Vg_XTMemory_Full))
+       VG_(XTMemory_Full_resize_in_place)(oldSizeB,  newSizeB, mc->where[0]);
+
    mc->szB = newSizeB;
    if (newSizeB < oldSizeB) {
       MC_(make_mem_noaccess)( p + newSizeB, oldSizeB - newSizeB + rzB );
@@ -1117,6 +1137,25 @@ Bool MC_(mempool_exists)(Addr pool)
    return True;
 }
 
+static void xtmemory_report_next_block(XT_Allocs* xta, ExeContext** ec_alloc)
+{
+   MC_Chunk* mc = VG_(HT_Next)(MC_(malloc_list));
+   if (mc) {
+      xta->nbytes = mc->szB;
+      xta->nblocks = 1;
+      *ec_alloc = MC_(allocated_at)(mc);
+   } else
+      xta->nblocks = 0;
+}
+
+void MC_(xtmemory_report) ( const HChar* filename, Bool fini )
+{ 
+   // Make xtmemory_report_next_block ready to be called.
+   VG_(HT_ResetIter)(MC_(malloc_list));
+
+   VG_(XTMemory_report)(filename, fini, xtmemory_report_next_block,
+                        VG_(XT_filter_1top_and_maybe_below_main));
+}
 
 /*------------------------------------------------------------*/
 /*--- Statistics printing                                  ---*/