|
From: apenwarr - 2003-11-30 04:42:09
|
The attached C program produces the attached valgrind output when run with
"valgrind --leak-check=yes".
I think valgrind shouldn't bother to do leak checking when a task exits with
_exit(), since the writer of that program "obviously" didn't intend to clean
up the subtask properly anyway. (If you clean up your objects in the child
task, for example by calling destructors on objects, all heck will generally
break loose because file descriptors are shared with the parent, who still
thinks those objects exist.)
My needs would also be met if I could simply tell valgrind to not follow
forks, since I'm really concerned with grinding my parent task, here.
Suggestions?
Have fun,
Avery
...
The program:
#include <malloc.h>
int main()
{
void *x = malloc(5);
if (!fork()) // child
_exit(0);
// else, this is the parent
free(x);
return 0;
}
...
The valgrind output:
==32117== Memcheck, a.k.a. Valgrind, a memory error detector for x86-linux.
==32117== Copyright (C) 2002-2003, and GNU GPL'd, by Julian Seward.
==32117== Using valgrind-2.0.0, a program supervision framework for x86-linux.
==32117== Copyright (C) 2000-2003, and GNU GPL'd, by Julian Seward.
==32117== Estimated CPU clock rate is 1209 MHz
==32117== For more details, rerun with: -v
==32117==
==32121==
==32121== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
==32121== malloc/free: in use at exit: 5 bytes in 1 blocks.
==32121== malloc/free: 1 allocs, 0 frees, 5 bytes allocated.
==32121== For counts of detected errors, rerun with: -v
==32121== searching for pointers to 1 not-freed blocks.
==32117==
==32117== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
==32117== malloc/free: in use at exit: 0 bytes in 0 blocks.
==32117== malloc/free: 1 allocs, 1 frees, 5 bytes allocated.
==32117== For counts of detected errors, rerun with: -v
==32117== No malloc'd blocks -- no leaks are possible.
==32121== checked 3649016 bytes.
==32121==
==32121== LEAK SUMMARY:
==32121== definitely lost: 0 bytes in 0 blocks.
==32121== possibly lost: 0 bytes in 0 blocks.
==32121== still reachable: 5 bytes in 1 blocks.
==32121== suppressed: 0 bytes in 0 blocks.
==32121== Reachable blocks (those to which a pointer was found) are not shown.
==32121== To see them, rerun with: --show-reachable=yes
==32121==
|
|
From: Nicholas N. <nj...@ca...> - 2003-11-30 10:16:53
|
On Sat, 29 Nov 2003 apenwarr@unspecified-domain wrote:
> The attached C program produces the attached valgrind output when run with
> "valgrind --leak-check=yes".
>
> I think valgrind shouldn't bother to do leak checking when a task exits with
> _exit(), since the writer of that program "obviously" didn't intend to clean
> up the subtask properly anyway. (If you clean up your objects in the child
> task, for example by calling destructors on objects, all heck will generally
> break loose because file descriptors are shared with the parent, who still
> thinks those objects exist.)
I disagree. There is an important difference between true space leaks,
and memory that you just didn't bother to free ("reachable"). Even
programs that call _exit() shouldn't have true space leaks. And a few
lines of output showing memory that was reachable doesn't seem like a big
inconvenience. In this example, Memcheck distinguishes the two cases
exactly how I would want and expect it to.
> My needs would also be met if I could simply tell valgrind to not follow
> forks, since I'm really concerned with grinding my parent task, here.
Not possible with the current design, unfortunately, since Valgrind
becomes part of the process, and so is unavoidably duplicated when the
kernel replicates the process via fork().
N
|
|
From: Avery P. <ape...@ni...> - 2003-11-30 18:18:01
|
On Sun, Nov 30, 2003 at 10:16:51AM +0000, Nicholas Nethercote wrote:
> I disagree. There is an important difference between true space leaks,
> and memory that you just didn't bother to free ("reachable"). Even
> programs that call _exit() shouldn't have true space leaks. And a few
> lines of output showing memory that was reachable doesn't seem like a big
> inconvenience. In this example, Memcheck distinguishes the two cases
> exactly how I would want and expect it to.
In this particular case, I want to suppress scary-looking output (ie.
anything from valgrind) because it happens in the middle of my unit tests,
and scary-looking output from my unit tests should constitute a bug, not a
bonus valgrind feature :)
> > My needs would also be met if I could simply tell valgrind to not follow
> > forks, since I'm really concerned with grinding my parent task, here.
>
> Not possible with the current design, unfortunately, since Valgrind
> becomes part of the process, and so is unavoidably duplicated when the
> kernel replicates the process via fork().
Can I "turn off valgrind" with a special valgrind client request somehow? I
don't mind running that in my subtask. Or even a
"valgrind_dont_report_on_exit" request?
Thanks,
Avery
|
|
From: Nicholas N. <nj...@ca...> - 2003-12-01 14:10:42
|
On Sun, 30 Nov 2003, Avery Pennarun wrote:
> > I disagree. There is an important difference between true space leaks,
> > and memory that you just didn't bother to free ("reachable"). Even
> > programs that call _exit() shouldn't have true space leaks. And a few
> > lines of output showing memory that was reachable doesn't seem like a big
> > inconvenience. In this example, Memcheck distinguishes the two cases
> > exactly how I would want and expect it to.
>
> In this particular case, I want to suppress scary-looking output (ie.
> anything from valgrind) because it happens in the middle of my unit tests,
> and scary-looking output from my unit tests should constitute a bug, not a
> bonus valgrind feature :)
Are you using -q? In that case, I think you do not want Valgrind to not
leak-check fork() children, but to just be quieter, and only print a
message if there is a genuine leak. Is that right?
N
|
|
From: Avery P. <ape...@ni...> - 2003-12-01 17:48:39
|
On Mon, Dec 01, 2003 at 02:10:38PM +0000, Nicholas Nethercote wrote: > On Sun, 30 Nov 2003, Avery Pennarun wrote: > > In this particular case, I want to suppress scary-looking output (ie. > > anything from valgrind) because it happens in the middle of my unit > > tests, and scary-looking output from my unit tests should constitute a > > bug, not a bonus valgrind feature :) > > Are you using -q? In that case, I think you do not want Valgrind to not > leak-check fork() children, but to just be quieter, and only print a > message if there is a genuine leak. Is that right? Hmm, I feel a bit silly that I didn't think of using -q. Now I tried it, and it still doesn't quite work the way I want: in fact, I don't think I want "quietness" so much, because I like having the valgrind banner at the top and bottom reminding me that I am, in fact, running valgrind. I agree with you about the different kinds of memory leaks. In this case, I guess I *do* want to hear about "really lost" memory, but not about "still accessible non-freed" memory... in the subprocess. In the main process, I want to hear about both, and it seems that using '-q' gets rid of the memory final summary altogether, even if there are leaks. (If I add --leak-check=yes, then I get both the parent and subtasks' summaries.) Hmm, I'm not sure what I want. Maybe I want a summary even if -q is enabled, but *only* if errors were detected. And then a way to auto-enable -q in a subtask but not in my main task? Have fun, Avery |
|
From: Olly B. <ol...@su...> - 2003-12-01 18:57:54
|
On Mon, Dec 01, 2003 at 12:48:36PM -0500, Avery Pennarun wrote:
> Hmm, I'm not sure what I want. Maybe I want a summary even if -q is
> enabled, but *only* if errors were detected. And then a way to auto-enable
> -q in a subtask but not in my main task?
Unfortunately to satisfy everyone valgrind would end up with dozens of output
verbosity options, which would make it harder to find the options you wanted
(the --help output is already a bit daunting).
My approach to controlling the output shown by valgrind in a test
harness is to call valgrind with --logfile-fd=255 (from the test suite
makefile or script). Then in the test harness (which links to each
test program) I send fd 255 to a scratch file:
#define LOG_FD_FOR_VG 255
[...]
if (verbose && RUNNING_ON_VALGRIND) {
/* Open a temporary file for valgrind to log to. */
FILE * f = tmpfile();
if (f) {
int fd = fileno(f);
if (fd != -1) {
fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_APPEND);
if (fd != LOG_FD_FOR_VG) {
dup2(fd, LOG_FD_FOR_VG);
fclose(f);
}
}
}
}
Then I can filter the output as I want (read from the file and send selected
lines to stdout or stderr), or discard it (with ftruncate(LOG_FD_FOR_VG, 0);).
For example, I only show valgrind's output if a test fails and the test harness
is running in verbose mode.
You could probably open a pipe on fd 255 but you might run into buffering
problems (buffering output yourself is problematic because valgrind sees the
buffer as memory that is allocated but not released, and the OS buffer for
the pipe is of finite size).
The full (GPLed) code is here. It's mixed in with the other test harness
code, but searching for HAVE_VALGRIND will find the valgrind relevant bits:
http://cvs.xapian.org/xapian/xapian-core/testsuite/testsuite.cc?rev=1.100&content-type=text/vnd.viewcvs-markup
Here's the wrapper script to launch each test program:
http://cvs.xapian.org/xapian/xapian-core/tests/runtest.in?rev=1.3&content-type=text/vnd.viewcvs-markup
Cheers,
Olly
|
|
From: Nicholas N. <nj...@ca...> - 2003-12-02 03:31:34
|
On Mon, 1 Dec 2003, Avery Pennarun wrote: > Hmm, I'm not sure what I want. Maybe I want a summary even if -q is > enabled, but *only* if errors were detected. And then a way to auto-enable > -q in a subtask but not in my main task? The intended behaviour with -q is that only errors get printed; no summaries. Currently --leak-check doesn't follow that, because you still get the "searching for pointers...", "checked N bytes" lines, plus the leak summary, when -q is specified. It should be changed, and I'll probably do so, maybe tomorrow. N |