|
From: Yeshurun, M. <mei...@in...> - 2005-10-17 18:43:34
|
I know of a memory checker that never ever gives you a single false
positive, and is included in all Linux distributions. Here is the
usage:
ls <program name>
Seriously now, my experience with Valgrind has been to the contrary.
Sure, its tempting to dismiss error messages as false alarms. But so
far, Valgrind was right about every error that I took the time to
investigate carefully. You can't blame Valgrind for reporting cases of
deliberate use of un-initialized values (and I've seen some of those).
There is one issue though: It looks like Valgrind reports partial loads
as errors by default. I think this shouldn't be the default behavior.
Regards,
Meir
-----Original Message-----
From: val...@li...
[mailto:val...@li...] On Behalf Of Nick
Lindridge
Sent: Monday, October 17, 2005 4:22 PM
To: val...@li...
Subject: [Valgrind-users] User error? - Valgrind 3 failing terribly
compared to purify
Hi all
Looking for any hints on why valgrind may be reporting hundreds of bogus
errors in some C++/C code, compared to purify working and reporting
flawlessly on the same code on the same machine.
The code was tested with both older valgrinds and the latest valgrind 3
on
a code base with openssh, libssh2, and other code, and has been giving
not
only vast numbers of errors, but plenty of errors reports that are
deomonstrably bogus. It took a couple of hours to produce a suppressions
file that would suppress enough to be able to see any possible genuine
errors, but even then, the genuine bugs in libssh2, for example, weren't
caught as far as we could see. Only purify gave the true picture,
finding
the problems in libssh2, and only a few other UMR reports related to
openssh crypto functions that are actually ok.
I know from previous experience that valgrind can be good, so does
anyone
have any ideas why in this case it was so disastrously off base? Files
were optimised -O0 as recommended, and tested both on a 2.2 kernel and
2.95.3 (with an old valgrind), and the latest valgrind with 2.4.20-31.9
and gcc 3.2.2.
One simple failing example was:
n =3D libssh2_channel_read(ch->channel_ptr(), buf, bufsize - 1);
if (n < 0) {
//
}
where n was sometimes reported as being uninitialised on the
conditional.
This was provably incorrect, and verifed both by purify and having a
correct return result, with all code paths inside the function
initialising the return value, and with values that were themselves
always
initialised, so there was no propagation of uninitialised data. Some of
the libssh code was also rewritten to move automatics defined in
innerblocks to the outer most level, just in case overlapping autos were
in anyway a problem, but as expected, this made no difference.
Sorry if I missed something such as valgrind not working with C++
binaries, but I don't believe that there's any problem there.
Any suggestions to try are welcome!
Nick
-------------------------------------------------------
This SF.Net email is sponsored by:
Power Architecture Resource Center: Free content, downloads,
discussions,
and more. http://solutions.newsforge.com/ibmarch.tmpl
_______________________________________________
Valgrind-users mailing list
Val...@li...
https://lists.sourceforge.net/lists/listinfo/valgrind-users
|
|
From: Yeshurun, M. <mei...@in...> - 2005-10-17 20:09:19
|
I mean errors of the following form: Invalid read of size x... Address is n - y bytes inside a block of size n... =20 - where y < x Can this sort of error be the result of some compiler optimization/bug? I get a huge number of those for some libraries we use. --partial-loads-ok=3Dyes doesn't help. (Perhaps I misunderstood the term "partial load".) Thanks, Meir -----Original Message----- From: val...@li... [mailto:val...@li...] On Behalf Of Nicholas Nethercote Sent: Monday, October 17, 2005 9:24 PM To: Tom Hughes Cc: val...@li... Subject: RE: [Valgrind-users] User error? - Valgrind 3 failing terribly compared to purify On Mon, 17 Oct 2005, Tom Hughes wrote: >> There is one issue though: It looks like Valgrind reports partial loads >> as errors by default. I think this shouldn't be the default behavior. > > Actually valgrind doesn't report any loads as errors - it only > reports an error when you use an undefined value in a way that > would effect the result of the program. In other words when a > conditional jump depends on it or you use it as a pointer and > read or write through that pointer. > > It tracks definedness at bit level, so a partial load will mark > some bits as defined and leaves others alone. If you then later > use one of the undefined bits it will complain. > > There are edge cases where it thinks a bit is used when it isn't > really but they are rare. > > I think you need to explain what you mean more fully. I think he's referring to the --partial-loads-ok option, but it's set to true by default (at least, that's what "valgrind -h" says). Nick ------------------------------------------------------- This SF.Net email is sponsored by: Power Architecture Resource Center: Free content, downloads, discussions, and more. http://solutions.newsforge.com/ibmarch.tmpl _______________________________________________ Valgrind-users mailing list Val...@li... https://lists.sourceforge.net/lists/listinfo/valgrind-users |
|
From: Yeshurun, M. <mei...@in...> - 2005-10-17 20:56:06
|
The following program generates an invalid read even when explicitly
specifying --partial-loads-ok=3Dyes. Am I missing something here?
#include <cstring>
#include <iostream>
using namespace std;
int main()
{
char *a =3D new char[11];
strcpy(a, "0123456789");
int b =3D *(int *)(a + 9); =20
}
Thanks,
Meir
-----Original Message-----
From: val...@li...
[mailto:val...@li...] On Behalf Of Tom
Hughes
Sent: Monday, October 17, 2005 9:07 PM
To: val...@li...
Subject: RE: [Valgrind-users] User error? - Valgrind 3 failing terribly
compared to purify
In message
<942...@ha...>
"Yeshurun, Meir" <mei...@in...> wrote:
> There is one issue though: It looks like Valgrind reports partial
loads
> as errors by default. I think this shouldn't be the default behavior.
Actually valgrind doesn't report any loads as errors - it only
reports an error when you use an undefined value in a way that
would effect the result of the program. In other words when a
conditional jump depends on it or you use it as a pointer and
read or write through that pointer.
It tracks definedness at bit level, so a partial load will mark
some bits as defined and leaves others alone. If you then later
use one of the undefined bits it will complain.
There are edge cases where it thinks a bit is used when it isn't
really but they are rare.
I think you need to explain what you mean more fully.
Tom
--=20
Tom Hughes (to...@co...)
http://www.compton.nu/
-------------------------------------------------------
This SF.Net email is sponsored by:
Power Architecture Resource Center: Free content, downloads,
discussions,
and more. http://solutions.newsforge.com/ibmarch.tmpl
_______________________________________________
Valgrind-users mailing list
Val...@li...
https://lists.sourceforge.net/lists/listinfo/valgrind-users
|
|
From: Brian C. <cr...@fi...> - 2005-10-17 21:03:36
|
"XXX" is uninitialized memory. Ints are assumed to be 4-byte:
a = { '0', '1', '2', '3', '4', '5', 6', '7', '8', '9', 0, XXX, XXX }
((int*)a + 9) = { ............................................RRR, RRR, RRR, RRR }
the last two bytes being read in the int dereference are uninitialized memory.
-- Brian
Yeshurun, Meir wrote:
> The following program generates an invalid read even when explicitly
> specifying --partial-loads-ok=yes. Am I missing something here?
>
> #include <cstring>
> #include <iostream>
>
> using namespace std;
>
> int main()
> {
> char *a = new char[11];
> strcpy(a, "0123456789");
> int b = *(int *)(a + 9);
> }
>
>
> Thanks,
>
> Meir
>
> -----Original Message-----
> From: val...@li...
> [mailto:val...@li...] On Behalf Of Tom
> Hughes
> Sent: Monday, October 17, 2005 9:07 PM
> To: val...@li...
> Subject: RE: [Valgrind-users] User error? - Valgrind 3 failing terribly
> compared to purify
>
> In message
> <942...@ha...>
> "Yeshurun, Meir" <mei...@in...> wrote:
>
>
>>There is one issue though: It looks like Valgrind reports partial
>
> loads
>
>>as errors by default. I think this shouldn't be the default behavior.
>
>
> Actually valgrind doesn't report any loads as errors - it only
> reports an error when you use an undefined value in a way that
> would effect the result of the program. In other words when a
> conditional jump depends on it or you use it as a pointer and
> read or write through that pointer.
>
> It tracks definedness at bit level, so a partial load will mark
> some bits as defined and leaves others alone. If you then later
> use one of the undefined bits it will complain.
>
> There are edge cases where it thinks a bit is used when it isn't
> really but they are rare.
>
> I think you need to explain what you mean more fully.
>
> Tom
>
|
|
From: Julian S. <js...@ac...> - 2005-10-17 23:07:28
|
What's happening is, gcc or glibc is doing the strcpy using 32-bit
loads/stores and so tramples off the end of the array.
Now ... unfortunately I believe I have confused everybody. Up to
and including 2.4.1, V would allow such loads from array ends without
complaint when --partial-loads-ok=yes applied, which was the default.
But that was always a kludge, which I never liked -- I thought it could
miss genuine bugs like that.
When memcheck was rewritten for the 3.0 line, that hack got dumped.
The rationale was that we would intercept all such str* functions and
substitute our own non-optimised-to-hell versions. And so we do.
And most of the time that works fine.
Unfortunately:
(1) I appear not to have updated the help text, removed the flag
handler, or updated the manual. That's really bad .. sorry.
(2) The intercept trick is defeated if gcc inlines strcpy/strcmp,
which in your example I believe it will do. What happens if
you try again with -mno-inline-all-stringops for gcc?
J
On Monday 17 October 2005 22:02, Brian Crowder wrote:
> "XXX" is uninitialized memory. Ints are assumed to be 4-byte:
>
> a = { '0', '1', '2', '3', '4', '5', 6', '7', '8', '9', 0,
> XXX, XXX } ((int*)a + 9) = {
> ............................................RRR, RRR, RRR, RRR }
>
> the last two bytes being read in the int dereference are uninitialized
> memory.
>
>
> -- Brian
>
> Yeshurun, Meir wrote:
> > The following program generates an invalid read even when explicitly
> > specifying --partial-loads-ok=yes. Am I missing something here?
> >
> > #include <cstring>
> > #include <iostream>
> >
> > using namespace std;
> >
> > int main()
> > {
> > char *a = new char[11];
> > strcpy(a, "0123456789");
> > int b = *(int *)(a + 9);
> > }
> >
> >
> > Thanks,
> >
> > Meir
> >
> > -----Original Message-----
> > From: val...@li...
> > [mailto:val...@li...] On Behalf Of Tom
> > Hughes
> > Sent: Monday, October 17, 2005 9:07 PM
> > To: val...@li...
> > Subject: RE: [Valgrind-users] User error? - Valgrind 3 failing terribly
> > compared to purify
> >
> > In message
> > <942...@ha...>
> >
> > "Yeshurun, Meir" <mei...@in...> wrote:
> >>There is one issue though: It looks like Valgrind reports partial
> >
> > loads
> >
> >>as errors by default. I think this shouldn't be the default behavior.
> >
> > Actually valgrind doesn't report any loads as errors - it only
> > reports an error when you use an undefined value in a way that
> > would effect the result of the program. In other words when a
> > conditional jump depends on it or you use it as a pointer and
> > read or write through that pointer.
> >
> > It tracks definedness at bit level, so a partial load will mark
> > some bits as defined and leaves others alone. If you then later
> > use one of the undefined bits it will complain.
> >
> > There are edge cases where it thinks a bit is used when it isn't
> > really but they are rare.
> >
> > I think you need to explain what you mean more fully.
> >
> > Tom
>
> -------------------------------------------------------
> This SF.Net email is sponsored by:
> Power Architecture Resource Center: Free content, downloads, discussions,
> and more. http://solutions.newsforge.com/ibmarch.tmpl
> _______________________________________________
> Valgrind-users mailing list
> Val...@li...
> https://lists.sourceforge.net/lists/listinfo/valgrind-users
|
|
From: Yeshurun, M. <mei...@in...> - 2005-10-17 21:06:33
|
The purpose of this little program was to do exactly that. My question
is why isn't the error suppressed by specifying =
--partial-loads-ok=3Dyes.
Meir
-----Original Message-----
From: Brian Crowder [mailto:cr...@fi...]=20
Sent: Monday, October 17, 2005 11:03 PM
To: Yeshurun, Meir
Cc: Tom Hughes; val...@li...
Subject: Re: [Valgrind-users] User error? - Valgrind 3 failing terribly
compared to purify
"XXX" is uninitialized memory. Ints are assumed to be 4-byte:
a =3D { '0', '1', '2', '3', '4', '5', 6', '7', '8', '9', =
0,
XXX, XXX }
((int*)a + 9) =3D { ............................................RRR, =
RRR,
RRR, RRR }
the last two bytes being read in the int dereference are uninitialized
memory.
-- Brian
Yeshurun, Meir wrote:
> The following program generates an invalid read even when explicitly
> specifying --partial-loads-ok=3Dyes. Am I missing something here?
>=20
> #include <cstring>
> #include <iostream>
>=20
> using namespace std;
>=20
> int main()
> {
> char *a =3D new char[11];
> strcpy(a, "0123456789");
> int b =3D *(int *)(a + 9); =20
> }
>=20
>=20
> Thanks,
>=20
> Meir
>=20
> -----Original Message-----
> From: val...@li...
> [mailto:val...@li...] On Behalf Of Tom
> Hughes
> Sent: Monday, October 17, 2005 9:07 PM
> To: val...@li...
> Subject: RE: [Valgrind-users] User error? - Valgrind 3 failing
terribly
> compared to purify
>=20
> In message
>
<942...@ha...>
> "Yeshurun, Meir" <mei...@in...> wrote:
>=20
>=20
>>There is one issue though: It looks like Valgrind reports partial
>=20
> loads
>=20
>>as errors by default. I think this shouldn't be the default behavior.
>=20
>=20
> Actually valgrind doesn't report any loads as errors - it only
> reports an error when you use an undefined value in a way that
> would effect the result of the program. In other words when a
> conditional jump depends on it or you use it as a pointer and
> read or write through that pointer.
>=20
> It tracks definedness at bit level, so a partial load will mark
> some bits as defined and leaves others alone. If you then later
> use one of the undefined bits it will complain.
>=20
> There are edge cases where it thinks a bit is used when it isn't
> really but they are rare.
>=20
> I think you need to explain what you mean more fully.
>=20
> Tom
>=20
|
|
From: Brian C. <cr...@fi...> - 2005-10-17 21:13:57
|
The bytes are not _only_ uninitalized, however, they are also beyond the end of the allocated data.
(don't know if that makes a difference).
-- Brian
Yeshurun, Meir wrote:
> The purpose of this little program was to do exactly that. My question
> is why isn't the error suppressed by specifying --partial-loads-ok=yes.
>
> Meir
>
> -----Original Message-----
> From: Brian Crowder [mailto:cr...@fi...]
> Sent: Monday, October 17, 2005 11:03 PM
> To: Yeshurun, Meir
> Cc: Tom Hughes; val...@li...
> Subject: Re: [Valgrind-users] User error? - Valgrind 3 failing terribly
> compared to purify
>
>
> "XXX" is uninitialized memory. Ints are assumed to be 4-byte:
>
> a = { '0', '1', '2', '3', '4', '5', 6', '7', '8', '9', 0,
> XXX, XXX }
> ((int*)a + 9) = { ............................................RRR, RRR,
> RRR, RRR }
>
> the last two bytes being read in the int dereference are uninitialized
> memory.
>
>
> -- Brian
>
> Yeshurun, Meir wrote:
>
>>The following program generates an invalid read even when explicitly
>>specifying --partial-loads-ok=yes. Am I missing something here?
>>
>>#include <cstring>
>>#include <iostream>
>>
>>using namespace std;
>>
>>int main()
>>{
>> char *a = new char[11];
>> strcpy(a, "0123456789");
>> int b = *(int *)(a + 9);
>>}
>>
>>
>>Thanks,
>>
>>Meir
>>
>>-----Original Message-----
>>From: val...@li...
>>[mailto:val...@li...] On Behalf Of Tom
>>Hughes
>>Sent: Monday, October 17, 2005 9:07 PM
>>To: val...@li...
>>Subject: RE: [Valgrind-users] User error? - Valgrind 3 failing
>
> terribly
>
>>compared to purify
>>
>>In message
>>
>
> <942...@ha...>
>
>> "Yeshurun, Meir" <mei...@in...> wrote:
>>
>>
>>
>>>There is one issue though: It looks like Valgrind reports partial
>>
>>loads
>>
>>
>>>as errors by default. I think this shouldn't be the default behavior.
>>
>>
>>Actually valgrind doesn't report any loads as errors - it only
>>reports an error when you use an undefined value in a way that
>>would effect the result of the program. In other words when a
>>conditional jump depends on it or you use it as a pointer and
>>read or write through that pointer.
>>
>>It tracks definedness at bit level, so a partial load will mark
>>some bits as defined and leaves others alone. If you then later
>>use one of the undefined bits it will complain.
>>
>>There are edge cases where it thinks a bit is used when it isn't
>>really but they are rare.
>>
>>I think you need to explain what you mean more fully.
>>
>>Tom
>>
>
>
>
>
|
|
From: Yeshurun, M. <mei...@in...> - 2005-10-17 21:20:55
|
It does make a difference.=20
If the bytes were merely un-initialized, Valgrind should never report an
error for this program. Since they are not even valid for
reading/writing, Valgrind should report an error, but only if you
specify --partial-loads-ok=3Dno.=20
All of this is based on my understanding of what's written in the
Valgrind user manual.
Meir
-----Original Message-----
From: Brian Crowder [mailto:cr...@fi...]=20
Sent: Monday, October 17, 2005 11:14 PM
To: Yeshurun, Meir
Cc: val...@li...
Subject: Re: [Valgrind-users] User error? - Valgrind 3 failing terribly
compared to purify
The bytes are not _only_ uninitalized, however, they are also beyond the
end of the allocated data.=20
(don't know if that makes a difference).
-- Brian
Yeshurun, Meir wrote:
> The purpose of this little program was to do exactly that. My question
> is why isn't the error suppressed by specifying
--partial-loads-ok=3Dyes.
>=20
> Meir
>=20
> -----Original Message-----
> From: Brian Crowder [mailto:cr...@fi...]=20
> Sent: Monday, October 17, 2005 11:03 PM
> To: Yeshurun, Meir
> Cc: Tom Hughes; val...@li...
> Subject: Re: [Valgrind-users] User error? - Valgrind 3 failing
terribly
> compared to purify
>=20
>=20
> "XXX" is uninitialized memory. Ints are assumed to be 4-byte:
>=20
> a =3D { '0', '1', '2', '3', '4', '5', 6', '7', '8', '9',
0,
> XXX, XXX }
> ((int*)a + 9) =3D { ............................................RRR,
RRR,
> RRR, RRR }
>=20
> the last two bytes being read in the int dereference are uninitialized
> memory.
>=20
>=20
> -- Brian
>=20
> Yeshurun, Meir wrote:
>=20
>>The following program generates an invalid read even when explicitly
>>specifying --partial-loads-ok=3Dyes. Am I missing something here?
>>
>>#include <cstring>
>>#include <iostream>
>>
>>using namespace std;
>>
>>int main()
>>{
>> char *a =3D new char[11];
>> strcpy(a, "0123456789");
>> int b =3D *(int *)(a + 9); =20
>>}
>>
>>
>>Thanks,
>>
>>Meir
>>
>>-----Original Message-----
>>From: val...@li...
>>[mailto:val...@li...] On Behalf Of Tom
>>Hughes
>>Sent: Monday, October 17, 2005 9:07 PM
>>To: val...@li...
>>Subject: RE: [Valgrind-users] User error? - Valgrind 3 failing
>=20
> terribly
>=20
>>compared to purify
>>
>>In message
>>
>=20
>
<942...@ha...>
>=20
>> "Yeshurun, Meir" <mei...@in...> wrote:
>>
>>
>>
>>>There is one issue though: It looks like Valgrind reports partial
>>
>>loads
>>
>>
>>>as errors by default. I think this shouldn't be the default behavior.
>>
>>
>>Actually valgrind doesn't report any loads as errors - it only
>>reports an error when you use an undefined value in a way that
>>would effect the result of the program. In other words when a
>>conditional jump depends on it or you use it as a pointer and
>>read or write through that pointer.
>>
>>It tracks definedness at bit level, so a partial load will mark
>>some bits as defined and leaves others alone. If you then later
>>use one of the undefined bits it will complain.
>>
>>There are edge cases where it thinks a bit is used when it isn't
>>really but they are rare.
>>
>>I think you need to explain what you mean more fully.
>>
>>Tom
>>
>=20
>=20
>=20
>=20
|
|
From: Yeshurun, M. <mei...@in...> - 2005-10-17 21:56:32
|
I don't understand why that would make a difference. The array is
initialized, it doesn't matter what it contains.
Meir
-----Original Message-----
From: Eric Lauzon [mailto:eri...@ab...]=20
Sent: Monday, October 17, 2005 11:51 PM
To: Yeshurun, Meir
Subject: RE: [Valgrind-users] User error? - Valgrind 3 failing terribly
compared to purify
shouldn't using zeroed memory be less problematic ...?
malloc/memset
new blabla =3D {0};
-elz
=20
> -----Original Message-----
> From: val...@li...=20
> [mailto:val...@li...] On Behalf=20
> Of Yeshurun, Meir
> Sent: 17 octobre 2005 17:21
> To: Brian Crowder
> Cc: val...@li...
> Subject: RE: [Valgrind-users] User error? - Valgrind 3=20
> failing terribly compared to purify
>=20
> It does make a difference.=20
>=20
> If the bytes were merely un-initialized, Valgrind should=20
> never report an error for this program. Since they are not=20
> even valid for reading/writing, Valgrind should report an=20
> error, but only if you specify --partial-loads-ok=3Dno.=20
>=20
> All of this is based on my understanding of what's written in=20
> the Valgrind user manual.
>=20
> Meir
>=20
> -----Original Message-----
> From: Brian Crowder [mailto:cr...@fi...]
> Sent: Monday, October 17, 2005 11:14 PM
> To: Yeshurun, Meir
> Cc: val...@li...
> Subject: Re: [Valgrind-users] User error? - Valgrind 3=20
> failing terribly compared to purify
>=20
>=20
> The bytes are not _only_ uninitalized, however, they are also=20
> beyond the
> end of the allocated data.=20
> (don't know if that makes a difference).
>=20
> -- Brian
>=20
> Yeshurun, Meir wrote:
> > The purpose of this little program was to do exactly that.=20
> My question
> > is why isn't the error suppressed by specifying
> --partial-loads-ok=3Dyes.
> >=20
> > Meir
> >=20
> > -----Original Message-----
> > From: Brian Crowder [mailto:cr...@fi...]=20
> > Sent: Monday, October 17, 2005 11:03 PM
> > To: Yeshurun, Meir
> > Cc: Tom Hughes; val...@li...
> > Subject: Re: [Valgrind-users] User error? - Valgrind 3 failing
> terribly
> > compared to purify
> >=20
> >=20
> > "XXX" is uninitialized memory. Ints are assumed to be 4-byte:
> >=20
> > a =3D { '0', '1', '2', '3', '4', '5', 6', '7', '8', '9',
> 0,
> > XXX, XXX }
> > ((int*)a + 9) =3D { ............................................RRR,
> RRR,
> > RRR, RRR }
> >=20
> > the last two bytes being read in the int dereference are=20
> uninitialized
> > memory.
> >=20
> >=20
> > -- Brian
> >=20
> > Yeshurun, Meir wrote:
> >=20
> >>The following program generates an invalid read even when explicitly
> >>specifying --partial-loads-ok=3Dyes. Am I missing something here?
> >>
> >>#include <cstring>
> >>#include <iostream>
> >>
> >>using namespace std;
> >>
> >>int main()
> >>{
> >> char *a =3D new char[11];
> >> strcpy(a, "0123456789");
> >> int b =3D *(int *)(a + 9); =20
> >>}
> >>
> >>
> >>Thanks,
> >>
> >>Meir
> >>
> >>-----Original Message-----
> >>From: val...@li...
> >>[mailto:val...@li...] On Behalf Of Tom
> >>Hughes
> >>Sent: Monday, October 17, 2005 9:07 PM
> >>To: val...@li...
> >>Subject: RE: [Valgrind-users] User error? - Valgrind 3 failing
> >=20
> > terribly
> >=20
> >>compared to purify
> >>
> >>In message
> >>
> >=20
> >
> <942...@ha...rp.i
> ntel.com>
> >=20
> >> "Yeshurun, Meir" <mei...@in...> wrote:
> >>
> >>
> >>
> >>>There is one issue though: It looks like Valgrind reports partial
> >>
> >>loads
> >>
> >>
> >>>as errors by default. I think this shouldn't be the=20
> default behavior.
> >>
> >>
> >>Actually valgrind doesn't report any loads as errors - it only
> >>reports an error when you use an undefined value in a way that
> >>would effect the result of the program. In other words when a
> >>conditional jump depends on it or you use it as a pointer and
> >>read or write through that pointer.
> >>
> >>It tracks definedness at bit level, so a partial load will mark
> >>some bits as defined and leaves others alone. If you then later
> >>use one of the undefined bits it will complain.
> >>
> >>There are edge cases where it thinks a bit is used when it isn't
> >>really but they are rare.
> >>
> >>I think you need to explain what you mean more fully.
> >>
> >>Tom
> >>
> >=20
> >=20
> >=20
> >=20
>=20
>=20
> -------------------------------------------------------
> This SF.Net email is sponsored by:
> Power Architecture Resource Center: Free content, downloads,=20
> discussions,
> and more. http://solutions.newsforge.com/ibmarch.tmpl
> _______________________________________________
> Valgrind-users mailing list
> Val...@li...
> https://lists.sourceforge.net/lists/listinfo/valgrind-users
>=20
|
|
From: Yeshurun, M. <mei...@in...> - 2005-10-17 23:21:50
|
Compiling with that flag didn't cause the error not to be reported.
I don't think the problem in this case is related to strcpy, it's
because of the weird read in the last line of the program.
Anyway, isn't there a way to suppress error messages for partially
invalid reads? These error messages are quite frequent, and with some
libraries they appear so often it makes the log file unreadable.
Thanks,
Meir
-----Original Message-----
From: Julian Seward [mailto:js...@ac...]=20
Sent: Tuesday, October 18, 2005 1:09 AM
To: val...@li...
Cc: Brian Crowder; Yeshurun, Meir; Tom Hughes
Subject: Re: [Valgrind-users] User error? - Valgrind 3 failing terribly
compared to purify
What's happening is, gcc or glibc is doing the strcpy using 32-bit
loads/stores and so tramples off the end of the array.
Now ... unfortunately I believe I have confused everybody. Up to
and including 2.4.1, V would allow such loads from array ends without
complaint when --partial-loads-ok=3Dyes applied, which was the default.
But that was always a kludge, which I never liked -- I thought it could
miss genuine bugs like that.
When memcheck was rewritten for the 3.0 line, that hack got dumped.
The rationale was that we would intercept all such str* functions and
substitute our own non-optimised-to-hell versions. And so we do.
And most of the time that works fine.
Unfortunately:
(1) I appear not to have updated the help text, removed the flag
handler, or updated the manual. That's really bad .. sorry.
(2) The intercept trick is defeated if gcc inlines strcpy/strcmp,
which in your example I believe it will do. What happens if=20
you try again with -mno-inline-all-stringops for gcc?
J
On Monday 17 October 2005 22:02, Brian Crowder wrote:
> "XXX" is uninitialized memory. Ints are assumed to be 4-byte:
>
> a =3D { '0', '1', '2', '3', '4', '5', 6', '7', '8', '9',
0,
> XXX, XXX } ((int*)a + 9) =3D {
> ............................................RRR, RRR, RRR, RRR }
>
> the last two bytes being read in the int dereference are uninitialized
> memory.
>
>
> -- Brian
>
> Yeshurun, Meir wrote:
> > The following program generates an invalid read even when explicitly
> > specifying --partial-loads-ok=3Dyes. Am I missing something here?
> >
> > #include <cstring>
> > #include <iostream>
> >
> > using namespace std;
> >
> > int main()
> > {
> > char *a =3D new char[11];
> > strcpy(a, "0123456789");
> > int b =3D *(int *)(a + 9);
> > }
> >
> >
> > Thanks,
> >
> > Meir
> >
> > -----Original Message-----
> > From: val...@li...
> > [mailto:val...@li...] On Behalf Of Tom
> > Hughes
> > Sent: Monday, October 17, 2005 9:07 PM
> > To: val...@li...
> > Subject: RE: [Valgrind-users] User error? - Valgrind 3 failing
terribly
> > compared to purify
> >
> > In message
> >
<942...@ha...>
> >
> > "Yeshurun, Meir" <mei...@in...> wrote:
> >>There is one issue though: It looks like Valgrind reports partial
> >
> > loads
> >
> >>as errors by default. I think this shouldn't be the default
behavior.
> >
> > Actually valgrind doesn't report any loads as errors - it only
> > reports an error when you use an undefined value in a way that
> > would effect the result of the program. In other words when a
> > conditional jump depends on it or you use it as a pointer and
> > read or write through that pointer.
> >
> > It tracks definedness at bit level, so a partial load will mark
> > some bits as defined and leaves others alone. If you then later
> > use one of the undefined bits it will complain.
> >
> > There are edge cases where it thinks a bit is used when it isn't
> > really but they are rare.
> >
> > I think you need to explain what you mean more fully.
> >
> > Tom
>
> -------------------------------------------------------
> This SF.Net email is sponsored by:
> Power Architecture Resource Center: Free content, downloads,
discussions,
> and more. http://solutions.newsforge.com/ibmarch.tmpl
> _______________________________________________
> Valgrind-users mailing list
> Val...@li...
> https://lists.sourceforge.net/lists/listinfo/valgrind-users
|
|
From: Julian S. <js...@ac...> - 2005-10-17 23:47:54
|
> I don't think the problem in this case is related to strcpy, it's > because of the weird read in the last line of the program. Oh .. my mistake. I misread the program. So then the question is .. why do you think this program is OK? After all you really are reading off the end of the array you allocated. ISO C I'm fairly sure would say that the behaviour is therefore undefined. > Anyway, isn't there a way to suppress error messages for partially > invalid reads? Not any more. Although it would be feasible to reinstate the partial-loads-ok hack, defaulted to off, I'd much prefer people to fix code which behaves like this. Do you have any further details of what this library is trying to do? Some kind of fast memcpy? J |
|
From: Dennis L. <pla...@in...> - 2005-10-18 12:18:02
|
Am Dienstag, den 18.10.2005, 00:49 +0100 schrieb Julian Seward: > > I don't think the problem in this case is related to strcpy, it's > > because of the weird read in the last line of the program. > > Oh .. my mistake. I misread the program. > > So then the question is .. why do you think this program is OK? > After all you really are reading off the end of the array you > allocated. ISO C I'm fairly sure would say that the behaviour > is therefore undefined. Yes, its undefined, and also very dangerous on some architectures and OS. On Linux malloc is often not only aligned at 4 bytes boundaries, it also allocates a bit more (often multiples of 4 or 16) than really requested, so those errors don't lead to problems during runtime. On other environments there are two major problems with the (a+9) example: - casting the pointer blindly to int can cause the compiler to omit code which just reads an int, not caring about alignedness, thus giving a SIGBUS on other architectures (btw. wasnt there sometimes an alignment checker tool for V?). - Some OS/arch can set memory access restrictions on byte level, causing this program to SIGSEGV. So, the program has big bugs and valgrind complaining is not only ok, its what V is for. When it comes to glibc&gcc, it knows perfectly whats valid on the OS its installed on, so it knows whether or not it is allowed to do such reads (there are even 8bytes reads with mmx/sse code in some implementations). Thats exactly what valgrinds suppresions should be used for (and imho only for such cases, never for just getting rid of errors youre not intrested in). Inlining is indeed a problem here, especially when it comes to linked in libraries. I agree when people here say that the suppression mechanism needs improvement, like its sometimes impossible to suppress certain bugs in other libraries (like the nvidia driver). But as a general I would like to have V report as much errors as possible, and I consider partial bad accesses and partial definedness as maybe more serious errors than the other ones, since not only the reasons are hard to track down, but the real effects might remain undetected for quite a while causing people to think they are not errors. But they are. As I have missed parts of the discussion before, let me say a few words to the 2 or 3 bytes offset. I personally prefer the way valgrind reports from a C/C++ background, because I see it as a subscript/offset to a pointer, pointing at the first byte *after* the actually allocated data. so ptr[0] (which is "0 bytes after block..:") is the first byte after the block, just good old C/C++ counting. (Just like the levels here at university building start with E[0] ;) greets Dennis |
|
From: Yeshurun, M. <mei...@in...> - 2005-10-18 00:03:26
|
Thanks, the whole issue of partially invalid reads and the problems with string manipulation functions is clear now (I didn't even know the two issues were related.) I guess it is safer to suppress the partial loads individually than to turn all of them off. At least in some of the cases, it looks indeed like a fast memcpy since the top-most function in the stack trace is named my_strdup. So I guess the only option is to add a suppression, right? Thanks, Meir -----Original Message----- From: Julian Seward [mailto:js...@ac...]=20 Sent: Tuesday, October 18, 2005 1:50 AM To: val...@li... Cc: Yeshurun, Meir Subject: Re: [Valgrind-users] User error? - Valgrind 3 failing terribly compared to purify > I don't think the problem in this case is related to strcpy, it's > because of the weird read in the last line of the program. Oh .. my mistake. I misread the program. So then the question is .. why do you think this program is OK? After all you really are reading off the end of the array you allocated. ISO C I'm fairly sure would say that the behaviour is therefore undefined. > Anyway, isn't there a way to suppress error messages for partially > invalid reads? Not any more. Although it would be feasible to reinstate the partial-loads-ok hack, defaulted to off, I'd much prefer people to fix code which behaves like this. Do you have any further details of what this library is trying to do? Some kind of fast memcpy? J |
|
From: Julian S. <js...@ac...> - 2005-10-18 00:23:15
|
> At least in some of the cases, it looks indeed like a fast memcpy since > the top-most function in the stack trace is named my_strdup. So I guess > the only option is to add a suppression, right? Can you rewrite my_strdup so it doesn't fall off the end of arrays? You should be able to do that without a loss of performance using standard loop vectorisation techniques. The only requirement is access to the source. J |
|
From: Yeshurun, M. <mei...@in...> - 2005-10-18 00:30:20
|
That's the only requirement I can't satisfy :). The libraries I'm talking about are from external vendors. Meir -----Original Message----- From: Julian Seward [mailto:js...@ac...]=20 Sent: Tuesday, October 18, 2005 2:25 AM To: Yeshurun, Meir Cc: val...@li... Subject: Re: [Valgrind-users] User error? - Valgrind 3 failing terribly compared to purify > At least in some of the cases, it looks indeed like a fast memcpy since > the top-most function in the stack trace is named my_strdup. So I guess > the only option is to add a suppression, right? Can you rewrite my_strdup so it doesn't fall off the end of arrays? You should be able to do that without a loss of performance using standard loop vectorisation techniques. The only requirement is=20 access to the source. J |
|
From: Christopher T. <Chr...@pa...> - 2005-10-18 00:41:48
|
This has been talked around already, but i wanted to be very clear: the =
example program given here is fundamentally incorrect. It is perfectly =
valid for a conforming compiler to emit code that causes this program to =
segfault on the access to *(int*)(a+9).
(This is done explicitly sometimes in debug allocators -- the requested =
block is located at the end of a VM page, and the following page is =
marked unreadable/unwritable.)
--
Christopher Tate
chr...@pa...
> -----Original Message-----
> From: val...@li...
> [mailto:val...@li...]On Behalf Of
> Yeshurun, Meir
> Sent: Monday, October 17, 2005 1:55 PM
> To: Tom Hughes
> Cc: val...@li...
> Subject: RE: [Valgrind-users] User error? - Valgrind 3=20
> failing terribly
> compared to purify
>=20
>=20
> The following program generates an invalid read even when explicitly
> specifying --partial-loads-ok=3Dyes. Am I missing something here?
>=20
> #include <cstring>
> #include <iostream>
>=20
> using namespace std;
>=20
> int main()
> {
> char *a =3D new char[11];
> strcpy(a, "0123456789");
> int b =3D *(int *)(a + 9); =20
> }
>=20
>=20
> Thanks,
>=20
> Meir
>=20
> -----Original Message-----
> From: val...@li...
> [mailto:val...@li...] On Behalf Of Tom
> Hughes
> Sent: Monday, October 17, 2005 9:07 PM
> To: val...@li...
> Subject: RE: [Valgrind-users] User error? - Valgrind 3=20
> failing terribly
> compared to purify
>=20
> In message
> <942...@ha...rp.i
> ntel.com>
> "Yeshurun, Meir" <mei...@in...> wrote:
>=20
> > There is one issue though: It looks like Valgrind reports partial
> loads
> > as errors by default. I think this shouldn't be the default=20
> behavior.
>=20
> Actually valgrind doesn't report any loads as errors - it only
> reports an error when you use an undefined value in a way that
> would effect the result of the program. In other words when a
> conditional jump depends on it or you use it as a pointer and
> read or write through that pointer.
>=20
> It tracks definedness at bit level, so a partial load will mark
> some bits as defined and leaves others alone. If you then later
> use one of the undefined bits it will complain.
>=20
> There are edge cases where it thinks a bit is used when it isn't
> really but they are rare.
>=20
> I think you need to explain what you mean more fully.
>=20
> Tom
>=20
> --=20
> Tom Hughes (to...@co...)
> http://www.compton.nu/
>=20
>=20
> -------------------------------------------------------
> This SF.Net email is sponsored by:
> Power Architecture Resource Center: Free content, downloads,
> discussions,
> and more. http://solutions.newsforge.com/ibmarch.tmpl
> _______________________________________________
> Valgrind-users mailing list
> Val...@li...
> https://lists.sourceforge.net/lists/listinfo/valgrind-users
>=20
>=20
> -------------------------------------------------------
> This SF.Net email is sponsored by:
> Power Architecture Resource Center: Free content, downloads,=20
> discussions,
> and more. http://solutions.newsforge.com/ibmarch.tmpl
> _______________________________________________
> Valgrind-users mailing list
> Val...@li...
> https://lists.sourceforge.net/lists/listinfo/valgrind-users
>=20
|
|
From: Yeshurun, M. <mei...@in...> - 2005-10-18 10:14:20
|
Thanks! :)
-----Original Message-----
From: Julian Seward [mailto:js...@ac...]=20
Sent: Tuesday, October 18, 2005 12:06 PM
To: Yeshurun, Meir
Subject: Re: [Valgrind-users] User error? - Valgrind 3 failing terribly
compared to purify
Try this. In mc_main.c find mc_LOADVn_slow() and in particular
this:
if (n_addrs_bad > 0)
MAC_(record_address_error)( VG_(get_running_tid)(), a, szB, False
);
change it to
if (n_addrs_bad =3D=3D szB)
MAC_(record_address_error)( VG_(get_running_tid)(), a, szB, False
);
This effectively reinstates the partial-loads-ok hack.
J
On Tuesday 18 October 2005 01:29, you wrote:
> That's the only requirement I can't satisfy :). The libraries I'm
> talking about are from external vendors.
>
> Meir
>
> -----Original Message-----
> From: Julian Seward [mailto:js...@ac...]
> Sent: Tuesday, October 18, 2005 2:25 AM
> To: Yeshurun, Meir
> Cc: val...@li...
> Subject: Re: [Valgrind-users] User error? - Valgrind 3 failing
terribly
> compared to purify
>
> > At least in some of the cases, it looks indeed like a fast memcpy
>
> since
>
> > the top-most function in the stack trace is named my_strdup. So I
>
> guess
>
> > the only option is to add a suppression, right?
>
> Can you rewrite my_strdup so it doesn't fall off the end of arrays?
> You should be able to do that without a loss of performance using
> standard loop vectorisation techniques. The only requirement is
> access to the source.
>
> J
|
|
From: Yeshurun, M. <mei...@in...> - 2005-10-18 11:54:15
|
If you're asking whether it works, yes, it sure does. Thanks again, Meir -----Original Message----- From: Julian Seward [mailto:js...@ac...]=20 Sent: Tuesday, October 18, 2005 12:30 PM To: Yeshurun, Meir Subject: Re: [Valgrind-users] User error? - Valgrind 3 failing terribly compared to purify Does it make any difference? J On Tuesday 18 October 2005 11:14, you wrote: > Thanks! :) > > -----Original Message----- > From: Julian Seward [mailto:js...@ac...] > Sent: Tuesday, October 18, 2005 12:06 PM > To: Yeshurun, Meir > Subject: Re: [Valgrind-users] User error? - Valgrind 3 failing terribly > compared to purify > > > Try this. In mc_main.c find mc_LOADVn_slow() and in particular > this: > > if (n_addrs_bad > 0) > MAC_(record_address_error)( VG_(get_running_tid)(), a, szB, False > ); > > change it to > > if (n_addrs_bad =3D=3D szB) > MAC_(record_address_error)( VG_(get_running_tid)(), a, szB, False > ); > > This effectively reinstates the partial-loads-ok hack. > > J > > On Tuesday 18 October 2005 01:29, you wrote: > > That's the only requirement I can't satisfy :). The libraries I'm > > talking about are from external vendors. > > > > Meir > > > > -----Original Message----- > > From: Julian Seward [mailto:js...@ac...] > > Sent: Tuesday, October 18, 2005 2:25 AM > > To: Yeshurun, Meir > > Cc: val...@li... > > Subject: Re: [Valgrind-users] User error? - Valgrind 3 failing > > terribly > > > compared to purify > > > > > At least in some of the cases, it looks indeed like a fast memcpy > > > > since > > > > > the top-most function in the stack trace is named my_strdup. So I > > > > guess > > > > > the only option is to add a suppression, right? > > > > Can you rewrite my_strdup so it doesn't fall off the end of arrays? > > You should be able to do that without a loss of performance using > > standard loop vectorisation techniques. The only requirement is > > access to the source. > > > > J |
|
From: Tom H. <to...@co...> - 2005-10-17 19:06:49
|
In message <942...@ha...>
"Yeshurun, Meir" <mei...@in...> wrote:
> There is one issue though: It looks like Valgrind reports partial loads
> as errors by default. I think this shouldn't be the default behavior.
Actually valgrind doesn't report any loads as errors - it only
reports an error when you use an undefined value in a way that
would effect the result of the program. In other words when a
conditional jump depends on it or you use it as a pointer and
read or write through that pointer.
It tracks definedness at bit level, so a partial load will mark
some bits as defined and leaves others alone. If you then later
use one of the undefined bits it will complain.
There are edge cases where it thinks a bit is used when it isn't
really but they are rare.
I think you need to explain what you mean more fully.
Tom
--
Tom Hughes (to...@co...)
http://www.compton.nu/
|
|
From: Nicholas N. <nj...@cs...> - 2005-10-17 19:24:06
|
On Mon, 17 Oct 2005, Tom Hughes wrote: >> There is one issue though: It looks like Valgrind reports partial loads >> as errors by default. I think this shouldn't be the default behavior. > > Actually valgrind doesn't report any loads as errors - it only > reports an error when you use an undefined value in a way that > would effect the result of the program. In other words when a > conditional jump depends on it or you use it as a pointer and > read or write through that pointer. > > It tracks definedness at bit level, so a partial load will mark > some bits as defined and leaves others alone. If you then later > use one of the undefined bits it will complain. > > There are edge cases where it thinks a bit is used when it isn't > really but they are rare. > > I think you need to explain what you mean more fully. I think he's referring to the --partial-loads-ok option, but it's set to true by default (at least, that's what "valgrind -h" says). Nick |
|
From: Nick L. <ni...@io...> - 2005-10-17 19:32:31
|
Hi
> Seriously now, my experience with Valgrind has been to the contrary.
> Sure, its tempting to dismiss error messages as false alarms. But so
> far, Valgrind was right about every error that I took the time to
> investigate carefully. You can't blame Valgrind for reporting cases of
> deliberate use of un-initialized values (and I've seen some of those).
Quite agree on the last point, which is why we weren't. As another poster
said, it's actually quite common in comms related code for there to be
valid UMR's.
Based on past good experiences I was surprised just how way off valgrind
was, hence the query really, and the reports of a function return value
being unintialised when it wasn't was particularly frustrating. I haven't
determined the syntax to suppress specific lines yet (can this even be
done?), so had to suppress the entire function which could have masked
genuine problems. As I said, valgrind has certainly been right on some C
projects in the past, so I didn't know what was up in this case. Purify
was spot on though.
I don't like to compare great free opensource efforts against highly
expensive commercial ones, but as well as an overhaul of the suppressions
mechanism, two features that really would be nice, and apologies if these
exist already, would be identifying variable names from addresses wherever
possible, and showing where freed memory was allocated from. In the
following case:
int main()
{
char* buf = malloc(5);
int i,j = 0;
buf[7] = 0;
free(buf);
buf[3] = 12;
return i + j;
}
Valgrind correctly reports the problems, although incorrectly says that
buf[7] is a write 2 bytes beyond the end of the memory when it's 3 bytes
beyond. The uninitialised value in the return is caught, however which
variable is at fault is not identified. Where the freed memory was
allocated from is also not shown.
In contrast, purify identifies correctly the write 3 bytes beyond the end
of the block, shows where the freed memory was allocated from, and most
crucially indicates that the problem in the return is with variable i. Of
course it's clear in this case, but in general, the symbolic
identification can be very useful in locating problems in compound
expressions.
VG
==9484== Invalid write of size 1
==9484== at 0x8048389: main (x.c:8)
==9484== Address 0x1BA5A02F is 2 bytes after a block of size 5 alloc'd
==9484== at 0x1B8FEA35: malloc (vg_replace_malloc.c:149)
==9484== by 0x8048375: main (x.c:5)
==9484==
==9484== Invalid write of size 1
==9484== at 0x80483A0: main (x.c:12)
==9484== Address 0x1BA5A02B is 3 bytes inside a block of size 5 free'd
==9484== at 0x1B8FF548: free (vg_replace_malloc.c:235)
==9484== by 0x8048396: main (x.c:10)
==9484==
==9484== Syscall param exit_group(exit_code) contains uninitialised byte(s)
==9484== at 0x1B9CC3F7: _Exit (in /lib/libc-2.3.2.so)
==9484== by 0x1B93391E: __libc_start_main (in /lib/libc-2.3.2.so)
==9484== by 0x80482CC: ??? (start.S:81)
Purify
**** Purify instrumented ./x (pid 9594) ****
ABW: Array bounds write:
* This is occurring while in:
main [x.c:8]
__libc_start_main [libc.so.6]
_start [crt1.o]
* Writing 1 byte to 0x80b4927 in the heap.
* Address 0x80b4927 is 3 bytes past end of a malloc'd block at 0x80b4920
of 5 bytes.
* This block was allocated from:
malloc [rtlib.o]
main [x.c:5]
__libc_start_main [libc.so.6]
_start [crt1.o]
**** Purify instrumented ./x (pid 9594) ****
FMW: Free memory write:
* This is occurring while in:
main [x.c:12]
__libc_start_main [libc.so.6]
_start [crt1.o]
* Writing 1 byte to 0x80b4923 in the heap.
* Address 0x80b4923 is 3 bytes into a freed block at 0x80b4920 of 5 bytes.
* This block was allocated from:
malloc [rtlib.o]
main [x.c:5]
__libc_start_main [libc.so.6]
_start [crt1.o]
* There have been 0 frees since this block was freed from:
free [rtlib.o]
main [x.c:10]
__libc_start_main [libc.so.6]
_start [crt1.o]
**** Purify instrumented ./x (pid 9594) ****
UMR: Uninitialized memory read:
* This is occurring while in:
main [x.c:14]
__libc_start_main [libc.so.6]
_start [crt1.o]
* Reading 4 bytes from 0xbfffeea0 on the stack.
* Address 0xbfffeea0 is local variable "i" in function main.
Nick
|
|
From: John R.
|
> char* buf = malloc(5); > buf[7] = 0; > Valgrind correctly reports the problems, although incorrectly says that > buf[7] is a write 2 bytes beyond the end of the memory when it's 3 bytes > beyond. Under the schema that is used by average programmers, Purify is correct that a write to buf[7] is 3 bytes beyond the end of the block that was allocated by malloc(5): "Address 0x80b4927 is 3 bytes past end of a malloc'd block at 0x80b4920 of 5 bytes." The schema is: number the bytes. The address of the last allocated byte is &buf[4], and &buf[7] - &buf[4] is 3. &buf[5] is "one byte beyond the end." However, under the schema that is used by the most experienced and skillful C programmers, Valgrind is correct that a write to buf[7] is 2 bytes beyond the end of the block. The schema is: number the [zero-width] boundaries between the bytes, and associate a byte with its lower-numbered boundary. The end of the block is the _boundary_ associated with buf[5], and &buf[7] - &buf[5] is 2. &buf[5] is "zero bytes beyond the end" because the boundary between the byte associated with offset +4 and the byte associated with offset +5 _is_ the [zero-width] end of the block. -- |
|
From: Julian S. <js...@ac...> - 2005-10-17 23:25:17
|
> > Seriously now, my experience with Valgrind has been to the contrary. > > Sure, its tempting to dismiss error messages as false alarms. But so > > far, Valgrind was right about every error that I took the time to > > investigate carefully. You can't blame Valgrind for reporting cases of > > deliberate use of un-initialized values (and I've seen some of those). > > Quite agree on the last point, which is why we weren't. As another poster > said, it's actually quite common in comms related code for there to be > valid UMR's. The way I think about memcheck is slightly different. Memcheck cannot exactly partition all possible programs into those which do really use uninitialised values and those which don't. But mostly it's pretty good. Nevertheless there is a set of programs which it incorrectly classifies. For that set, it leans in the direction of reporting an error even when one doesn't exist. The reason is simple: you can usually make it shut up by adding a few unnecessary initialisations in the right place. The KDE folks did that, I believe, at some point in the KDE 3.0 line. Once you've made it shut up, you at least know that your program is now (probably) safe against use of uninitialised values. The alternative is to make it not report errors from such programs. That seems more convenient, but from an absolutist perspective of detecting all possible errors (so as to enable programmers to maximise software reliability, which was the original design goal for memcheck), it seems a poor alternative. In practice the fact that large systems like Qt4 and KDE 3.X run essentially with zero complaints on memcheck leads me to believe that the strategy is a reasonable one. J |
|
From: Nick L. <ni...@io...> - 2005-10-18 00:38:13
|
Hi > For that set, it leans in the direction of reporting an error even when > one doesn't exist. The reason is simple: you can usually make it shut up > by adding a few unnecessary initialisations in the right place. The > KDE folks did that, I believe, at some point in the KDE 3.0 line. > Once you've made it shut up, you at least know that your program is > now (probably) safe against use of uninitialised values. Thanks for the response Julian. You're quite correct, and that's the right approach. e.g. the RAND_bytes() function generates errors on the buffer it's filling in, so just memset() the buffer first. No problem with that at all, and a totally standad technique in these cases. The problem as much as anything though was with the value returned from the function that I mentioned in the first post. No amount of assigning to the variable being returned would stop valgrind from reporting the returned value in some cases as uninitialised, and preinitialising to zero the variable accepting the returned value prior to the assignment made no difference either. There were also quite a few reports of memory that wasn't in a known area, i.e. not stack'd, alloc'd etc., but where there was actually no problem at all, and as far as I could tell, a genuine error of a free memory write in libssh2 wasn't caught. On other large projects with the same compiler etc. it's done well though, so who knows? I was surprised, hence the post :) On the reply to the offset issue, there appears to be a confusion over offsets vs. byte counts. In the case of &buf[7], where buf is a buffer of 5 bytes, Purify is correct to say that &buf[7] is 3 bytes beyond the end as it's reporting the byte count. valgrinds report of 2 is really the byte offset, although worded as a count, but if interpreted as an offset then also correct as if we've set a variable 'end' to (beyond) the end of the buffer, &end[2] (offset 2) would be &buf[7] (the 3rd byte relative to the end). Nick |