|
From: Stephan M. <sm...@gm...> - 2004-10-27 10:02:48
|
=2D----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Hi,
I became a little bit confused doing memchecks using c++ classes.
One of those classes maintains a mem area which is frequently resized using=
=20
realloc.
The Code segment looks perfectly alright to me...
void MyClass::resize(size_t n) {
char *buf;
if (n >=3D _size) {
if (!(buf =3D (char*)realloc(_buf,n+1)))
throw std::bad_alloc();
_buf =3D buf;
_size =3D n + 1;
}
}
But using this class (a lot, multithreaded) valgrind 2.2.0 shows something=
=20
like this:
=3D12311=3D=3D 309 bytes in 7 blocks are definitely lost in loss record 18 =
of 30
=3D=3D12311=3D=3D at 0x1B903A8B: realloc (vg_replace_malloc.c:197)
=3D=3D12311=3D=3D by 0x8085F2C: MyClass::resize(unsigned int) (../MyClas=
s.cc:650)
=3D=3D12311=3D=3D by 0x80847FF: MyClass::append(char const *, unsigned i=
nt
=3D=3D12311=3D=3D by 0x8084723: MyClass::append(MyClass const &) (../MyC=
lass.cc
What should be lost there? Does it refer to the mem area being abandoned wh=
en=20
realloc() gives a pointer different to _buf?
But it's supposed to be lost, we give it up. Why complain? I don't have to=
=20
free it do I?
Am I mistaken here or is it just a warning to be safely ignored?
System is linux 2.6.9, valgrind 2.2.0, gcc 2.95-3
Greetings...
Stephan
=2D----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.4 (GNU/Linux)
iD8DBQFBf3I0bv5p9h9J588RAtXgAJ0fAiWYxa6fMhmTOidrVIN65iyRxACgp/SU
MAVHyX15zHwyD/8gY3i2Qr4=3D
=3DzQbv
=2D----END PGP SIGNATURE-----
|
|
From: Dimitri Papadopoulos-O. <pap...@sh...> - 2004-10-27 10:06:27
|
Hi,
> I became a little bit confused doing memchecks using c++ classes.
> One of those classes maintains a mem area which is frequently resized using
> realloc.
> The Code segment looks perfectly alright to me...
>
> void MyClass::resize(size_t n) {
> char *buf;
>
> if (n >= _size) {
> if (!(buf = (char*)realloc(_buf,n+1)))
> throw std::bad_alloc();
> _buf = buf;
> _size = n + 1;
> }
> }
How was _buf allocated in the first place? malloc or new[]?
Dimitri
|
|
From: Stephan M. <sm...@gm...> - 2004-10-27 10:12:21
|
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Am Mittwoch, 27. Oktober 2004 12:05 schrieb Dimitri Papadopoulos-Orfanos:
> Hi,
>
> > I became a little bit confused doing memchecks using c++ classes.
> > One of those classes maintains a mem area which is frequently resized
> > using realloc.
> > The Code segment looks perfectly alright to me...
> >
> > void MyClass::resize(size_t n) {
> > char *buf;
> >
> > if (n >= _size) {
> > if (!(buf = (char*)realloc(_buf,n+1)))
> > throw std::bad_alloc();
> > _buf = buf;
> > _size = n + 1;
> > }
> > }
>
> How was _buf allocated in the first place? malloc or new[]?
malloc.
Or another realloc, if there were resize events before, which is not unlikely.
Greetings...
Stephan
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.4 (GNU/Linux)
iD8DBQFBf3R8bv5p9h9J588RAu/ZAJ9bpZ7sok4vmjzSMFleiAE8Q6SETACeOy2Q
m90AE79YurGGqvO5Bl7fmZA=
=li7V
-----END PGP SIGNATURE-----
|
|
From: Tom H. <th...@cy...> - 2004-10-27 10:25:48
|
In message <417...@sh...>
Dimitri Papadopoulos-Orfanos <pap...@sh...> wrote:
> Hi,
>
>> I became a little bit confused doing memchecks using c++ classes.
>> One of those classes maintains a mem area which is frequently
>> resized using realloc.
>> The Code segment looks perfectly alright to me...
>> void MyClass::resize(size_t n) {
>> char *buf;
>> if (n >= _size) {
>> if (!(buf = (char*)realloc(_buf,n+1)))
>> throw std::bad_alloc();
>> _buf = buf;
>> _size = n + 1;
>> }
>> }
>
> How was _buf allocated in the first place? malloc or new[]?
An even better question would be "where was it supposed to be freed".
Tom
--
Tom Hughes (th...@cy...)
Software Engineer, Cyberscience Corporation
http://www.cyberscience.com/
|
|
From: Jeroen N. W. <jn...@xs...> - 2004-10-27 10:25:56
|
Stephan,
Does the MyClass destructor free(_buf)?
Jeroen.
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> Hi,
>
> I became a little bit confused doing memchecks using c++ classes.
> One of those classes maintains a mem area which is frequently resized
> using
> realloc.
> The Code segment looks perfectly alright to me...
>
> void MyClass::resize(size_t n) {
> char *buf;
>
> if (n >=3D _size) {
> if (!(buf =3D (char*)realloc(_buf,n+1)))
> throw std::bad_alloc();
> _buf =3D buf;
> _size =3D n + 1;
> }
> }
>
> But using this class (a lot, multithreaded) valgrind 2.2.0 shows someth=
ing
> like this:
>
> =3D12311=3D=3D 309 bytes in 7 blocks are definitely lost in loss record=
18 of 30
> =3D=3D12311=3D=3D at 0x1B903A8B: realloc (vg_replace_malloc.c:197)
> =3D=3D12311=3D=3D by 0x8085F2C: MyClass::resize(unsigned int)
> (../MyClass.cc:650)
> =3D=3D12311=3D=3D by 0x80847FF: MyClass::append(char const *, unsign=
ed int
> =3D=3D12311=3D=3D by 0x8084723: MyClass::append(MyClass const &) (..=
/MyClass.cc
>
> What should be lost there? Does it refer to the mem area being abandone=
d
> when
> realloc() gives a pointer different to _buf?
> But it's supposed to be lost, we give it up. Why complain? I don't have=
to
> free it do I?
> Am I mistaken here or is it just a warning to be safely ignored?
>
> System is linux 2.6.9, valgrind 2.2.0, gcc 2.95-3
>
> Greetings...
>
> Stephan
> -----BEGIN PGP SIGNATURE-----
> Version: GnuPG v1.2.4 (GNU/Linux)
>
> iD8DBQFBf3I0bv5p9h9J588RAtXgAJ0fAiWYxa6fMhmTOidrVIN65iyRxACgp/SU
> MAVHyX15zHwyD/8gY3i2Qr4=3D
> =3DzQbv
> -----END PGP SIGNATURE-----
>
>
> -------------------------------------------------------
> This SF.Net email is sponsored by:
> Sybase ASE Linux Express Edition - download now for FREE
> LinuxWorld Reader's Choice Award Winner for best database on Linux.
> http://ads.osdn.com/?ad_idU88&alloc_id=12065&op=CCk
> _______________________________________________
> Valgrind-users mailing list
> Val...@li...
> https://lists.sourceforge.net/lists/listinfo/valgrind-users
>
>
|
|
From: Tom H. <th...@cy...> - 2004-10-27 10:28:38
|
In message <200...@gm...>
Stephan Menzel <sm...@gm...> wrote:
> But using this class (a lot, multithreaded) valgrind 2.2.0 shows something
> like this:
>
> =12311== 309 bytes in 7 blocks are definitely lost in loss record 18 of 30
> ==12311== at 0x1B903A8B: realloc (vg_replace_malloc.c:197)
> ==12311== by 0x8085F2C: MyClass::resize(unsigned int) (../MyClass.cc:650)
> ==12311== by 0x80847FF: MyClass::append(char const *, unsigned int
> ==12311== by 0x8084723: MyClass::append(MyClass const &) (../MyClass.cc
>
> What should be lost there?
I don't think anything is lost there. That code looks fine.
I think you are misunderstanding the error - that stack trace does not
indicate the point at which the memory was lost (that is virtually
impossible to determine) but rather the place where the memory which
has been lost was allocated.
> Does it refer to the mem area being abandoned when
> realloc() gives a pointer different to _buf?
No, because that is expected and that abandoned area becomes part of
the free pool and can be reused.
> Am I mistaken here or is it just a warning to be safely ignored?
It shouldn't be ignored. The memory which was allocated by that call
to realloc has been lost, presumably because something overwrite the
_buf pointer later on without freeing the memory first.
Tom
--
Tom Hughes (th...@cy...)
Software Engineer, Cyberscience Corporation
http://www.cyberscience.com/
|
|
From: Stephan M. <sm...@gm...> - 2004-10-27 10:39:45
|
=2D----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Am Mittwoch, 27. Oktober 2004 12:28 schrieb Tom Hughes:
=46irst of all, Jeroen, the destructor frees indeed.
MyClass::~MyClass() {
if (_buf)
free(_buf);
}
There's not much room for errors here.
> I think you are misunderstanding the error - that stack trace does not
> indicate the point at which the memory was lost (that is virtually
> impossible to determine) but rather the place where the memory which
> has been lost was allocated.
OK, so I did misunderstand. But anyway, is it possible to determine, where =
it=20
IS lost?=20
I think I should mention that the debugged program is a demon process and i=
t=20
initialises lots of those objects and destroys lots of them during runtime.=
=20
But some should still live when I shut down the process. Is it possible tha=
t=20
those errors refer to still existing objects when I kill the demon? That=20
wouldn't bother me as long as it's not leaking mem during normal runtime.
> It shouldn't be ignored. The memory which was allocated by that call
> to realloc has been lost, presumably because something overwrite the
> _buf pointer later on without freeing the memory first.
I checked it pretty thoroughly but I'll keep on looking for stuff like that.
Greetings...
Stephan
=2D----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.4 (GNU/Linux)
iD8DBQFBf3rbbv5p9h9J588RAkKNAJwKP5F+SEmsaW9bNGQJX26zj7v/twCgh0li
2rnSrc69z6nr0W6zD0+rSXs=3D
=3DCEdj
=2D----END PGP SIGNATURE-----
|
|
From: Nicholas N. <nj...@ca...> - 2004-10-27 11:23:20
|
On Wed, 27 Oct 2004, Stephan Menzel wrote:
>> I think you are misunderstanding the error - that stack trace does not
>> indicate the point at which the memory was lost (that is virtually
>> impossible to determine) but rather the place where the memory which
>> has been lost was allocated.
>
> OK, so I did misunderstand. But anyway, is it possible to determine, where it
> IS lost?
It is possible; the following paper describes a technique to do it.
author = {Jonas Maebe and Michiel Ronsse and Koen De Bosschere},
title = {Precise detection of memory leaks},
booktitle = {Proceedings of the Second International Workshop on Dynamic
Analysis (WODA 2004)},
address = {Edinburgh, Scotland},
month = may,
year = 2004,
Unfortunately, it is not practical; the prototype implementation
described runs programs 200--300 times slower than normal, which makes
even Memcheck look fast.
> I checked it pretty thoroughly but I'll keep on looking for stuff like that.
I'd recommend writing a very short test program that is a distillation of
your daemon's behaviour, and then run Memcheck on it. That should make
things clearer, eg. about exactly how Memcheck works, and what it
reports. I find this a useful technique in general when trying something
I haven't tried before (eg. an obscure language feature, a programming
tool, etc.)
N
|
|
From: Paul P. <ppl...@gm...> - 2004-10-27 14:22:33
|
On Wed, 27 Oct 2004 12:23:08 +0100 (BST), Nicholas Nethercote <nj...@ca...> wrote: > On Wed, 27 Oct 2004, Stephan Menzel wrote: > > > OK, so I did misunderstand. But anyway, is it possible to determine, where it > > IS lost? > > It is possible; the following paper describes a technique to do it. [...] > Unfortunately, it is not practical; Insure++, a commercial tool from Parasoft, attempts to report where the memory is lost, and, contrary to the claim in the article, also reports where the pointer got its value. > I'd recommend writing a very short test program that is a distillation of > your daemon's behaviour, and then run Memcheck on it. I second that suggestion. Also, nobody mentioned this, but are you perhaps violating "Effective C++" rule 11: Define a copy constructor and an assignment operator for classes with dynamically allocated memory" Cheers, |
|
From: Stephan M. <sm...@gm...> - 2004-10-27 14:53:59
|
=2D----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Am Mittwoch, 27. Oktober 2004 16:22 schrieb Paul Pluzhnikov: > Define a copy constructor and an assignment operator for classes with > dynamically allocated memory" Well spoken, but I didn't write this class and this is of course one of the= =20 first things I checked. Thank you anyway. Stephan =2D----BEGIN PGP SIGNATURE----- Version: GnuPG v1.2.4 (GNU/Linux) iD8DBQFBf7Ztbv5p9h9J588RAlAOAJ9mn+qFgY0i9RN6eGecy3ogfKCRAQCfRf+b jnFhjWNRT9mPZRpYR+/pe8A=3D =3DZIDF =2D----END PGP SIGNATURE----- |
|
From: Nicholas N. <nj...@ca...> - 2004-10-27 14:34:38
|
On Wed, 27 Oct 2004, Paul Pluzhnikov wrote: > Insure++, a commercial tool from Parasoft, attempts to report where > the memory is lost, and, contrary to the claim in the article, also > reports where the pointer got its value. Is that in the source-code instrumentation mode, or the binary instrumentation mode? Thanks. N |
|
From: Paul P. <ppl...@gm...> - 2004-10-27 14:44:21
|
> Is that in the source-code instrumentation mode, or the binary
> instrumentation mode?
C and C++ source instrumentation and malloc() interception library
cooperate to provide
"pointer tracking".
This also allows to find bugs that (I think) can not be found by any
other means, such as:
char *p = new char[1024];
char *q = new char[1024];
p[1500] = 'a'; // "logical" overflow of the "p" buffer, but physically
// very likely inside the "q" buffer, so not detected by
// Purify, VG, etc.
|