|
From: Dennis L. <pla...@in...> - 2005-09-23 16:56:50
|
Hi, while having a question I read up valgrinds FAQ (actually the one from current svn) and hoped to find the answer in section 6.2. I think although its mentioned in the manual, there should be a short explanation of "direct" and "indirect" too. Now to my question I could not really find in the manual too. When valgrind(memcheck) reports the following: 80 (48 direct, 32 indirect) bytes in 1 blocks are definitely lost What I thought about a "block" was always that one block is one allocated chunk of memory, like the result of one single new/malloc etc. Now how can a part of this block beeing directly lost and the other one indirectly ? From what I understand the manual so far a block is directly lost if no pointer points to the beginning, or the block is indirectly lost when a pointer points into the middle of the block. But a part of the block beeing directly lost and the other one indirectly does not currently make sense to me, can anyone enlighten me on this point ? greets Dennis |
|
From: Nicholas N. <nj...@cs...> - 2005-09-23 19:22:36
|
On Fri, 23 Sep 2005, Dennis Lubert wrote: > while having a question I read up valgrinds FAQ (actually the one from > current svn) and hoped to find the answer in section 6.2. > I think although its mentioned in the manual, there should be a short > explanation of "direct" and "indirect" too. > > Now to my question I could not really find in the manual too. When > valgrind(memcheck) reports the following: > > 80 (48 direct, 32 indirect) bytes in 1 blocks are definitely lost > > What I thought about a "block" was always that one block is one > allocated chunk of memory, like the result of one single new/malloc etc. > Now how can a part of this block beeing directly lost and the other one > indirectly ? From what I understand the manual so far a block is > directly lost if no pointer points to the beginning, or the block is > indirectly lost when a pointer points into the middle of the block. But > a part of the block beeing directly lost and the other one indirectly > does not currently make sense to me, can anyone enlighten me on this > point ? You are right that the manual and FAQ should explain better the difference between direct and indirect leaks. As for your example, I don't understand what it's saying. It might be a bug :( Nick |
|
From: Dennis L. <pla...@in...> - 2005-09-24 11:51:31
|
Am Freitag, den 23.09.2005, 14:22 -0500 schrieb Nicholas Nethercote:
> On Fri, 23 Sep 2005, Dennis Lubert wrote:
>
> You are right that the manual and FAQ should explain better the difference
> between direct and indirect leaks.
>
> As for your example, I don't understand what it's saying. It might be a
> bug :(
Ok, in a 4-beer-investigation yesterday evening I found out the
following:
int main()
{
char* z = new char[100];
}
causes (of course): "100 bytes in 1 blocks are possibly lost in loss
record 1 of 1"
while
int main()
{
char* z = new char[100];
new char* (z);
}
causes (with leak-check=full):
104 (4 direct, 100 indirect) bytes in 1 blocks are definitely lost in
loss record 2 of 2
So I think the message mans that there is really two blocks lost, one
100 byte block and one pointer, together 104 bytes. The stack traces
shows the allocation of the pointer. I think this message should be more
clear. As Im not a native english speaker I dont know a good one, but my
suggestion would be sometihng like:
4 bytes (indirectly leaking 100 additional bytes) in 1 blocks are
definitely lost in loss record 1 of 2
or similar, and maybe some more descriptive message for the 100 bytes
block. Also the "loss record 2 of 2" message is confusing, as I first
thought "yes and where is loss record 1?".
Replacing the allocation of the pointer with a static pointer I get as
expected a "possibly lost" when setting the pointer to z+50. Maybe it
would be nice to show some information about the pointer thats found
(and if its only the address), preferrably with the help of debug info
the variable name, or where the pointer came from etc.
greets
Dennis
|
|
From: Tom H. <to...@co...> - 2005-09-24 12:12:30
|
In message <112...@sp...>
Dennis Lubert <pla...@in...> wrote:
> Am Freitag, den 23.09.2005, 14:22 -0500 schrieb Nicholas Nethercote:
> > On Fri, 23 Sep 2005, Dennis Lubert wrote:
> >
> > You are right that the manual and FAQ should explain better the difference
> > between direct and indirect leaks.
> >
> > As for your example, I don't understand what it's saying. It might be a
> > bug :(
>
> Ok, in a 4-beer-investigation yesterday evening I found out the
> following:
>
> int main()
> {
> char* z = new char[100];
> }
>
> causes (of course): "100 bytes in 1 blocks are possibly lost in loss
> record 1 of 1"
>
> while
> int main()
> {
> char* z = new char[100];
> new char* (z);
> }
>
> causes (with leak-check=full):
> 104 (4 direct, 100 indirect) bytes in 1 blocks are definitely lost in
> loss record 2 of 2
That looks wrong to me - the second new is a placement new which
doesn't actually allocate any memory at all I believe. It just
constructs an object of the specified type (char *) at the given
address (z, which was already allocated).
I wonder if we're not handling placement new right.
Tom
--
Tom Hughes (to...@co...)
http://www.compton.nu/
|
|
From: Christoph B. <bar...@or...> - 2005-09-24 20:49:13
|
Am Samstag, 24. September 2005 14:12 schrieb Tom Hughes:
> > int main()
> > {
> > char* z = new char[100];
> > new char* (z);
> > }
> >
> > causes (with leak-check=full):
> > 104 (4 direct, 100 indirect) bytes in 1 blocks are definitely lost in
> > loss record 2 of 2
>
> That looks wrong to me - the second new is a placement new which
> doesn't actually allocate any memory at all I believe. It just
> constructs an object of the specified type (char *) at the given
> address (z, which was already allocated).
>
> I wonder if we're not handling placement new right.
This is not a placement new. This is a normal new calling the copy constructor
for char *.
A placement new would look this way:
new (z) char *;
Christoph Bartoschek
|
|
From: Paul P. <ppl...@gm...> - 2005-09-24 21:29:45
|
On 9/24/05, Tom Hughes <to...@co...> wrote: >> new char* (z); > That looks wrong to me - the second new is a placement new which > doesn't actually allocate any memory at all I believe. It is not. It is an allocation of one 'char *' with initial value "z". It would have been placement new if it was written as new (z) char *; I do agree with Dennis: the "in 1 blocks" message is plain wrong. Cheers, |
|
From: Tom H. <to...@co...> - 2005-09-24 17:16:39
|
In message <2a2...@ma...>
Paul Pluzhnikov <ppl...@gm...> wrote:
> On 9/24/05, Tom Hughes <to...@co...> wrote:
>
> >> new char* (z);
>
> > That looks wrong to me - the second new is a placement new which
> > doesn't actually allocate any memory at all I believe.
>
> It is not. It is an allocation of one 'char *' with initial value "z".
> It would have been placement new if it was written as
>
> new (z) char *;
You're quite right - shows how much C++ I write ;-)
> I do agree with Dennis: the "in 1 blocks" message is plain wrong.
That wasn't what he was complaing about there was it? I suspect that
the blocks count is probably only the direct blocks and doesn't include
the indirect ones but I'd have to check the source to be sure.
Tom
--
Tom Hughes (to...@co...)
http://www.compton.nu/
|
|
From: Dennis L. <pla...@in...> - 2005-09-24 17:34:11
|
Am Samstag, den 24.09.2005, 18:16 +0100 schrieb Tom Hughes: > In message <2a2...@ma...> > Paul Pluzhnikov <ppl...@gm...> wrote: > > > On 9/24/05, Tom Hughes <to...@co...> wrote: > > > > >> new char* (z); > > > > > That looks wrong to me - the second new is a placement new which > > > doesn't actually allocate any memory at all I believe. > > > > It is not. It is an allocation of one 'char *' with initial value "z". > > It would have been placement new if it was written as > > > > new (z) char *; > > You're quite right - shows how much C++ I write ;-) > > > I do agree with Dennis: the "in 1 blocks" message is plain wrong. > > That wasn't what he was complaing about there was it? I suspect that > the blocks count is probably only the direct blocks and doesn't include > the indirect ones but I'd have to check the source to be sure. Well it was part of it, its confusing. If you say that the one block refers to the directly lost part of this message, then it is clear that it is one block. But then Id say it should be written like "one direct block which is additionally leading to another indirect lost block". And that there is only one report is shown for when valgrind says there are 2 loss records, its confusing too, one would ask were the other report is. So I think the message should be cleared if its something like the previously mentioned "4 bytes (indirectly leaking 100 additional bytes) in 1 blocks are definitely lost in loss record 1 of 2" and a "100 bytes (indirectly leaked by loss record1 at 0x3245657) in 1 blocks are indrectly leaked in loss record 2 of 2" greets Dennis PS: I did not get the message from Paul you have replied to, was it private message, or did the mailing list eat it ? |
|
From: Paul P. <ppl...@gm...> - 2005-09-24 19:10:26
|
On 9/24/05, Dennis Lubert <pla...@in...> wrote: :So I think the message should be cleared if its something like the :previously mentioned "4 bytes (indirectly leaking 100 additional bytes) :in 1 blocks are definitely lost in loss record 1 of 2" :and a "100 bytes (indirectly leaked by loss record1 at 0x3245657) in 1 :blocks are indrectly leaked in loss record 2 of 2" Here is how Insure++ reports leaks in the same program: Leaks detected at exit ---------------------- 100 bytes 1 chunk allocated at junk.cc, 6 malloc() (interface) operator new() operator new[]() main() junk.cc, 6 4 bytes 1 chunk allocated at junk.cc, 7 malloc() (interface) operator new() main() junk.cc, 7 Insure doesn't make a distinction between direct and indirect leaks; none of our users ever asked for it; I wonder if this VG feature is causing more confusion than it's worth. OTOH, I have seen situations where the direct/indirect distinction would have come quite useful (leaking a single pointer to large STL map). :PS: I did not get the message from Paul you have replied to, was it :private message, or did the mailing list eat it ? The message was CC'd to valgrind-users. |
|
From: Dennis L. <pla...@in...> - 2005-09-24 21:53:10
|
Am Samstag, den 24.09.2005, 11:16 -0700 schrieb Paul Pluzhnikov: > On 9/24/05, Dennis Lubert <pla...@in...> wrote: > > :So I think the message should be cleared if its something like > the > :previously mentioned "4 bytes (indirectly leaking 100 additional > bytes) > :in 1 blocks are definitely lost in loss record 1 of 2" > :and a "100 bytes (indirectly leaked by loss record1 at 0x3245657) > in 1 > :blocks are indrectly leaked in loss record 2 of 2" > > Here is how Insure++ reports leaks in the same program: > > Leaks detected at exit > ---------------------- > 100 bytes 1 chunk allocated at junk.cc, 6 > malloc() (interface) > operator new() > operator new[]() > main() junk.cc, 6 > > 4 bytes 1 chunk allocated at junk.cc, 7 > malloc() (interface) > operator new() > main() junk.cc, 7 > > Insure doesn't make a distinction between direct and indirect leaks; > none of our users ever asked for it; I wonder if this VG feature is > causing more confusion than it's worth. I think if we clear up the message its more useful than if there wasnt some message. Like often fixing the direct leak first does also fix the indirect, since a delete of one struct might call this ones destructor which then deletes the indirect leaked memory by itself. So I personally would then first fix the direct leaks, keeping in mind there are indirect, look if theyre oviously to spot and if not run valgrind again and then look whats left.... So Id say we should give as much information as possible, and try to make it clear and document it. Better than to have people searching for some info thats there, but just not outputted... perhaps there is even currently some more info thats not outputted which we just do not know ;) greets Dennis > The message was CC'd to valgrind-users. Funny, it arrived about 4 hours later at our mailserver... |