|
From: Kyle M. <kyl...@gm...> - 2013-02-28 22:56:39
|
Hi all, I'm wondering if it's possible for memcheck to show the last place
that some memory was accessible before being leaked. For example, I would
like to see the line numbers for both "allocated here" and "leaked here" in
the example below.
int* g() {
int* x = new int[256]; <-- allocated here
...
return x;
}
int f() {
int* x = g();
...
return 0; <-- leaked here
}
Thanks!
Kyle
|
|
From: Philippe W. <phi...@sk...> - 2013-03-01 00:12:17
|
On Thu, 2013-02-28 at 14:53 -0800, Kyle Mahan wrote:
> Hi all, I'm wondering if it's possible for memcheck to show the last
> place that some memory was accessible before being leaked. For
> example, I would like to see the line numbers for both "allocated
> here" and "leaked here" in the example below.
>
>
> int* g() {
> int* x = new int[256]; <-- allocated here
> ...
> return x;
> }
>
>
> int f() {
>
> int* x = g();
> ...
>
> return 0; <-- leaked here
>
> }
No, this is not supported.
IIRC, there was an experimental tool (omega ?)
that was trying to do that. To my knowledge, there were some
conceptual problems in it but I do not know the details.
Philippe
|
|
From: Dan K. <da...@ke...> - 2013-03-01 00:17:42
|
On Thu, Feb 28, 2013 at 3:28 PM, Philippe Waroquiers <phi...@sk...> wrote: > IIRC, there was an experimental tool (omega ?) > that was trying to do that. And here I thought it was a Galaxy Quest reference... |
|
From: John R. <jr...@bi...> - 2013-03-01 03:14:02
|
> Hi all, I'm wondering if it's possible for memcheck to show the last place that some memory was accessible before being leaked.
The current implementation of memcheck cannot do this.
Reporting the location of the leak for each leak
would take a major re-think of memcheck. It would be
easier to report the location of only the *last* leak.
(If there were 500 leaks then you could find them all
by running the tool 500 times, fixing them one-by-one
as you go. And if you couldn't fix a particular last
leak at some point, then you would be stuck; the tool
could not pinpoint any more leaks for you.)
If allocation and freeing were "stable" with respect
to re-running the program, then a two-pass procedure
would be almost easy. (It would take *lots* of disk
space, but it would be easy.) Unfortunately "stable"
is not as common as one might hope.
In your example below the difficulty lies in the code that has been elided
by the ellipses "...". If there are any assignments of x to other pointers,
or if x is passed as an actual argument of a function call, then it is hard
to determine whether a leak occurs.
>
> int* g() {
> int* x = new int[256]; <-- allocated here
> ...
> return x;
> }
>
> int f() {
> int* x = g();
> ...
> return 0; <-- leaked here
> }
>
--
|
|
From: David C. <dcc...@ac...> - 2013-03-01 07:48:07
|
On 2/28/2013 4:58 PM, John Reiser wrote:
>> Hi all, I'm wondering if it's possible for memcheck to show the last place that some memory was accessible before being leaked.
> <snip>
>
> In your example below the difficulty lies in the code that has been elided
> by the ellipses "...". If there are any assignments of x to other pointers,
> or if x is passed as an actual argument of a function call, then it is hard
> to determine whether a leak occurs.
It could be done with reference counting, though this is of course
easier in more-constrained languages that do not allow (for example)
int *x = new int [256];
size_t x_ugly = (size_t) x;
double *x_uglier = (double *) x_ugly;
int *y = (int *) x_uglier;
I for one am glad that I am not trying to add this to memcheck.
Maybe it's just the domain I work in (electronic design automation),
where memory usage ebbs and flows and there are clearly defined
producers and consumers, but I don't ever recall needing this feature.
My code tends to be of the form "dispose of the object in the routine it
is created in, or else add it to the return value". This nested
responsibility means very little stuff gets lost, and it's pretty easy
to track down when leakage does occur.
I just finished cleaning up a multi-gigabyte program (135 K lines of new
code) that I wrote; it took about four runs of valgrind. Typical runs
can be six hours or more, so I wouldn't want to learn of a leak the hard
way. In a small run (15 minutes; six hours in valgrind) the initial
leakage was 22 Kbytes. All of the errors turned out to be local,
meaning the routine creating the object failed to dispose of it; I fixed
these and the 15-minute run is now leak-free.
This was helped by my XP-like development methodology; every module has
a standalone test program and I can run leak checks on these too.
>> int* g() {
>> int* x = new int[256]; <-- allocated here
>> ...
>> return x;
>> }
>>
>> int f() {
>> int* x = g();
>> ...
>> return 0; <-- leaked here
>> }
>>
--
David Chapman dcc...@ac...
Chapman Consulting -- San Jose, CA
Software Development Done Right.
www.chapman-consulting-sj.com
|
|
From: Julian S. <js...@ac...> - 2013-03-01 21:25:28
|
On 03/01/2013 06:23 AM, David Chapman wrote: > On 2/28/2013 4:58 PM, John Reiser wrote: >>> Hi all, I'm wondering if it's possible for memcheck to show the last place that > some memory was accessible before being leaked. This has been discussed before, and there was an experimental tool (Omega) to do that. It would be feasible to build a tool to refcount pointers to blocks, but the fundamental problem is that the last pointer to a block might get overwritten at some place which is totally nonsensical from the programmer's point of view. In particular, imagine that the last pointer to a block ends up in a spill slot on the stack, and at some later point the compiler generated code to use the spill slot to hold some new value. Then, the last pointer would disappear at the point of that overwrite. IOW .. the idea of tracking the last pointer to a block depends on the assumption that the only loads/stores in the generated machine code are directly related to source language constructs. But that's not the case, because of spilling during register allocation. AFAIK, there's no way to do this reliably at the machine code level. J |