You can subscribe to this list here.
| 2002 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
(1) |
Oct
(122) |
Nov
(152) |
Dec
(69) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2003 |
Jan
(6) |
Feb
(25) |
Mar
(73) |
Apr
(82) |
May
(24) |
Jun
(25) |
Jul
(10) |
Aug
(11) |
Sep
(10) |
Oct
(54) |
Nov
(203) |
Dec
(182) |
| 2004 |
Jan
(307) |
Feb
(305) |
Mar
(430) |
Apr
(312) |
May
(187) |
Jun
(342) |
Jul
(487) |
Aug
(637) |
Sep
(336) |
Oct
(373) |
Nov
(441) |
Dec
(210) |
| 2005 |
Jan
(385) |
Feb
(480) |
Mar
(636) |
Apr
(544) |
May
(679) |
Jun
(625) |
Jul
(810) |
Aug
(838) |
Sep
(634) |
Oct
(521) |
Nov
(965) |
Dec
(543) |
| 2006 |
Jan
(494) |
Feb
(431) |
Mar
(546) |
Apr
(411) |
May
(406) |
Jun
(322) |
Jul
(256) |
Aug
(401) |
Sep
(345) |
Oct
(542) |
Nov
(308) |
Dec
(481) |
| 2007 |
Jan
(427) |
Feb
(326) |
Mar
(367) |
Apr
(255) |
May
(244) |
Jun
(204) |
Jul
(223) |
Aug
(231) |
Sep
(354) |
Oct
(374) |
Nov
(497) |
Dec
(362) |
| 2008 |
Jan
(322) |
Feb
(482) |
Mar
(658) |
Apr
(422) |
May
(476) |
Jun
(396) |
Jul
(455) |
Aug
(267) |
Sep
(280) |
Oct
(253) |
Nov
(232) |
Dec
(304) |
| 2009 |
Jan
(486) |
Feb
(470) |
Mar
(458) |
Apr
(423) |
May
(696) |
Jun
(461) |
Jul
(551) |
Aug
(575) |
Sep
(134) |
Oct
(110) |
Nov
(157) |
Dec
(102) |
| 2010 |
Jan
(226) |
Feb
(86) |
Mar
(147) |
Apr
(117) |
May
(107) |
Jun
(203) |
Jul
(193) |
Aug
(238) |
Sep
(300) |
Oct
(246) |
Nov
(23) |
Dec
(75) |
| 2011 |
Jan
(133) |
Feb
(195) |
Mar
(315) |
Apr
(200) |
May
(267) |
Jun
(293) |
Jul
(353) |
Aug
(237) |
Sep
(278) |
Oct
(611) |
Nov
(274) |
Dec
(260) |
| 2012 |
Jan
(303) |
Feb
(391) |
Mar
(417) |
Apr
(441) |
May
(488) |
Jun
(655) |
Jul
(590) |
Aug
(610) |
Sep
(526) |
Oct
(478) |
Nov
(359) |
Dec
(372) |
| 2013 |
Jan
(467) |
Feb
(226) |
Mar
(391) |
Apr
(281) |
May
(299) |
Jun
(252) |
Jul
(311) |
Aug
(352) |
Sep
(481) |
Oct
(571) |
Nov
(222) |
Dec
(231) |
| 2014 |
Jan
(185) |
Feb
(329) |
Mar
(245) |
Apr
(238) |
May
(281) |
Jun
(399) |
Jul
(382) |
Aug
(500) |
Sep
(579) |
Oct
(435) |
Nov
(487) |
Dec
(256) |
| 2015 |
Jan
(338) |
Feb
(357) |
Mar
(330) |
Apr
(294) |
May
(191) |
Jun
(108) |
Jul
(142) |
Aug
(261) |
Sep
(190) |
Oct
(54) |
Nov
(83) |
Dec
(22) |
| 2016 |
Jan
(49) |
Feb
(89) |
Mar
(33) |
Apr
(50) |
May
(27) |
Jun
(34) |
Jul
(53) |
Aug
(53) |
Sep
(98) |
Oct
(206) |
Nov
(93) |
Dec
(53) |
| 2017 |
Jan
(65) |
Feb
(82) |
Mar
(102) |
Apr
(86) |
May
(187) |
Jun
(67) |
Jul
(23) |
Aug
(93) |
Sep
(65) |
Oct
(45) |
Nov
(35) |
Dec
(17) |
| 2018 |
Jan
(26) |
Feb
(35) |
Mar
(38) |
Apr
(32) |
May
(8) |
Jun
(43) |
Jul
(27) |
Aug
(30) |
Sep
(43) |
Oct
(42) |
Nov
(38) |
Dec
(67) |
| 2019 |
Jan
(32) |
Feb
(37) |
Mar
(53) |
Apr
(64) |
May
(49) |
Jun
(18) |
Jul
(14) |
Aug
(53) |
Sep
(25) |
Oct
(30) |
Nov
(49) |
Dec
(31) |
| 2020 |
Jan
(87) |
Feb
(45) |
Mar
(37) |
Apr
(51) |
May
(99) |
Jun
(36) |
Jul
(11) |
Aug
(14) |
Sep
(20) |
Oct
(24) |
Nov
(40) |
Dec
(23) |
| 2021 |
Jan
(14) |
Feb
(53) |
Mar
(85) |
Apr
(15) |
May
(19) |
Jun
(3) |
Jul
(14) |
Aug
(1) |
Sep
(57) |
Oct
(73) |
Nov
(56) |
Dec
(22) |
| 2022 |
Jan
(3) |
Feb
(22) |
Mar
(6) |
Apr
(55) |
May
(46) |
Jun
(39) |
Jul
(15) |
Aug
(9) |
Sep
(11) |
Oct
(34) |
Nov
(20) |
Dec
(36) |
| 2023 |
Jan
(79) |
Feb
(41) |
Mar
(99) |
Apr
(169) |
May
(48) |
Jun
(16) |
Jul
(16) |
Aug
(57) |
Sep
(19) |
Oct
|
Nov
|
Dec
|
| S | M | T | W | T | F | S |
|---|---|---|---|---|---|---|
|
|
|
|
|
1
(14) |
2
(8) |
3
(7) |
|
4
(7) |
5
(7) |
6
(6) |
7
(11) |
8
(10) |
9
(14) |
10
(10) |
|
11
(13) |
12
(15) |
13
(6) |
14
(8) |
15
(6) |
16
(6) |
17
(6) |
|
18
(6) |
19
(11) |
20
(15) |
21
(14) |
22
(11) |
23
(7) |
24
(17) |
|
25
(14) |
26
(28) |
27
(21) |
28
(23) |
29
(21) |
30
(17) |
31
(8) |
|
From: Julian S. <js...@ac...> - 2007-03-29 23:59:42
|
On Friday 30 March 2007 00:40, Nicholas Nethercote wrote: > On Fri, 30 Mar 2007, Julian Seward wrote: > >> Patch is below. > > > > Nice! Did it allow you to track down the original problem with > > env vars (now lost in the mists of time) ? > > So you've essentially added eager definedness checking for environment > variables -- is that right? Oh, yes, you're right. Hang on. That's not good. The original reason I wrote a getenv wrapper is I thought that the glibc one over-read memory (like memcpy etc). But I was wrong, it was the application putting bogus strings into the environment. So now Dirk is trying to detect this when at the putenv/addenv point rather than later in getenv, when it is really too late. Sounds reasonable; on the other hand it's a bit specialised and would cause a false error in the case where you added an undefined string to the environment and then never looked it up. Should be be in the business of checking arguments to arbitrary libc functions? I had not realised this before, but the function wrapping stuff makes it possible to do that if we want. J |
|
From: Nicholas N. <nj...@cs...> - 2007-03-29 23:40:11
|
On Fri, 30 Mar 2007, Julian Seward wrote: >> Patch is below. > > Nice! Did it allow you to track down the original problem with > env vars (now lost in the mists of time) ? So you've essentially added eager definedness checking for environment variables -- is that right? Nick |
|
From: Julian S. <js...@ac...> - 2007-03-29 23:32:26
|
> Patch is below.
Nice! Did it allow you to track down the original problem with
env vars (now lost in the mists of time) ?
My only concerns are (mostly the 2nd point):
- could you change 'int result' to 'Word result' (64-bit paranoia
w.r.t the horrible CALL_FN_W.. macros)
- how do we stop some future gcc-5.7.2 from noticing that
"if (p) while (*p++) ;" does not compute anything useful and
and therefore optimising it away?
Only solution I can think of (is horrible) is:
if (p) {
while (*p++)
;
__asm__ __volatile__( "" : /*out*/ : /*in*/ "r"(p) );
}
Since gcc has no way to know what is going in inside the asm, it
has to believe our claim that it reads p.
Nicer suggestions welcomed.
J
|
|
From: Dirk M. <dm...@gm...> - 2007-03-29 23:11:43
|
On Thursday, 29. March 2007, Julian Seward wrote: > > the patch is below, and its not working. probably I'm doing something > > stupid, > No - this is subtle. Hmm, no :) I was actually looking for something like the call wrapper, but I must have been blind. Thanks a lot for your help! Patch is below. The reason glibc doesn't trigger the memcheck traces itself is that it never actually touches the memory, it just stores the pointer to it in the environment table and is done with it. Ok? Thanks, Dirk |
|
From: <sv...@va...> - 2007-03-29 22:46:12
|
Author: njn Date: 2007-03-29 23:46:05 +0100 (Thu, 29 Mar 2007) New Revision: 322 Log: wibble2 Modified: trunk/help/projects.html Modified: trunk/help/projects.html =================================================================== --- trunk/help/projects.html 2007-03-29 22:42:35 UTC (rev 321) +++ trunk/help/projects.html 2007-03-29 22:46:05 UTC (rev 322) @@ -240,6 +240,7 @@ -1). You might also need to handle some slight variations on the above (eg. an extra arg to the dealloc function). You'd implement it in Valgrind using function wrapping to know when the alloc/dealloc functions are called. +(Added March 30, 2007; idea from Brant Gurganus) </p> <h3>Incremental debug info reading</h3> |
|
From: <sv...@va...> - 2007-03-29 22:42:37
|
Author: njn Date: 2007-03-29 23:42:35 +0100 (Thu, 29 Mar 2007) New Revision: 321 Log: wibble Modified: trunk/help/projects.html Modified: trunk/help/projects.html =================================================================== --- trunk/help/projects.html 2007-03-29 22:41:38 UTC (rev 320) +++ trunk/help/projects.html 2007-03-29 22:42:35 UTC (rev 321) @@ -234,8 +234,8 @@ <p>The tool would have a configuration file where you name the alloc/dealloc function pairs. Those examples all follow the following pattern in their type signatures:<br> - token alloc(...)<br> - ... dealloc(token t)<br> + <tt>token alloc(...)</tt><br> + <tt>... dealloc(token t)</tt><br> You'd need a way to handle cases where alloc() fails (eg. open() returns -1). You might also need to handle some slight variations on the above (eg. an extra arg to the dealloc function). You'd implement it in Valgrind using |
|
From: <sv...@va...> - 2007-03-29 22:41:38
|
Author: njn Date: 2007-03-29 23:41:38 +0100 (Thu, 29 Mar 2007) New Revision: 320 Log: Added a tool suggestion. Modified: trunk/help/projects.html Modified: trunk/help/projects.html =================================================================== --- trunk/help/projects.html 2007-03-25 08:33:47 UTC (rev 319) +++ trunk/help/projects.html 2007-03-29 22:41:38 UTC (rev 320) @@ -225,6 +225,22 @@ may be instructive. This is a fairly straightforward project. (Added August 27, 2005)</p> +<h3>New tool: resource alloc/dealloc checker</h3> +<p>Memcheck detects memory leaks and file descriptor leaks. There are other +resource allocators that have alloc/dealloc functions. Some examples: +malloc/free, fopen/fclose, open/close, XOpenDisplay/XCloseDisplay, etc. +It would be nice to check them for leaks in an extensible fashion. +</p> +<p>The tool would have a configuration file where you name the alloc/dealloc +function pairs. Those examples all follow the following pattern in their +type signatures:<br> + token alloc(...)<br> + ... dealloc(token t)<br> +You'd need a way to handle cases where alloc() fails (eg. open() returns +-1). You might also need to handle some slight variations on the above (eg. +an extra arg to the dealloc function). You'd implement it in Valgrind using +function wrapping to know when the alloc/dealloc functions are called. +</p> <h3>Incremental debug info reading</h3> <p>When a code segment is loaded Valgrind mmaps the entire file into |
|
From: <sv...@va...> - 2007-03-29 22:32:45
|
Author: njn Date: 2007-03-29 23:32:41 +0100 (Thu, 29 Mar 2007) New Revision: 6690 Log: comment-only changes Modified: branches/MASSIF2/massif/ms_main.c Modified: branches/MASSIF2/massif/ms_main.c =================================================================== --- branches/MASSIF2/massif/ms_main.c 2007-03-29 22:31:57 UTC (rev 6689) +++ branches/MASSIF2/massif/ms_main.c 2007-03-29 22:32:41 UTC (rev 6690) @@ -31,17 +31,18 @@ // XXX: //--------------------------------------------------------------------------- // Next: -// - truncate really long file names [hmm, could make getting the name of -// alloc-fns more difficult] // - Check MALLOCLIKE_BLOCK works, write regtest // +// Work out how to take the peak. +// - exact peak, or within a certain percentage? +// - include the stack? makes it harder +// // Separate content from presentation by dumping all results to a file and // then post-processing with a separate program, a la Cachegrind? // - work out the file format -// - allow two decimal places in percentages (Kirk Johnson says people want -// it) // - allow truncation of long fnnames if the exact line number is -// identified? +// identified? [hmm, could make getting the name of alloc-fns more +// difficult] // // Examine and fix bugs on bugzilla: // IGNORE: @@ -64,20 +65,26 @@ // // TODO: // 141631 nor Massif: percentages don't add up correctly +// - better sanity-checking should help this greatly // 142706 nor massif numbers don't seem to add up +// - better sanity-checking should help this greatly // 143062 cra massif crashes on app exit with signal 8 SIGFPE // - occurs with no allocations -- ensure that case works // -// Work out how to take the peak. -// - exact peak, or within a certain percentage? -// - include the stack? makes it harder -// // Michael Meeks: // - wants an interactive way to request a dump (callgrind_control-style) // - "profile now" // - "show me the extra allocations from last-snapshot" // - "start/stop logging" (eg. quickly skip boring bits) // +// Artur Wisz: +// - added a feature to Massif to ignore any heap blocks larger than a +// certain size! Because: +// "linux's malloc allows to set a MMAP_THRESHOLD value, so we +// set it to 4096 - all blocks above that will be handled directly by +// the kernel, and are guaranteed to be returned to the system when +// freed. So we needed to profile only blocks below this limit." +// // Other: // - am I recording asked-for sizes or actual rounded-up sizes? // - there's a gap between the ms timer initialisation during Valgrind @@ -98,6 +105,8 @@ // [XXX: that doesn't work if the option is in a .valgrindrc file or in // $VALGRIND_OPTS. In m_commandline.c:add_args_from_string() need to // respect single quotes...] +// - Explain the --threshold=0 case -- entries with zero bytes must have +// allocated some memory and then freed it all again. // // Tests: // - tests/overloaded_new.cpp is there @@ -105,12 +114,6 @@ // //--------------------------------------------------------------------------- -// Memory profiler. Produces a graph, gives lots of information about -// allocation contexts, in terms of space.time values (ie. area under the -// graph). Allocation context information is hierarchical, and can thus -// be inspected step-wise to an appropriate depth. See comments on data -// structures below for more info on how things work. - #include "pub_tool_basics.h" #include "pub_tool_vki.h" #include "pub_tool_aspacemgr.h" |
|
From: <sv...@va...> - 2007-03-29 22:32:04
|
Author: njn
Date: 2007-03-29 23:31:57 +0100 (Thu, 29 Mar 2007)
New Revision: 6689
Log:
add a useful test case. Not actually plumbed into the Makefile yet.
Added:
branches/MASSIF2/massif/tests/overloaded-new.cpp
Added: branches/MASSIF2/massif/tests/overloaded-new.cpp
===================================================================
--- branches/MASSIF2/massif/tests/overloaded-new.cpp (rev 0)
+++ branches/MASSIF2/massif/tests/overloaded-new.cpp 2007-03-29 22:31:57 UTC (rev 6689)
@@ -0,0 +1,46 @@
+// operator new(unsigned)
+// operator new[](unsigned)
+// operator new(unsigned, std::nothrow_t const&)
+// operator new[](unsigned, std::nothrow_t const&)
+
+#include <stdlib.h>
+
+#include <new>
+
+using std::nothrow_t;
+
+// A big structure. It's details don't matter.
+struct s {
+ int array[1000];
+};
+
+void* operator new (std::size_t n) throw (std::bad_alloc)
+{
+ return malloc(n);
+}
+
+void* operator new (std::size_t n, std::nothrow_t const &) throw ()
+{
+ return malloc(n);
+}
+
+void* operator new[] (std::size_t n) throw (std::bad_alloc)
+{
+ return malloc(n);
+}
+
+void* operator new[] (std::size_t n, std::nothrow_t const &) throw ()
+{
+ return malloc(n);
+}
+
+int main(void)
+{
+ struct s* p1 = new struct s;
+ struct s* p2 = new (std::nothrow) struct s;
+ char* c1 = new char[2000];
+ char* c2 = new (std::nothrow) char[2000];
+ return 0;
+}
+
+
|
|
From: Julian S. <js...@ac...> - 2007-03-29 21:39:44
|
Dirk > the patch is below, and its not working. probably I'm doing something > stupid, No - this is subtle. > but I can't find an example for a wrapper function anywhere. auxprogs/libmpiwrap.c has a huge collection of them. You've hit the distinction between replacement functions and wrapper functions. A replacement (eg malloc) simply replaces some function; there is no way to call onwards to the original. A wrapper function is more powerful - it gives you a way to find out the original and call onwards to it. I think your wrapper might produce an infinite loop, since the call to putenv just goes back to the wrapper. Try the code below. All this strange stuff is documented at http://www.valgrind.org/docs/manual/manual-core.html#manual-core.wrapping J /* putenv */ int VG_WRAP_FUNCTION_ZU(m_libc_soname, putenv) (char* string); int VG_WRAP_FUNCTION_ZU(m_libc_soname, putenv) (char* string) { OrigFn fn; char* p; VALGRIND_GET_ORIG_FN(fn); // remember the original p = string; if (string) { int len = 0; while (*p++) len++; VALGRIND_CHECK_MEM_IS_DEFINED(string, len+1); } // call original, ultra-magic hacks to avoid recursion unsigned long tmp; CALL_FN_W_W(tmp, fn, (unsigned long)string); return (int)tmp; } |
|
From: Dirk M. <dm...@gm...> - 2007-03-29 21:19:35
|
On Wednesday, 21. March 2007, Julian Seward wrote: > Dirk, thanks for the confirmation. Yes, the getenv wrapper is already > reverted. Ah, sorry, didn't see it. I've tried to implement a putenv function wrapper in order to be able to pinpoint the place where undefined values are put into the environment (setenv is also to be fixed similarly) instead of having to trace miracle errors during getenv time. the patch is below, and its not working. probably I'm doing something stupid, but I can't find an example for a wrapper function anywhere. Any insights much appreciated. Thanks, Dirk |
|
From: <sv...@va...> - 2007-03-29 16:35:08
|
Author: sewardj
Date: 2007-03-29 17:35:00 +0100 (Thu, 29 Mar 2007)
New Revision: 6688
Log:
Test some Fortran types.
Modified:
trunk/auxprogs/mpiwrap_type_test.c
Modified: trunk/auxprogs/mpiwrap_type_test.c
===================================================================
--- trunk/auxprogs/mpiwrap_type_test.c 2007-03-29 08:37:13 UTC (rev 6687)
+++ trunk/auxprogs/mpiwrap_type_test.c 2007-03-29 16:35:00 UTC (rev 6688)
@@ -133,8 +133,7 @@
walk_type_fn;
if (!dl_walk_type) {
- printf("sendToMyself: can't find mpiwrap_walk_type_EXTERNALLY_VISIBLE"
- " in current process image\n");
+ printf("sendToMyself: can't establish type walker fn\n");
return;
}
@@ -233,6 +232,8 @@
return 1;
}
+ /* Note: this trick doesn't work on 64-bit platforms,
+ since MPI_Init returns int. */
walk_type_fn = (void*)(long) MPI_Init( &argc, &argv );
printf("mpiwrap_type_test: walk_type_fn = %p\n", walk_type_fn);
assert(walk_type_fn);
@@ -242,8 +243,8 @@
if (rank == 0) {
- Ty t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13;
- Nm n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, n12, n13;
+ Ty t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15, t16, t17, t18;
+ Nm n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, n12, n13, n14, n15, n16, n17, n18;
t2 = tycon_Contiguous(3, MPI_INT);
n2 = "Contig{3xINT}";
@@ -281,6 +282,21 @@
t13 = MPI_SHORT_INT;
n13 = "SHORT_INT";
+ t14 = MPI_REAL8;
+ n14 = "REAL8";
+
+ t15 = MPI_REAL4;
+ n15 = "REAL4";
+
+ t16 = MPI_INTEGER8;
+ n16 = "INTEGER8";
+
+ t17 = MPI_INTEGER4;
+ n17 = "INTEGER4";
+
+ t18 = MPI_2INT;
+ n18 = "2INT";
+
sendToMyself(True, &t2, n2);
sendToMyself(True, &t3, n3);
sendToMyself(True, &t4, n4);
@@ -293,6 +309,11 @@
sendToMyself(False, &t11, n11);
sendToMyself(False, &t12, n12);
sendToMyself(False, &t13, n13);
+ sendToMyself(False, &t14, n14);
+ sendToMyself(False, &t15, n15);
+ sendToMyself(False, &t16, n16);
+ sendToMyself(False, &t17, n17);
+ sendToMyself(False, &t18, n18);
}
MPI_Finalize();
|
|
From: <js...@ac...> - 2007-03-29 11:11:00
|
Nightly build on minnie ( SuSE 10.0, ppc32 ) started at 2007-03-29 09:00:02 BST Results unchanged from 24 hours ago Checking out valgrind source tree ... done Configuring valgrind ... done Building valgrind ... done Running regression tests ... failed Regression test results follow == 219 tests, 10 stderr failures, 6 stdout failures, 0 posttest failures == memcheck/tests/leak-tree (stderr) memcheck/tests/leakotron (stdout) memcheck/tests/pointer-trace (stderr) memcheck/tests/stack_changes (stderr) memcheck/tests/xml1 (stderr) none/tests/faultstatus (stderr) none/tests/fdleak_cmsg (stderr) none/tests/mremap (stderr) none/tests/mremap2 (stdout) none/tests/ppc32/jm-fp (stdout) none/tests/ppc32/jm-fp (stderr) none/tests/ppc32/round (stdout) none/tests/ppc32/round (stderr) none/tests/ppc32/test_fx (stdout) none/tests/ppc32/test_fx (stderr) none/tests/ppc32/test_gx (stdout) |
|
From: <sv...@va...> - 2007-03-29 08:37:15
|
Author: njn
Date: 2007-03-29 09:37:13 +0100 (Thu, 29 Mar 2007)
New Revision: 6687
Log:
- Show second decimal place in percentages.
- Show remaining percentage/size in "n other insignificant place" entries.
Modified:
branches/MASSIF2/massif/ms_main.c
Modified: branches/MASSIF2/massif/ms_main.c
===================================================================
--- branches/MASSIF2/massif/ms_main.c 2007-03-29 08:25:57 UTC (rev 6686)
+++ branches/MASSIF2/massif/ms_main.c 2007-03-29 08:37:13 UTC (rev 6687)
@@ -31,8 +31,6 @@
// XXX:
//---------------------------------------------------------------------------
// Next:
-// - print percentages/sizes in "the rest" entries
-// - show 2nd decimal point (only if threshold is below 10, ie. 0.1%?)
// - truncate really long file names [hmm, could make getting the name of
// alloc-fns more difficult]
// - Check MALLOCLIKE_BLOCK works, write regtest
@@ -1540,7 +1538,7 @@
// tl_assert(x <= y); XXX; put back in later...
// XXX: I'm not confident that VG_(percentify) works as it should...
- VG_(percentify)(x, y, 1, 5, mbuf);
+ VG_(percentify)(x, y, 2, 6, mbuf);
// XXX: this is bogus if the denominator was zero -- resulting string is
// something like "0 --%")
if (' ' == mbuf[0]) mbuf[0] = '0';
@@ -1567,6 +1565,7 @@
XPt* child;
Bool child_is_last_sibling;
Char* ip_desc, *perc;
+ SizeT printed_children_szB = 0;
// Check that the sum of all children's sizes equals the parent's size.
SizeT children_sum_szB = 0;
@@ -1595,7 +1594,8 @@
// This child is significant. Print it.
perc = make_perc(child->curr_szB, curr_total_szB);
ip_desc = VG_(describe_IP)(child->ip-1, buf2, BUF_LEN);
- P("->%6s(%,ldB): %s\n", perc, child->curr_szB, ip_desc);
+ P("->%s (%,ldB): %s\n", perc, child->curr_szB, ip_desc);
+ printed_children_szB += child->curr_szB;
// If the child has any children, print them. But first add the
// prefix for them, which is " " if the parent has no smaller
@@ -1626,12 +1626,15 @@
} else {
// This child is insignificant, as are all those remaining.
// Don't bother with them.
- UInt n_insig = parent->n_children - i;
- Char* s = ( n_insig == 1 ? "" : "s" );
- Char* other = ( 0 == i ? "" : "other " );
+ UInt n_insig = parent->n_children - i;
+ Char* s = ( n_insig == 1 ? "" : "s" );
+ Char* other = ( 0 == i ? "" : "other " );
+ SizeT unprinted_children_szB = parent->curr_szB - printed_children_szB;
// XXX: should give the percentage. be careful when computing
// it...
- P("->the rest in %d %sinsignificant place%s\n", n_insig, other, s);
+ perc = make_perc(unprinted_children_szB, curr_total_szB);
+ P("->%s (%,ldB): in %d %sinsignificant place%s\n",
+ perc, unprinted_children_szB, n_insig, other, s);
P("%s\n", depth_str);
return;
}
@@ -1664,7 +1667,7 @@
P("(No heap memory currently allocated)\n");
} else {
P("Heap tree:\n");
- P("%6s(%,ldB): (heap allocation functions) malloc/new/new[],"
+ P("%s (%,ldB): (heap allocation functions) malloc/new/new[],"
" --alloc-fns, etc.\n",
make_perc(snapshot->heap_szB, snapshot->total_szB),
snapshot->heap_szB);
|
|
From: <sv...@va...> - 2007-03-29 08:26:02
|
Author: njn
Date: 2007-03-29 09:25:57 +0100 (Thu, 29 Mar 2007)
New Revision: 6686
Log:
- Added periodic XTree sanity checking.
- Added sanity checking of snapshots[] array.
- Being more careful about zeroing unused entries in snapshots[]. This
should fix some bugs/assertion failures.
- Now deallocating XTrees from discarded snapshots.
- Some formatting changes, and moved some stuff around.
Modified:
branches/MASSIF2/massif/ms_main.c
Modified: branches/MASSIF2/massif/ms_main.c
===================================================================
--- branches/MASSIF2/massif/ms_main.c 2007-03-29 02:10:37 UTC (rev 6685)
+++ branches/MASSIF2/massif/ms_main.c 2007-03-29 08:25:57 UTC (rev 6686)
@@ -1,8 +1,7 @@
+//--------------------------------------------------------------------*/
+//--- Massif: a heap profiling tool. ms_main.c ---*/
+//--------------------------------------------------------------------*/
-/*--------------------------------------------------------------------*/
-/*--- Massif: a heap profiling tool. ms_main.c ---*/
-/*--------------------------------------------------------------------*/
-
/*
This file is part of Massif, a Valgrind tool for profiling memory
usage of programs.
@@ -32,9 +31,6 @@
// XXX:
//---------------------------------------------------------------------------
// Next:
-// - sanity check: do the periodic core-based one, check the main XTree but
-// not the individual snapshots, since they're checked when taken and
-// printed.
// - print percentages/sizes in "the rest" entries
// - show 2nd decimal point (only if threshold is below 10, ie. 0.1%?)
// - truncate really long file names [hmm, could make getting the name of
@@ -138,9 +134,9 @@
#include "valgrind.h" // For {MALLOC,FREE}LIKE_BLOCK
-/*------------------------------------------------------------*/
-/*--- Overview of operation ---*/
-/*------------------------------------------------------------*/
+//------------------------------------------------------------*/
+//--- Overview of operation ---*/
+//------------------------------------------------------------*/
// The size of the stacks and heap is tracked. The heap is tracked in a lot
// of detail, enough to tell how many bytes each line of code is responsible
@@ -232,9 +228,9 @@
// - etc.
-/*------------------------------------------------------------*/
-/*--- Main types ---*/
-/*------------------------------------------------------------*/
+///-----------------------------------------------------------//
+//--- Main types ---//
+//------------------------------------------------------------//
// An XPt represents an "execution point", ie. a code address. Each XPt is
// part of a tree of XPts (an "execution tree", or "XTree"). The details of
@@ -264,6 +260,10 @@
// | / \ | the XTree will look like this.
// | v v |
// child1 child2
+//
+// Sanity checking: we check snapshot XTrees when they are taken, deleted
+// and printed. We periodically check the main heap XTree periodically via
+// ms_expensive_sanity_check.
typedef struct _XPt XPt;
@@ -330,10 +330,11 @@
}
HP_Chunk;
-/*------------------------------------------------------------*/
-/*--- Statistics ---*/
-/*------------------------------------------------------------*/
+//------------------------------------------------------------//
+//--- Statistics ---//
+//------------------------------------------------------------//
+
// Konqueror startup, to give an idea of the numbers involved with a biggish
// program, with default depth:
//
@@ -357,10 +358,11 @@
static UInt n_real_snapshots = 0;
static UInt n_fake_snapshots = 0;
-/*------------------------------------------------------------*/
-/*--- Globals ---*/
-/*------------------------------------------------------------*/
+//------------------------------------------------------------//
+//--- Globals ---//
+//------------------------------------------------------------//
+
#define FILENAME_LEN 256
#define P VG_(printf)
@@ -377,7 +379,7 @@
// Make these signed so things are more obvious if they go negative.
static SSizeT sigstacks_szB = 0; // Current signal stacks space sum
static SSizeT heap_szB = 0; // Live heap size
-static SSizeT peak_heap_szB = 0;
+static SSizeT peak_heap_szB = 0; // XXX: currently unused
static SSizeT peak_snapshot_total_szB = 0;
static VgHashTable malloc_list = NULL; // HP_Chunks
@@ -409,9 +411,9 @@
};
-/*------------------------------------------------------------*/
-/*--- Command line args ---*/
-/*------------------------------------------------------------*/
+//------------------------------------------------------------//
+//--- Command line args ---//
+//------------------------------------------------------------//
#define MAX_DEPTH 50
@@ -475,10 +477,11 @@
VG_(replacement_malloc_print_debug_usage)();
}
-/*------------------------------------------------------------*/
-/*--- XPts ---*/
-/*------------------------------------------------------------*/
+//------------------------------------------------------------//
+//--- XPts ---//
+//------------------------------------------------------------//
+
// Fake XPt representing all allocation functions like malloc(). Acts as
// parent node to all top-XPts.
static XPt* alloc_xpt;
@@ -505,6 +508,21 @@
return (void*)(hp - n_bytes);
}
+__attribute__((unused))
+static void pp_XPt(XPt* xpt)
+{
+ Int i;
+ P("XPt (%p):\n", xpt);
+ P("- ip: : %p\n", (void*)xpt->ip);
+ P("- curr_szB : %ld\n", xpt->curr_szB);
+ P("- parent : %p\n", xpt->parent);
+ P("- n_children : %d\n", xpt->n_children);
+ P("- max_children: %d\n", xpt->max_children);
+ for (i = 0; i < xpt->n_children; i++) {
+ P("- children[%2d]: %p\n", i, xpt->children[i]);
+ }
+}
+
static XPt* new_XPt(Addr ip, XPt* parent)
{
// XPts are never freed, so we can use perm_malloc to allocate them.
@@ -558,10 +576,83 @@
: 0);
}
-/*------------------------------------------------------------*/
-/*--- XCons ---*/
-/*------------------------------------------------------------*/
+//------------------------------------------------------------//
+//--- XTrees ---//
+//------------------------------------------------------------//
+
+// XXX: taking a full snapshot... could/should just snapshot the significant
+// parts. Nb: then the amounts wouldn't add up, unless I represented the
+// "other insignificant places" in XPts.
+static XPt* dup_XTree(XPt* xpt, XPt* parent)
+{
+ Int i;
+ XPt* dup_xpt = VG_(malloc)(sizeof(XPt));
+ dup_xpt->ip = xpt->ip;
+ dup_xpt->curr_szB = xpt->curr_szB;
+ dup_xpt->parent = parent; // Nb: not xpt->children!
+ dup_xpt->n_children = xpt->n_children;
+ dup_xpt->max_children = xpt->n_children; // Nb: don't copy max_children!
+ dup_xpt->children = VG_(malloc)(dup_xpt->max_children * sizeof(XPt*));
+ for (i = 0; i < xpt->n_children; i++) {
+ dup_xpt->children[i] = dup_XTree(xpt->children[i], dup_xpt);
+ }
+
+ n_dupd_xpts++;
+
+ return dup_xpt;
+}
+
+static void free_XTree(XPt* xpt)
+{
+ Int i;
+ // Free all children XPts, then the children array, then the XPt itself.
+ tl_assert(xpt != NULL);
+ for (i = 0; i < xpt->n_children; i++) {
+ XPt* child = xpt->children[i];
+ free_XTree(child);
+ xpt->children[i] = NULL;
+ }
+ VG_(free)(xpt->children); xpt->children = NULL;
+ VG_(free)(xpt); xpt = NULL;
+
+ n_dupd_xpts_freed++;
+}
+
+// XXX: improve this so that it prints the failing XPt always.
+static void sanity_check_XTree(XPt* xpt, XPt* parent)
+{
+ Int i;
+ SizeT children_sum_szB = 0;
+
+ tl_assert(xpt != NULL);
+
+ // Check back-pointer.
+ tl_assert2(xpt->parent == parent,
+ "xpt->parent = %p, parent = %p\n", xpt->parent, parent);
+
+ // Check children counts look sane.
+ tl_assert(xpt->n_children <= xpt->max_children);
+
+ // Check the sum of any children szBs equals the XPt's szB.
+ if (xpt->n_children > 0) {
+ for (i = 0; i < xpt->n_children; i++) {
+ children_sum_szB += xpt->children[i]->curr_szB;
+ }
+ tl_assert(children_sum_szB == xpt->curr_szB);
+ }
+
+ // Check each child.
+ for (i = 0; i < xpt->n_children; i++) {
+ sanity_check_XTree(xpt->children[i], xpt);
+ }
+}
+
+
+//------------------------------------------------------------//
+//--- XCons ---//
+//------------------------------------------------------------//
+
// This is the limit on the number of removed alloc-fns that can be in a
// single XCon.
#define MAX_OVERESTIMATE 50
@@ -755,69 +846,80 @@
}
-/*------------------------------------------------------------*/
-/*--- Sanity checking ---*/
-/*------------------------------------------------------------*/
+//------------------------------------------------------------//
+//--- Snapshots ---//
+//------------------------------------------------------------//
-__attribute__((unused))
-static void pp_XPt(XPt* xpt)
+static Snapshot snapshots[MAX_N_SNAPSHOTS];
+static UInt next_snapshot = 0; // Points to where next snapshot will go.
+
+static Bool is_snapshot_in_use(Snapshot* snapshot)
{
- Int i;
- P("XPt (%p):\n", xpt);
- P("- ip: : %p\n", (void*)xpt->ip);
- P("- curr_szB : %ld\n", xpt->curr_szB);
- P("- parent : %p\n", xpt->parent);
- P("- n_children : %d\n", xpt->n_children);
- P("- max_children: %d\n", xpt->max_children);
- for (i = 0; i < xpt->n_children; i++) {
- P("- children[%2d]: %p\n", i, xpt->children[i]);
+ if (-1 == snapshot->ms_time) {
+ // If .ms_time looks unused, check everything else is.
+ tl_assert(snapshot->total_szB == 0);
+ tl_assert(snapshot->heap_admin_szB == 0);
+ tl_assert(snapshot->heap_szB == 0);
+ tl_assert(snapshot->stacks_szB == 0);
+ tl_assert(snapshot->alloc_xpt == NULL);
+ return False;
+ } else {
+ return True;
}
}
-static void sanity_check_XTree(XPt* xpt, XPt* parent)
+static Bool is_detailed_snapshot(Snapshot* snapshot)
{
- Int i;
- SizeT children_sum_szB = 0;
-
- if (NULL == xpt)
- return;
-
- // Check back-pointer.
- tl_assert2(xpt->parent == parent,
- "xpt->parent = %p, parent = %p\n", xpt->parent, parent);
-
- // Check children counts look sane.
- tl_assert(xpt->n_children <= xpt->max_children);
-
- // Check the sum of any children szBs equals the XPt's szB.
- if (xpt->n_children > 0) {
- for (i = 0; i < xpt->n_children; i++) {
- children_sum_szB += xpt->children[i]->curr_szB;
- }
- tl_assert(children_sum_szB == xpt->curr_szB);
- }
-
- // Check each child.
- for (i = 0; i < xpt->n_children; i++) {
- sanity_check_XTree(xpt->children[i], xpt);
- }
+ return (snapshot->alloc_xpt ? True : False);
}
static void sanity_check_snapshot(Snapshot* snapshot)
{
tl_assert(snapshot->total_szB ==
snapshot->heap_admin_szB + snapshot->heap_szB + snapshot->stacks_szB);
- sanity_check_XTree(snapshot->alloc_xpt, /*parent*/NULL);
+ if (snapshot->alloc_xpt) {
+ sanity_check_XTree(snapshot->alloc_xpt, /*parent*/NULL);
+ }
}
-/*------------------------------------------------------------*/
-/*--- Taking a snapshot ---*/
-/*------------------------------------------------------------*/
+// All the used entries should look used, all the unused ones should be clear.
+static void sanity_check_snapshots_array(void)
+{
+ Int i;
+ for (i = 0; i < next_snapshot; i++) {
+ tl_assert( is_snapshot_in_use( & snapshots[i] ));
+ }
+ for ( ; i < MAX_N_SNAPSHOTS; i++) {
+ tl_assert(!is_snapshot_in_use( & snapshots[i] ));
+ }
+}
-static Snapshot snapshots[MAX_N_SNAPSHOTS];
-static UInt curr_snapshot = 0; // Points to where next snapshot will go.
+// This zeroes all the fields in the snapshot, but does not free the heap
+// XTree if present.
+static void clear_snapshot(Snapshot* snapshot)
+{
+ sanity_check_snapshot(snapshot);
+ snapshot->ms_time = -1;
+ snapshot->total_szB = 0;
+ snapshot->heap_admin_szB = 0;
+ snapshot->heap_szB = 0;
+ snapshot->stacks_szB = 0;
+ snapshot->alloc_xpt = NULL;
+}
-static UInt ms_interval;
+// This zeroes all the fields in the snapshot, and frees the heap XTree if
+// present.
+static void delete_snapshot(Snapshot* snapshot)
+{
+ // Nb: if there's an XTRee, we free it after calling clear_snapshot,
+ // because clear_snapshot does a sanity check which includes checking the
+ // XTree.
+ XPt* tmp_xpt = snapshot->alloc_xpt;
+ clear_snapshot(snapshot);
+ if (tmp_xpt) {
+ free_XTree(tmp_xpt);
+ }
+}
// Weed out half the snapshots; we choose those that represent the smallest
// time-spans, because that loses the least information.
@@ -840,7 +942,9 @@
// Sets j to the index of the first not-yet-removed snapshot at or after i
#define FIND_SNAPSHOT(i, j) \
- for (j = i; j < MAX_N_SNAPSHOTS && -1 == snapshots[j].ms_time; j++) { }
+ for (j = i; \
+ j < MAX_N_SNAPSHOTS && !is_snapshot_in_use(&snapshots[j]); \
+ j++) { }
for (i = 2; i < MAX_N_SNAPSHOTS; i += 2) {
// Find the snapshot representing the smallest timespan. The timespan
@@ -866,72 +970,38 @@
j = jn;
FIND_SNAPSHOT(jn+1, jn);
}
- // We've found the least important snapshot, now remove it
+ // We've found the least important snapshot, now delete it.
min_snapshot = & snapshots[ min_j ];
- min_snapshot->ms_time = -1;
-
- // XXX: free XTree if present...
- // free_XTree(min_snapshot->alloc_xpt)
+ delete_snapshot(min_snapshot);
}
// Slide down the remaining snapshots over the removed ones. The '<=' is
// because we are removing on (N/2)-1, rather than N/2.
- for (i = 0, j = 0; i <= MAX_N_SNAPSHOTS / 2; i++, j++) {
- FIND_SNAPSHOT(j, j);
- if (i != j) {
- snapshots[i] = snapshots[j];
+ // First set i to point to the first empty slot, and j to the first full
+ // slot after i. Then slide everything down.
+ for (i = 0; is_snapshot_in_use( &snapshots[i] ); i++) { }
+ for (j = i; !is_snapshot_in_use( &snapshots[j] ); j++) { }
+ for ( ; j < MAX_N_SNAPSHOTS; j++) {
+ if (is_snapshot_in_use( &snapshots[j] )) {
+ snapshots[i++] = snapshots[j];
+ clear_snapshot(&snapshots[j]);
}
}
- curr_snapshot = i;
+ next_snapshot = i;
- // Double intervals
- ms_interval *= 2;
+ // Check snapshots array looks ok after changes.
+ sanity_check_snapshots_array();
if (VG_(clo_verbosity) > 1)
VG_(message)(Vg_DebugMsg, "...done");
}
-// XXX: taking a full snapshot... could/should just snapshot the significant
-// parts. Nb: then the amounts wouldn't add up, unless I represented the
-// "other insignificant places" in XPts.
-static XPt* dup_XTree(XPt* xpt, XPt* parent)
-{
- Int i;
- XPt* dup_xpt = VG_(malloc)(sizeof(XPt));
- dup_xpt->ip = xpt->ip;
- dup_xpt->curr_szB = xpt->curr_szB;
- dup_xpt->parent = parent; // Nb: not xpt->children!
- dup_xpt->n_children = xpt->n_children;
- dup_xpt->max_children = xpt->n_children; // Nb: don't copy max_children!
- dup_xpt->children = VG_(malloc)(dup_xpt->max_children * sizeof(XPt*));
- for (i = 0; i < xpt->n_children; i++) {
- dup_xpt->children[i] = dup_XTree(xpt->children[i], dup_xpt);
- }
-
- n_dupd_xpts++;
-
- return dup_xpt;
-}
-
-static void free_XTree(XPt* xpt)
-{
- Int i;
- // Free all children XPts, then the children array, then the XPt itself.
- for (i = 0; i < xpt->n_children; i++) {
- free_XTree(xpt->children[i]);
- }
- VG_(free)(xpt->children); xpt->children = NULL;
- VG_(free)(xpt); xpt = NULL;
-
- n_dupd_xpts_freed++;
-}
-
-
// Take a snapshot. Note that with bigger depths, snapshots can be slow,
// eg. konqueror snapshots can easily take 50ms!
// [XXX: is that still true?]
static void take_snapshot(void)
{
+ static UInt ms_interval = 5;
static UInt ms_prev_snapshot = 0;
static UInt ms_next_snapshot = 0; // zero allows startup snapshot
static Int n_snapshots_since_last_detailed = 0;
@@ -949,7 +1019,9 @@
// Right! We're taking a real snapshot.
n_real_snapshots++;
- snapshot = & snapshots[curr_snapshot];
+ snapshot = & snapshots[next_snapshot];
+ next_snapshot++;
+ tl_assert(!is_snapshot_in_use(snapshot));
// Heap -------------------------------------------------------------
if (clo_heap) {
@@ -1000,13 +1072,10 @@
// VG_(printf)("heap, admin, stacks: %ld, %ld, %ld B\n",
// snapshot_heap_szB, snapshot_heap_admin_szB, snapshot_stacks_szB);
- // Clean-ups
- curr_snapshot++;
- snapshot = NULL; // don't use again now that curr_snapshot changed
-
// Halve the entries, if our snapshot table is full
- if (MAX_N_SNAPSHOTS == curr_snapshot) {
+ if (MAX_N_SNAPSHOTS == next_snapshot) {
halve_snapshots();
+ ms_interval *= 2;
}
// Take time for next snapshot from now, rather than when this snapshot
@@ -1022,10 +1091,28 @@
}
-/*------------------------------------------------------------*/
-/*--- Heap management ---*/
-/*------------------------------------------------------------*/
+//------------------------------------------------------------//
+//--- Sanity checking ---//
+//------------------------------------------------------------//
+static Bool ms_cheap_sanity_check ( void )
+{
+ // Nothing useful we can rapidly check.
+ return True;
+}
+
+static Bool ms_expensive_sanity_check ( void )
+{
+ sanity_check_XTree(alloc_xpt, /*parent*/NULL);
+ sanity_check_snapshots_array();
+ return True;
+}
+
+
+//------------------------------------------------------------//
+//--- Heap management ---//
+//------------------------------------------------------------//
+
static void update_heap_stats(SSizeT heap_szB_delta, Int n_heap_blocks_delta)
{
if (n_heap_blocks_delta<0) tl_assert(n_heap_blocks >= -n_heap_blocks_delta);
@@ -1169,10 +1256,11 @@
return p_new;
}
-/*------------------------------------------------------------*/
-/*--- malloc() et al replacement wrappers ---*/
-/*------------------------------------------------------------*/
+//------------------------------------------------------------//
+//--- malloc() et al replacement wrappers ---//
+//------------------------------------------------------------//
+
static void* ms_malloc ( ThreadId tid, SizeT szB )
{
return new_block( tid, NULL, szB, VG_(clo_alignment), /*is_zeroed*/False );
@@ -1219,9 +1307,9 @@
}
-/*------------------------------------------------------------*/
-/*--- Tracked events ---*/
-/*------------------------------------------------------------*/
+//------------------------------------------------------------//
+//--- Tracked events ---//
+//------------------------------------------------------------//
static void new_mem_stack_signal(Addr a, SizeT len)
{
@@ -1234,10 +1322,11 @@
sigstacks_szB -= len;
}
-/*------------------------------------------------------------*/
-/*--- Client Requests ---*/
-/*------------------------------------------------------------*/
+//------------------------------------------------------------//
+//--- Client Requests ---//
+//------------------------------------------------------------//
+
static Bool ms_handle_client_request ( ThreadId tid, UWord* argv, UWord* ret )
{
switch (argv[0]) {
@@ -1263,9 +1352,9 @@
}
}
-/*------------------------------------------------------------*/
-/*--- Instrumentation ---*/
-/*------------------------------------------------------------*/
+//------------------------------------------------------------//
+//--- Instrumentation ---//
+//------------------------------------------------------------//
static
IRSB* ms_instrument ( VgCallbackClosure* closure,
@@ -1285,10 +1374,11 @@
return bb_in;
}
-/*------------------------------------------------------------*/
-/*--- Writing the graph file ---*/
-/*------------------------------------------------------------*/
+//------------------------------------------------------------//
+//--- Writing the graph file ---//
+//------------------------------------------------------------//
+
#if 0
static Char* make_filename(Char* dir, Char* suffix)
{
@@ -1329,8 +1419,8 @@
// We increment end_ms_time by 1 so that the last snapshot occurs just
// before it, and doesn't spill over into the final column.
- tl_assert(curr_snapshot > 0);
- end_ms_time = snapshots[curr_snapshot-1].ms_time + 1;
+ tl_assert(next_snapshot > 0);
+ end_ms_time = snapshots[next_snapshot-1].ms_time + 1;
tl_assert(end_ms_time > 0);
// Setup graph[][].
@@ -1345,9 +1435,8 @@
// Write snapshot bars into graph[][].
// XXX: many detailed snapshot bars are being overwritten by
- for (i = 0; i < curr_snapshot; i++) {
+ for (i = 0; i < next_snapshot; i++) {
Snapshot* snapshot = & snapshots[i];
- Bool is_detailed = ( snapshot->alloc_xpt ? True : False );
// Work out how many bytes each row represents.
double per_row_full_thresh_szB = (double)peak_snapshot_total_szB / GRAPH_Y;
@@ -1367,10 +1456,10 @@
if (snapshot->total_szB >= this_row_half_thresh_szB)
graph[x][y] = '.';
if (snapshot->total_szB >= this_row_full_thresh_szB)
- graph[x][y] = ( is_detailed ? '|' : ':' );
+ graph[x][y] = ( is_detailed_snapshot(snapshot) ? '|' : ':' );
}
// If it's detailed, mark the x-axis
- if (is_detailed)
+ if (is_detailed_snapshot(snapshot))
graph[x][0] = '|';
}
@@ -1428,21 +1517,21 @@
// Print graph legend.
P("-- start graph legend --\n");
- for (i = 0; i < curr_snapshot; i++) {
+ for (i = 0; i < next_snapshot; i++) {
Snapshot* snapshot = & snapshots[i];
- Bool is_detailed = ( snapshot->alloc_xpt ? True : False );
- if (is_detailed) {
- P(" snapshot %3d, t = %,12d ms, size = %,12ld bytes\n",
+ if (is_detailed_snapshot(snapshot)) {
+ P(" snapshot %3d: t = %,12d ms, size = %,12ld bytes\n",
i, snapshot->ms_time, snapshot->total_szB);
}
}
P("-- end graph legend --\n");
}
-/*------------------------------------------------------------*/
-/*--- Writing snapshots ---*/
-/*------------------------------------------------------------*/
+//------------------------------------------------------------//
+//--- Writing snapshots ---//
+//------------------------------------------------------------//
+
// Nb: uses a static buffer, each call trashes the last string returned.
static Char* make_perc(ULong x, ULong y)
{
@@ -1587,35 +1676,22 @@
VG_(free)(depth_str);
}
-static void write_snapshots(void)
+static void write_detailed_snapshots(void)
{
Int i;
-
- // XXX: temporary
- Int depth_str_len = clo_depth * 2 + 2;
- Char* depth_str = VG_(malloc)(sizeof(Char) * depth_str_len);
- depth_str[0] = '\0'; // Initialise to "".
-
- for (i = 0; i < curr_snapshot; i++) {
+ for (i = 0; i < next_snapshot; i++) {
Snapshot* snapshot = & snapshots[i];
if (snapshot->alloc_xpt) {
pp_snapshot(snapshot, i); // Detailed snapshot!
}
}
- P("=================================\n");
- P("== main XTree\n");
- P("=================================\n");
- P("heap szB: %ld\n", heap_szB);
- pp_snapshot_child_XPts(alloc_xpt, 0, depth_str, depth_str_len,
- heap_szB, 999999);
-
- VG_(free)(depth_str);
}
-/*------------------------------------------------------------*/
-/*--- Finalisation ---*/
-/*------------------------------------------------------------*/
+//------------------------------------------------------------//
+//--- Finalisation ---//
+//------------------------------------------------------------//
+
static void ms_fini(Int exit_status)
{
// Do a final (empty) sample to show program's end
@@ -1623,7 +1699,7 @@
// Output.
write_text_graph();
- write_snapshots();
+ write_detailed_snapshots();
// Stats
if (VG_(clo_verbosity) > 1) {
@@ -1645,10 +1721,11 @@
}
}
-/*------------------------------------------------------------*/
-/*--- Initialisation ---*/
-/*------------------------------------------------------------*/
+//------------------------------------------------------------//
+//--- Initialisation ---//
+//------------------------------------------------------------//
+
static void ms_post_clo_init(void)
{
Int i;
@@ -1658,8 +1735,6 @@
VG_(message)(Vg_DebugMsg, " %d: %s", i, alloc_fns[i]);
}
}
-
- ms_interval = 5;
// We don't take a snapshot now, because there's still some core
// initialisation to do, in which case we have an artificial gap.
@@ -1669,6 +1744,8 @@
static void ms_pre_clo_init(void)
{
+ Int i;
+
VG_(details_name) ("Massif");
VG_(details_version) (NULL);
VG_(details_description) ("a space profiler");
@@ -1686,6 +1763,8 @@
ms_print_usage,
ms_print_debug_usage);
VG_(needs_client_requests) (ms_handle_client_request);
+ VG_(needs_sanity_checks) (ms_cheap_sanity_check,
+ ms_expensive_sanity_check);
VG_(needs_malloc_replacement) (ms_malloc,
ms___builtin_new,
ms___builtin_vec_new,
@@ -1707,13 +1786,17 @@
// Dummy node at top of the context structure.
alloc_xpt = new_XPt(/*ip*/0, /*parent*/NULL);
+ // Initialise snapshot array, and sanity check it.
+ for (i = 0; i < MAX_N_SNAPSHOTS; i++) {
+ clear_snapshot( & snapshots[i] );
+ }
+ sanity_check_snapshots_array();
+
tl_assert( VG_(getcwd)(base_dir, VKI_PATH_MAX) );
}
VG_DETERMINE_INTERFACE_VERSION(ms_pre_clo_init)
-/*--------------------------------------------------------------------*/
-/*--- end ---*/
-/*--------------------------------------------------------------------*/
-
-
+//--------------------------------------------------------------------//
+//--- end ---//
+//--------------------------------------------------------------------//
|
|
From: Tom H. <th...@cy...> - 2007-03-29 02:31:45
|
Nightly build on alvis ( i686, Red Hat 7.3 ) started at 2007-03-29 03:15:02 BST Results unchanged from 24 hours ago Checking out valgrind source tree ... done Configuring valgrind ... done Building valgrind ... done Running regression tests ... failed Regression test results follow == 256 tests, 27 stderr failures, 1 stdout failure, 0 posttest failures == memcheck/tests/addressable (stderr) memcheck/tests/badjump (stderr) memcheck/tests/describe-block (stderr) memcheck/tests/erringfds (stderr) memcheck/tests/leak-0 (stderr) memcheck/tests/leak-cycle (stderr) memcheck/tests/leak-pool-0 (stderr) memcheck/tests/leak-pool-1 (stderr) memcheck/tests/leak-pool-2 (stderr) memcheck/tests/leak-pool-3 (stderr) memcheck/tests/leak-pool-4 (stderr) memcheck/tests/leak-pool-5 (stderr) memcheck/tests/leak-regroot (stderr) memcheck/tests/leak-tree (stderr) memcheck/tests/long_namespace_xml (stderr) memcheck/tests/match-overrun (stderr) memcheck/tests/partial_load_dflt (stderr) memcheck/tests/partial_load_ok (stderr) memcheck/tests/partiallydefinedeq (stderr) memcheck/tests/pointer-trace (stderr) memcheck/tests/sigkill (stderr) memcheck/tests/stack_changes (stderr) memcheck/tests/x86/scalar (stderr) memcheck/tests/x86/scalar_supp (stderr) memcheck/tests/x86/xor-undef-x86 (stderr) memcheck/tests/xml1 (stderr) none/tests/mremap (stderr) none/tests/mremap2 (stdout) |
|
From: Tom H. <th...@cy...> - 2007-03-29 02:25:18
|
Nightly build on dellow ( x86_64, Fedora Core 6 ) started at 2007-03-29 03:10:34 BST Results unchanged from 24 hours ago Checking out valgrind source tree ... done Configuring valgrind ... done Building valgrind ... done Running regression tests ... failed Regression test results follow == 291 tests, 4 stderr failures, 2 stdout failures, 0 posttest failures == memcheck/tests/pointer-trace (stderr) memcheck/tests/x86/scalar (stderr) memcheck/tests/xml1 (stderr) none/tests/mremap (stderr) none/tests/mremap2 (stdout) none/tests/pth_detached (stdout) |
|
From: Tom H. <th...@cy...> - 2007-03-29 02:20:01
|
Nightly build on lloyd ( x86_64, Fedora Core 3 ) started at 2007-03-29 03:05:10 BST Results unchanged from 24 hours ago Checking out valgrind source tree ... done Configuring valgrind ... done Building valgrind ... done Running regression tests ... failed Regression test results follow == 291 tests, 6 stderr failures, 1 stdout failure, 0 posttest failures == memcheck/tests/pointer-trace (stderr) memcheck/tests/stack_switch (stderr) memcheck/tests/x86/scalar (stderr) memcheck/tests/x86/scalar_supp (stderr) memcheck/tests/xml1 (stderr) none/tests/mremap (stderr) none/tests/mremap2 (stdout) |
|
From: Tom H. <th...@cy...> - 2007-03-29 02:12:59
|
Nightly build on gill ( x86_64, Fedora Core 2 ) started at 2007-03-29 03:00:07 BST Results unchanged from 24 hours ago Checking out valgrind source tree ... done Configuring valgrind ... done Building valgrind ... done Running regression tests ... failed Regression test results follow == 293 tests, 6 stderr failures, 1 stdout failure, 0 posttest failures == memcheck/tests/pointer-trace (stderr) memcheck/tests/stack_switch (stderr) memcheck/tests/x86/scalar (stderr) memcheck/tests/x86/scalar_supp (stderr) none/tests/fdleak_fcntl (stderr) none/tests/mremap (stderr) none/tests/mremap2 (stdout) |
|
From: <sv...@va...> - 2007-03-29 02:10:48
|
Author: njn
Date: 2007-03-29 03:10:37 +0100 (Thu, 29 Mar 2007)
New Revision: 6685
Log:
- Fix stupid bug.
- Take more snapshots.
- Add a note.
Modified:
branches/MASSIF2/massif/ms_main.c
Modified: branches/MASSIF2/massif/ms_main.c
===================================================================
--- branches/MASSIF2/massif/ms_main.c 2007-03-28 23:26:18 UTC (rev 6684)
+++ branches/MASSIF2/massif/ms_main.c 2007-03-29 02:10:37 UTC (rev 6685)
@@ -32,7 +32,11 @@
// XXX:
//---------------------------------------------------------------------------
// Next:
+// - sanity check: do the periodic core-based one, check the main XTree but
+// not the individual snapshots, since they're checked when taken and
+// printed.
// - print percentages/sizes in "the rest" entries
+// - show 2nd decimal point (only if threshold is below 10, ie. 0.1%?)
// - truncate really long file names [hmm, could make getting the name of
// alloc-fns more difficult]
// - Check MALLOCLIKE_BLOCK works, write regtest
@@ -296,8 +300,8 @@
// XXX: if the program is really short, we may get no detailed snapshots...
// that's bad, do something about it.
-#define MAX_N_SNAPSHOTS 50 // Keep it even, for simplicity
-#define DETAILED_SNAPSHOT_FREQ 2 // Every Nth snapshot will be detailed
+#define MAX_N_SNAPSHOTS 100 // Keep it even, for simplicity
+#define DETAILED_SNAPSHOT_FREQ 10 // Every Nth snapshot will be detailed
typedef
struct {
@@ -1211,10 +1215,7 @@
static void* ms_realloc ( ThreadId tid, void* p_old, SizeT new_szB )
{
-// return renew_block(tid, p_old, new_size);
- die_block( p_old, /*custom_free*/False );
- return new_block( tid, NULL, new_szB, VG_(clo_alignment),
- /*is_zeroed*/False );
+ return renew_block(tid, p_old, new_szB);
}
|
|
From: <js...@ac...> - 2007-03-29 00:16:17
|
Nightly build on g5 ( SuSE 10.1, ppc970 ) started at 2007-03-29 02:00:01 CEST Results unchanged from 24 hours ago Checking out valgrind source tree ... done Configuring valgrind ... done Building valgrind ... done Running regression tests ... failed Regression test results follow == 226 tests, 6 stderr failures, 2 stdout failures, 0 posttest failures == memcheck/tests/deep_templates (stdout) memcheck/tests/leak-cycle (stderr) memcheck/tests/leak-tree (stderr) memcheck/tests/pointer-trace (stderr) none/tests/faultstatus (stderr) none/tests/fdleak_cmsg (stderr) none/tests/mremap (stderr) none/tests/mremap2 (stdout) |
|
From: <sv...@va...> - 2007-03-28 23:26:22
|
Author: njn
Date: 2007-03-29 00:26:18 +0100 (Thu, 29 Mar 2007)
New Revision: 6684
Log:
- Fix bugs. Sanity checking complex data structures is a good idea.
- Added --threshold option, to control how much of the trees you see.
- (Temporary): showing the final global XTree at the end.
Modified:
branches/MASSIF2/massif/ms_main.c
Modified: branches/MASSIF2/massif/ms_main.c
===================================================================
--- branches/MASSIF2/massif/ms_main.c 2007-03-28 13:17:18 UTC (rev 6683)
+++ branches/MASSIF2/massif/ms_main.c 2007-03-28 23:26:18 UTC (rev 6684)
@@ -32,6 +32,7 @@
// XXX:
//---------------------------------------------------------------------------
// Next:
+// - print percentages/sizes in "the rest" entries
// - truncate really long file names [hmm, could make getting the name of
// alloc-fns more difficult]
// - Check MALLOCLIKE_BLOCK works, write regtest
@@ -84,6 +85,7 @@
// - there's a gap between the ms timer initialisation during Valgrind
// start-up and our first use of it. Could normalise versus our first
// use...
+// - could conceivably remove XPts that have their szB reduced to zero.
//
// Docs:
// - need to explain that --alloc-fn changed slightly -- now if an entry
@@ -292,8 +294,10 @@
// This isn't exactly right, because we actually drop (N/2)-1 when halving,
// but it shows the basic idea.
+// XXX: if the program is really short, we may get no detailed snapshots...
+// that's bad, do something about it.
#define MAX_N_SNAPSHOTS 50 // Keep it even, for simplicity
-#define DETAILED_SNAPSHOT_FREQ 10 // Every Nth snapshot will be detailed
+#define DETAILED_SNAPSHOT_FREQ 2 // Every Nth snapshot will be detailed
typedef
struct {
@@ -355,6 +359,8 @@
#define FILENAME_LEN 256
+#define P VG_(printf)
+
#define SPRINTF(zz_buf, fmt, args...) \
do { Int len = VG_(sprintf)(zz_buf, fmt, ## args); \
VG_(write)(fd, (void*)zz_buf, len); \
@@ -409,15 +415,18 @@
static UInt clo_heap_admin = 8;
static Bool clo_stacks = True;
static Bool clo_depth = 8;
+static UInt clo_threshold = 100; // 100 == 1%
static Bool ms_process_cmd_line_option(Char* arg)
{
VG_BOOL_CLO(arg, "--heap", clo_heap)
else VG_BOOL_CLO(arg, "--stacks", clo_stacks)
- else VG_NUM_CLO (arg, "--heap-admin", clo_heap_admin)
- else VG_BNUM_CLO(arg, "--depth", clo_depth, 1, MAX_DEPTH)
+ else VG_NUM_CLO (arg, "--heap-admin", clo_heap_admin)
+ else VG_BNUM_CLO(arg, "--depth", clo_depth, 1, MAX_DEPTH)
+ else VG_NUM_CLO(arg, "--threshold", clo_threshold)
+
else if (VG_CLO_STREQN(11, arg, "--alloc-fn=")) {
int i;
@@ -450,6 +459,9 @@
" --stacks=no|yes profile stack(s) [yes]\n"
" --depth=<number> depth of contexts [8]\n"
" --alloc-fn=<name> specify <fn> as an alloc function [empty]\n"
+" --threshold=<n> significance threshold, in 100ths of a percent\n"
+" (eg. <n>=100 shows nodes covering >= 1%% of\n"
+" total size, <n>=0 shows all nodes) [100]\n"
);
VG_(replacement_malloc_print_usage)();
}
@@ -740,6 +752,61 @@
/*------------------------------------------------------------*/
+/*--- Sanity checking ---*/
+/*------------------------------------------------------------*/
+
+__attribute__((unused))
+static void pp_XPt(XPt* xpt)
+{
+ Int i;
+ P("XPt (%p):\n", xpt);
+ P("- ip: : %p\n", (void*)xpt->ip);
+ P("- curr_szB : %ld\n", xpt->curr_szB);
+ P("- parent : %p\n", xpt->parent);
+ P("- n_children : %d\n", xpt->n_children);
+ P("- max_children: %d\n", xpt->max_children);
+ for (i = 0; i < xpt->n_children; i++) {
+ P("- children[%2d]: %p\n", i, xpt->children[i]);
+ }
+}
+
+static void sanity_check_XTree(XPt* xpt, XPt* parent)
+{
+ Int i;
+ SizeT children_sum_szB = 0;
+
+ if (NULL == xpt)
+ return;
+
+ // Check back-pointer.
+ tl_assert2(xpt->parent == parent,
+ "xpt->parent = %p, parent = %p\n", xpt->parent, parent);
+
+ // Check children counts look sane.
+ tl_assert(xpt->n_children <= xpt->max_children);
+
+ // Check the sum of any children szBs equals the XPt's szB.
+ if (xpt->n_children > 0) {
+ for (i = 0; i < xpt->n_children; i++) {
+ children_sum_szB += xpt->children[i]->curr_szB;
+ }
+ tl_assert(children_sum_szB == xpt->curr_szB);
+ }
+
+ // Check each child.
+ for (i = 0; i < xpt->n_children; i++) {
+ sanity_check_XTree(xpt->children[i], xpt);
+ }
+}
+
+static void sanity_check_snapshot(Snapshot* snapshot)
+{
+ tl_assert(snapshot->total_szB ==
+ snapshot->heap_admin_szB + snapshot->heap_szB + snapshot->stacks_szB);
+ sanity_check_XTree(snapshot->alloc_xpt, /*parent*/NULL);
+}
+
+/*------------------------------------------------------------*/
/*--- Taking a snapshot ---*/
/*------------------------------------------------------------*/
@@ -823,18 +890,18 @@
// XXX: taking a full snapshot... could/should just snapshot the significant
// parts. Nb: then the amounts wouldn't add up, unless I represented the
// "other insignificant places" in XPts.
-static XPt* dup_XTree(XPt* xpt)
+static XPt* dup_XTree(XPt* xpt, XPt* parent)
{
Int i;
XPt* dup_xpt = VG_(malloc)(sizeof(XPt));
dup_xpt->ip = xpt->ip;
dup_xpt->curr_szB = xpt->curr_szB;
- dup_xpt->parent = xpt->parent;
+ dup_xpt->parent = parent; // Nb: not xpt->children!
dup_xpt->n_children = xpt->n_children;
dup_xpt->max_children = xpt->n_children; // Nb: don't copy max_children!
dup_xpt->children = VG_(malloc)(dup_xpt->max_children * sizeof(XPt*));
for (i = 0; i < xpt->n_children; i++) {
- dup_xpt->children[i] = dup_XTree(xpt->children[i]);
+ dup_xpt->children[i] = dup_XTree(xpt->children[i], dup_xpt);
}
n_dupd_xpts++;
@@ -885,7 +952,8 @@
snapshot->heap_szB = heap_szB;
// Take a detailed snapshot if it's been long enough since the last one.
if (DETAILED_SNAPSHOT_FREQ == n_snapshots_since_last_detailed) {
- snapshot->alloc_xpt = dup_XTree(alloc_xpt);
+ snapshot->alloc_xpt = dup_XTree(alloc_xpt, /*parent*/NULL);
+ tl_assert(snapshot->alloc_xpt->curr_szB == heap_szB);
n_snapshots_since_last_detailed = 0;
} else {
n_snapshots_since_last_detailed++;
@@ -913,6 +981,9 @@
snapshot->total_szB =
snapshot->heap_szB + snapshot->heap_admin_szB + snapshot->stacks_szB;
+ // Sanity-check it.
+ sanity_check_snapshot(snapshot);
+
// Update peak data -------------------------------------------------
// XXX: this is not really the right way to do peak data -- it's only
// peak snapshot data, the true peak could be between snapshots.
@@ -963,29 +1034,29 @@
}
static
-void* new_block ( ThreadId tid, void* p, SizeT size, SizeT align,
+void* new_block ( ThreadId tid, void* p, SizeT szB, SizeT alignB,
Bool is_zeroed )
{
HP_Chunk* hc;
Bool custom_alloc = (NULL == p);
- if (size < 0) return NULL;
+ if (szB < 0) return NULL;
// Update statistics
n_allocs++;
- if (0 == size) n_zero_allocs++;
+ if (0 == szB) n_zero_allocs++;
// Allocate and zero if necessary
if (!p) {
- p = VG_(cli_malloc)( align, size );
+ p = VG_(cli_malloc)( alignB, szB );
if (!p) {
return NULL;
}
- if (is_zeroed) VG_(memset)(p, 0, size);
+ if (is_zeroed) VG_(memset)(p, 0, szB);
}
// Make new HP_Chunk node, add to malloc_list
hc = VG_(malloc)(sizeof(HP_Chunk));
- hc->szB = size;
+ hc->szB = szB;
hc->data = (Addr)p;
hc->where = NULL; // paranoia
@@ -995,7 +1066,7 @@
// Update XTree, if necessary
if (clo_heap) {
hc->where = get_XCon( tid, custom_alloc );
- update_XCon(hc->where, size);
+ update_XCon(hc->where, szB);
}
VG_(HT_add_node)(malloc_list, hc);
@@ -1098,29 +1169,29 @@
/*--- malloc() et al replacement wrappers ---*/
/*------------------------------------------------------------*/
-static void* ms_malloc ( ThreadId tid, SizeT n )
+static void* ms_malloc ( ThreadId tid, SizeT szB )
{
- return new_block( tid, NULL, n, VG_(clo_alignment), /*is_zeroed*/False );
+ return new_block( tid, NULL, szB, VG_(clo_alignment), /*is_zeroed*/False );
}
-static void* ms___builtin_new ( ThreadId tid, SizeT n )
+static void* ms___builtin_new ( ThreadId tid, SizeT szB )
{
- return new_block( tid, NULL, n, VG_(clo_alignment), /*is_zeroed*/False );
+ return new_block( tid, NULL, szB, VG_(clo_alignment), /*is_zeroed*/False );
}
-static void* ms___builtin_vec_new ( ThreadId tid, SizeT n )
+static void* ms___builtin_vec_new ( ThreadId tid, SizeT szB )
{
- return new_block( tid, NULL, n, VG_(clo_alignment), /*is_zeroed*/False );
+ return new_block( tid, NULL, szB, VG_(clo_alignment), /*is_zeroed*/False );
}
-static void* ms_calloc ( ThreadId tid, SizeT m, SizeT size )
+static void* ms_calloc ( ThreadId tid, SizeT m, SizeT szB )
{
- return new_block( tid, NULL, m*size, VG_(clo_alignment), /*is_zeroed*/True );
+ return new_block( tid, NULL, m*szB, VG_(clo_alignment), /*is_zeroed*/True );
}
-static void *ms_memalign ( ThreadId tid, SizeT align, SizeT n )
+static void *ms_memalign ( ThreadId tid, SizeT alignB, SizeT szB )
{
- return new_block( tid, NULL, n, align, False );
+ return new_block( tid, NULL, szB, alignB, False );
}
static void ms_free ( ThreadId tid, void* p )
@@ -1138,9 +1209,12 @@
die_block( p, /*custom_free*/False );
}
-static void* ms_realloc ( ThreadId tid, void* p_old, SizeT new_size )
+static void* ms_realloc ( ThreadId tid, void* p_old, SizeT new_szB )
{
- return renew_block(tid, p_old, new_size);
+// return renew_block(tid, p_old, new_size);
+ die_block( p_old, /*custom_free*/False );
+ return new_block( tid, NULL, new_szB, VG_(clo_alignment),
+ /*is_zeroed*/False );
}
@@ -1168,10 +1242,11 @@
switch (argv[0]) {
case VG_USERREQ__MALLOCLIKE_BLOCK: {
void* res;
- void* p = (void*)argv[1];
- SizeT sizeB = argv[2];
- *ret = 0;
- res = new_block( tid, p, sizeB, /*align--ignored*/0, /*is_zeroed*/False );
+ void* p = (void*)argv[1];
+ SizeT szB = argv[2];
+ *ret = 0;
+ res =
+ new_block( tid, p, szB, /*alignB--ignored*/0, /*is_zeroed*/False );
tl_assert(res == p);
return True;
}
@@ -1232,8 +1307,6 @@
}
#endif
-#define P VG_(printf)
-
static void write_text_graph(void)
{
Int i;
@@ -1373,6 +1446,8 @@
static Char* make_perc(ULong x, ULong y)
{
static Char mbuf[32];
+
+// tl_assert(x <= y); XXX; put back in later...
// XXX: I'm not confident that VG_(percentify) works as it should...
VG_(percentify)(x, y, 1, 5, mbuf);
@@ -1386,7 +1461,12 @@
// XXX: make command-line controllable?
static Bool is_significant_XPt(XPt* xpt, SizeT curr_total_szB)
{
- return (xpt->curr_szB * 1000 / curr_total_szB >= 10); // < 1%?
+ // clo_threshold is measured in hundredths of a percent of total size,
+ // ie. 10,000ths of total size. So clo_threshold=100 means that the
+ // threshold is 1% of total size.
+ tl_assert(xpt->curr_szB <= curr_total_szB);
+ // XXX: overflow danger here...
+ return (xpt->curr_szB * 10000 / curr_total_szB >= clo_threshold);
}
static void pp_snapshot_child_XPts(XPt* parent, Int depth, Char* depth_str,
@@ -1404,6 +1484,7 @@
children_sum_szB += parent->children[i]->curr_szB;
}
tl_assert(children_sum_szB == parent->curr_szB);
+// VG_(printf)("szB = %,ld B\n", children_sum_szB);
// Sort children by curr_szB (reverse order: biggest to smallest)
// XXX: is it better to keep them always in order?
@@ -1424,7 +1505,7 @@
// This child is significant. Print it.
perc = make_perc(child->curr_szB, curr_total_szB);
ip_desc = VG_(describe_IP)(child->ip-1, buf2, BUF_LEN);
- P("->%6s: %s\n", perc, ip_desc);
+ P("->%6s(%,ldB): %s\n", perc, child->curr_szB, ip_desc);
// If the child has any children, print them. But first add the
// prefix for them, which is " " if the parent has no smaller
@@ -1472,6 +1553,8 @@
Int depth_str_len = clo_depth * 2 + 2;
Char* depth_str = VG_(malloc)(sizeof(Char) * depth_str_len);
depth_str[0] = '\0'; // Initialise to "".
+
+ sanity_check_snapshot(snapshot);
P("=================================\n");
P("== snapshot %d\n", snapshot_n);
@@ -1491,11 +1574,12 @@
P("(No heap memory currently allocated)\n");
} else {
P("Heap tree:\n");
- P("%6s: (heap allocation functions) malloc/new/new[],"
- " --alloc-fn functions, etc.\n",
- make_perc(snapshot->heap_szB, snapshot->total_szB));
+ P("%6s(%,ldB): (heap allocation functions) malloc/new/new[],"
+ " --alloc-fns, etc.\n",
+ make_perc(snapshot->heap_szB, snapshot->total_szB),
+ snapshot->heap_szB);
- pp_snapshot_child_XPts(alloc_xpt, 0, depth_str, depth_str_len,
+ pp_snapshot_child_XPts(snapshot->alloc_xpt, 0, depth_str, depth_str_len,
snapshot->heap_szB, snapshot->total_szB);
}
@@ -1505,12 +1589,26 @@
static void write_snapshots(void)
{
Int i;
+
+ // XXX: temporary
+ Int depth_str_len = clo_depth * 2 + 2;
+ Char* depth_str = VG_(malloc)(sizeof(Char) * depth_str_len);
+ depth_str[0] = '\0'; // Initialise to "".
+
for (i = 0; i < curr_snapshot; i++) {
Snapshot* snapshot = & snapshots[i];
if (snapshot->alloc_xpt) {
pp_snapshot(snapshot, i); // Detailed snapshot!
}
}
+ P("=================================\n");
+ P("== main XTree\n");
+ P("=================================\n");
+ P("heap szB: %ld\n", heap_szB);
+ pp_snapshot_child_XPts(alloc_xpt, 0, depth_str, depth_str_len,
+ heap_szB, 999999);
+
+ VG_(free)(depth_str);
}
/*------------------------------------------------------------*/
|
|
From: Nicholas N. <nj...@cs...> - 2007-03-28 22:04:49
|
On Wed, 28 Mar 2007, Vince Weaver wrote: > I've just released the simpoint tool: > > http://www.csl.cornell.edu/~vince/projects/valsim/ > I'm working right now on writing up all the results of the validation > effort. Nice. I'd be interested to see the paper when it's done. You do things at the superblock level rather than the basic block level because Valgrind uses superblocks. I think if you use --vex-guest-chase-thresh=0 it will not chase across branches and thus will effectively do things at a basic block level. At least, that's what the comments for VexControl in VEX/pub/libvex.h seem to indicate -- Julian, is that right? (You could write another paper comparing accuracy of BBs vs SBs in SimPoint tools ;) You might then want to increase --vex-guest-max-insns to allow BBs to be as big as possible (at least bigger than 50, which is the default maximum). Nick |
|
From: Nicholas N. <nj...@cs...> - 2007-03-28 21:54:16
|
On Wed, 28 Mar 2007, Josef Weidendorfer wrote: > On Wednesday 28 March 2007, you wrote: >> Welcome. If you get any speedups as a result of these tricks I'd >> be interested to hear about them, because the main valgrind dispatcher >> (m_dispatch) suffers from exactly the same problem. > > I thought that SB chaining reduces the problem here, does it? It would, if Valgrind did it :) It used to (in the UCode days), but it hasn't been implemented for Vex yet. Vex does chase across some unconditional branches, though. Nick |
|
From: Nicholas N. <nj...@cs...> - 2007-03-28 21:48:30
|
On Thu, 29 Mar 2007, Yao Qi wrote: > I am playing with helgrind on data race detection, and want to implement > my data race detection in the framework of helgrind. > > I find that hg_thread_create and hg_thread_join is "hooked" to > VG_(track_post_thread_create) and VG_(track_post_thread_join) > respectively. One point confused me is how VG_(track_post_thread_join) > is called? I could find the location invoke > VG_(track_post_thread_create), but I could not find any thing call this > function. I set breakpoint on hg_thread_join in gdb, and the helgrind > does not hit this breakpoint either. > > Am I missing something? Thanks. These functions are called via functions pointers. The names depend on which version you're using, but look at the code within VG_(track_post_thread_create) to see where the function pointer is being assigned. Also beware that the point where the function pointer is called may involve macros, and so the names might not match up exactly. Nick |