|
From: <sv...@va...> - 2013-01-10 20:43:00
|
philippe 2013-01-10 20:42:51 +0000 (Thu, 10 Jan 2013)
New Revision: 13220
Log:
Addition of GDB server monitor command 'v.info execontext' that shows
information about the stack traces recorded by Valgrind.
This can be used to analyse one possible cause of Valgrind high
memory usage for some programs.
At work, a big set of regression tests crashed out of memory under Valgrind.
Two main causes for out of memory were identified:
1. big memory usage for stacktrace (exe contexts) recording by Valgrind
2. big number of partially initialised bytes.
This patch adds a gdbsrv monitor command that output (very) detailed
information about all the recorded exe context.
This has been used to analyse the problem 1. above,
showing the following identified causes for a (too) big nr of execontexts:
A. When the JIT handles an unknown SP update, even when --track-origins=no,
an execontext is (uselessly) created and recorded
to track the (never used) origin of some uninitialised stack memory.
This creates a whole bunch of 'one IP' execontexts.
B. same problem in handling some system calls (at least the brk system
calls always records an origin, even when --track-origins=yes).
C. The Valgrind unwinder cannot properly unwind some stack traces.
It unwinds a few frames, then go bezerk and stops at a "random" IP.
This then causes the same "logical" stacktrace to be truncated
and records thousands of times with this "differentiating" last IP.
For problem cause 2 above ( a lot of partially initialised bytes),
the idea is to similarly add another gdbsrv commands that will output
statistics about which stack traces are causing a lot of uninitialised bytes.
Modified files:
trunk/NEWS
trunk/coregrind/m_execontext.c
trunk/coregrind/m_gdbserver/server.c
trunk/coregrind/m_main.c
trunk/coregrind/pub_core_execontext.h
trunk/docs/xml/manual-core-adv.xml
Modified: trunk/docs/xml/manual-core-adv.xml (+13 -0)
===================================================================
--- trunk/docs/xml/manual-core-adv.xml 2013-01-10 15:44:28 +00:00 (rev 13219)
+++ trunk/docs/xml/manual-core-adv.xml 2013-01-10 20:42:51 +00:00 (rev 13220)
@@ -1363,6 +1363,19 @@
</listitem>
<listitem>
+ <para><varname>v.info exectxt</varname> shows informations about
+ the "executable contexts" (i.e. the stack traces) recorded by
+ Valgrind. For some programs, Valgrind can record a very high
+ number of such stack traces, causing a high memory usage. This
+ monitor command shows all the recorded stack traces, followed by
+ some statistics. This can be used to analyse the reason for having
+ a big number of stack traces. Typically, you will use this command
+ if <varname>v.info memory</varname> has shown significant memory
+ usage by the "exectxt" arena.
+ </para>
+ </listitem>
+
+ <listitem>
<para><varname>v.info scheduler</varname> shows the state and
stack trace for all threads, as known by Valgrind. This allows to
compare the stack traces produced by the Valgrind unwinder with
Modified: trunk/coregrind/pub_core_execontext.h (+2 -1)
===================================================================
--- trunk/coregrind/pub_core_execontext.h 2013-01-10 15:44:28 +00:00 (rev 13219)
+++ trunk/coregrind/pub_core_execontext.h 2013-01-10 20:42:51 +00:00 (rev 13220)
@@ -44,7 +44,8 @@
#define VG_DEEPEST_BACKTRACE 500
// Print stats (informational only).
-extern void VG_(print_ExeContext_stats) ( void );
+// If with_stacktraces, outputs all the recorded stacktraces.
+extern void VG_(print_ExeContext_stats) ( Bool with_stacktraces );
// Extract the StackTrace from an ExeContext.
// (Minor hack: we use Addr* as the return type instead of StackTrace so
Modified: trunk/coregrind/m_main.c (+1 -1)
===================================================================
--- trunk/coregrind/m_main.c 2013-01-10 15:44:28 +00:00 (rev 13219)
+++ trunk/coregrind/m_main.c 2013-01-10 20:42:51 +00:00 (rev 13220)
@@ -81,7 +81,7 @@
VG_(print_translation_stats)();
VG_(print_tt_tc_stats)();
VG_(print_scheduler_stats)();
- VG_(print_ExeContext_stats)();
+ VG_(print_ExeContext_stats)( False /* with_stacktraces */ );
VG_(print_errormgr_stats)();
// Memory stats
Modified: trunk/coregrind/m_gdbserver/server.c (+7 -1)
===================================================================
--- trunk/coregrind/m_gdbserver/server.c 2013-01-10 15:44:28 +00:00 (rev 13219)
+++ trunk/coregrind/m_gdbserver/server.c 2013-01-10 20:42:51 +00:00 (rev 13220)
@@ -27,6 +27,7 @@
#include "pub_core_translate.h"
#include "pub_core_mallocfree.h"
#include "pub_core_initimg.h"
+#include "pub_core_execontext.h"
#include "pub_core_syswrap.h" // VG_(show_open_fds)
unsigned long cont_thread;
@@ -177,6 +178,7 @@
" v.info gdbserver_status : show gdbserver status\n"
" v.info memory [aspacemgr] : show valgrind heap memory stats\n"
" (with aspacemgr arg, also shows valgrind segments on log ouput)\n"
+" v.info exectxt : show stacktraces and stats of all execontexts\n"
" v.info scheduler : show valgrind thread state and stacktrace\n"
" v.set debuglog <level> : set valgrind debug log level to <level>\n"
" v.translate <addr> [<traceflags>] : debug translation of <addr> with <traceflags>\n"
@@ -243,7 +245,7 @@
wcmd = strtok_r (NULL, " ", &ssaveptr);
switch (kwdid = VG_(keyword_id)
("all_errors n_errs_found last_error gdbserver_status memory"
- " scheduler open_fds",
+ " scheduler open_fds exectxt",
wcmd, kwd_report_all)) {
case -2:
case -1:
@@ -295,6 +297,10 @@
" to show open fds\n");
ret = 1;
break;
+ case 7: /* exectxt */
+ VG_(print_ExeContext_stats) (True /* with_stacktraces */);
+ ret = 1;
+ break;
default:
vg_assert(0);
}
Modified: trunk/NEWS (+5 -0)
===================================================================
--- trunk/NEWS 2013-01-10 15:44:28 +00:00 (rev 13219)
+++ trunk/NEWS 2013-01-10 20:42:51 +00:00 (rev 13220)
@@ -20,6 +20,11 @@
- Addition of GDB server monitor command 'v.info open_fds' that gives the
list of open file descriptors and additional details.
+ - Addition of GDB server monitor command 'v.info execontext' that shows
+ information about the stack traces recorded by Valgrind.
+ This can be used to analyse one possible cause of Valgrind high
+ memory usage for some programs.
+
* ==================== FIXED BUGS ====================
The following bugs have been fixed or resolved. Note that "n-i-bz"
Modified: trunk/coregrind/m_execontext.c (+18 -1)
===================================================================
--- trunk/coregrind/m_execontext.c 2013-01-10 15:44:28 +00:00 (rev 13219)
+++ trunk/coregrind/m_execontext.c 2013-01-10 20:42:51 +00:00 (rev 13220)
@@ -146,9 +146,26 @@
/* Print stats. */
-void VG_(print_ExeContext_stats) ( void )
+void VG_(print_ExeContext_stats) ( Bool with_stacktraces )
{
init_ExeContext_storage();
+
+ if (with_stacktraces) {
+ Int i;
+ ExeContext* ec;
+ VG_(message)(Vg_DebugMsg, " exectx: Printing contexts stacktraces\n");
+ for (i = 0; i < ec_htab_size; i++) {
+ for (ec = ec_htab[i]; ec; ec = ec->chain) {
+ VG_(message)(Vg_DebugMsg, " exectx: stacktrace ecu %u\n",
+ ec->ecu);
+ VG_(pp_StackTrace)( ec->ips, ec->n_ips );
+ }
+ }
+ VG_(message)(Vg_DebugMsg,
+ " exectx: Printed %'llu contexts stacktraces\n",
+ ec_totstored);
+ }
+
VG_(message)(Vg_DebugMsg,
" exectx: %'lu lists, %'llu contexts (avg %'llu per list)\n",
ec_htab_size, ec_totstored, ec_totstored / (ULong)ec_htab_size
|