|
From: Robert C. <r.c...@gs...> - 2007-10-16 10:40:39
|
I have quite a lot of functions in which I pass a pointer to a structure at first uninitialised that I then initialise within the function. I use the return value of the function to indicate whether the process was successful, I then wrap the function call in an if() to exit if the function wasn't successful. However Valgrind seems to see this as a test of an uninitialised variable, which is isn't, because the function is evaluated before the condition. This results in me having a very large number of errors of this sort: Conditional jump or move depends on uninitialised value(s) is there a reason why it doesn't see this, is it just too in depth to expect or have I misunderstood something? This is not a criticism of Valgrind, it has already proved very useful to me, just want to understand :-) Also, it seems if you allocate a char array, then fill some of its elements and terminate it properly valgrind gives the same error as above, I understand the logic, as I have not initialised every element. Is there a way to do this without looping over all elements and giving them a value? Many thanks, Rob. |
|
From: Julian S. <js...@ac...> - 2007-10-16 10:50:25
|
On Tuesday 16 October 2007 12:40, Robert Cussons wrote: > I have quite a lot of functions in which I pass a pointer to a structure > at first uninitialised [...] A bit hard to follow. Can you send a small test program which illustrates the problem(s)? That would help. J |
|
From: Robert C. <r.c...@gs...> - 2007-10-16 11:47:40
|
Julian Seward wrote: > On Tuesday 16 October 2007 12:40, Robert Cussons wrote: >> I have quite a lot of functions in which I pass a pointer to a structure >> at first uninitialised [...] > > A bit hard to follow. Can you send a small test program which > illustrates the problem(s)? That would help. > > J Of course, sorry, it wasn't that clear. So for example I have a file "interactionfile" containing information that I want to read into a struct called Inf of type Information. char* informationfile = argv[optind+3]; Information Inf; if (readInteractionfromFile(&Inf, informationfile)) exit(-1); readInteractionfromFile reads lines from the file and stores them into elements in the structure Inf, if the file is not in the expected format, readInteractionfromFile outputs a message and returns a non-zero value, causing the if to be entered and the routine to exit. So inside the function, Inf is initialised, but it seems that valgrind doesn't check for that, it just sees the if, sees Inf, which is not initialised until you descend into the function, which is of course done before the if condition is evaluated. and gives the warning: Conditional jump or move depends on uninitialised value(s) Hope that's a bit clearer. Thanks for the help. |
|
From: Christoph B. <bar...@or...> - 2007-10-16 11:55:45
|
Am Dienstag, 16. Oktober 2007 schrieb Robert Cussons: > readInteractionfromFile reads lines from the file and stores them into > elements in the structure Inf, if the file is not in the expected > format, readInteractionfromFile outputs a message and returns a non-zero > value, causing the if to be entered and the routine to exit. So inside > the function, Inf is initialised, but it seems that valgrind doesn't > check for that, it just sees the if, sees Inf, which is not initialised > until you descend into the function, which is of course done before the > if condition is evaluated. and gives the warning: > > Conditional jump or move depends on uninitialised value(s) I am not convinced that this is a valgrind error. Most of the time people interpret the valgrind result wrongly. To clarify the situation you should provide a compilable small testcase that shows the problem. If this is not possible you might do the following: 1. Ensure that you are compiling with debug symbols enabled and without optimization. 2. Post the whole valgrind message. The error and the tracebacks. 3. Post the declarations of your structs and the whole code of readInteractionfromFile. Christoph |
|
From: Robert C. <r.c...@gs...> - 2007-10-16 12:47:39
|
Christoph Bartoschek wrote: > Am Dienstag, 16. Oktober 2007 schrieb Robert Cussons: > >> readInteractionfromFile reads lines from the file and stores them into >> elements in the structure Inf, if the file is not in the expected >> format, readInteractionfromFile outputs a message and returns a non-zero >> value, causing the if to be entered and the routine to exit. So inside >> the function, Inf is initialised, but it seems that valgrind doesn't >> check for that, it just sees the if, sees Inf, which is not initialised >> until you descend into the function, which is of course done before the >> if condition is evaluated. and gives the warning: >> >> Conditional jump or move depends on uninitialised value(s) > > I am not convinced that this is a valgrind error. Most of the time people > interpret the valgrind result wrongly. This is obviously more than possible, I am very new to valgrind so I may well not be understanding it's messages correctly. > To clarify the situation you should > provide a compilable small testcase that shows the problem. I am attempting to do this at the moment using another function that gave the same error as the one I mentioned, it seems to come up with no complaints from Valgrind (which makes it even less likely it's a shortcoming of valgrind), so I'll keep adding to it to make it more and more similar and see if I can isolate what's causing the valgrind complaints in the other case. > If this is not > possible you might do the following: > > 1. Ensure that you are compiling with debug symbols enabled and without > optimization. compiling without optimisation and with debug information turned on if that's what you mean by debug symbols enabled (from gcc manual): -g Produce debugging information in the operating system’s native format -O0 no optimisation Thanks for the help, Rob. |
|
From: Paul P. <ppl...@gm...> - 2007-10-16 14:07:46
|
Robert Cussons wrote:
>I am attempting to do this at the moment using another function that
>gave the same error as the one I mentioned, it seems to come up with no
>complaints from Valgrind (which makes it even less likely it's a
>shortcoming of valgrind), so I'll keep adding to it to make it more and
>more similar and see if I can isolate what's causing the valgrind
>complaints in the other case.
>
One "common" way to return uninitialized data from a function is this:
int fn(int x)
{
int y;
if (x) return 1;
return y; // returns "uninitialized" when x==0
}
Later in the code:
int n = 0;
if (fn(n)) { // VG complains here
Cheers,
|
|
From: Robert C. <r.c...@gs...> - 2007-10-16 14:33:07
|
Christoph Bartoschek wrote:
> Am Dienstag, 16. Oktober 2007 schrieb Robert Cussons:
>
>> readInteractionfromFile reads lines from the file and stores them into
>> elements in the structure Inf, if the file is not in the expected
>> format, readInteractionfromFile outputs a message and returns a non-zero
>> value, causing the if to be entered and the routine to exit. So inside
>> the function, Inf is initialised, but it seems that valgrind doesn't
>> check for that, it just sees the if, sees Inf, which is not initialised
>> until you descend into the function, which is of course done before the
>> if condition is evaluated. and gives the warning:
>>
>> Conditional jump or move depends on uninitialised value(s)
>
> I am not convinced that this is a valgrind error. Most of the time people
> interpret the valgrind result wrongly. To clarify the situation you should
> provide a compilable small testcase that shows the problem. If this is not
> possible you might do the following:
>
> 1. Ensure that you are compiling with debug symbols enabled and without
> optimization.
> 2. Post the whole valgrind message. The error and the tracebacks.
> 3. Post the declarations of your structs and the whole code of
> readInteractionfromFile.
>
> Christoph
>
Ok, this is not really like the original thing I had in mind, and I have
found that a number of the other places that I thought were complaints
about my code actually referred to places in included libraries.
==9866== Conditional jump or move depends on uninitialised value(s)
==9866== at 0x401E66C: rawmemchr (mc_replace_strmem.c:547)
==9866== by 0x4098E61: (within /lib/tls/i686/cmov/libc-2.3.6.so)
==9866== by 0x408DBDC: vsscanf (in /lib/tls/i686/cmov/libc-2.3.6.so)
==9866== by 0x40890AD: sscanf (in /lib/tls/i686/cmov/libc-2.3.6.so)
==9866== by 0x804864D: main (in /the/cussons/testvalgrind/test4)
I was reading errors like the above to mean that there is a conditional
in main that is dependent on an uninitialised value, which I knew but
thought the problem should be resolved by the value being set during the
function, however the above error can also mean that somewhere in the
rawmemchr function there is a variable used that is uninitialised and
just because I happen to call that function, I get the warning, is that
correct? Now I see the big thing with suppression :-)
I have attached the below just in case anyone is interested, the output
I get from valgrind is given at the bottom. I guess that the point here
is that if we satsify the if condition then the variables: typename,
gamma, kappa and label aren't initialised, because the values aren't
there to initialise them to, of course valgrind doesn't know that I
don't care about this eventuality as if it happens the program is going
to exit straight away. To avoid this complaint I suppose I would have to
loop over all the elements in each array giving them an initial value,
or is there an easier way to get valgrind to accept them as initialised?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// for valgrind to accept client requests
#include "/the/cussons/include/valgrind/memcheck.h"
#define BUFSIZE 255
int main()
{
char buf[BUFSIZE];
char typename[BUFSIZE], label[BUFSIZE];
double gamma, kappa;
VALGRIND_CHECK_VALUE_IS_DEFINED(typename);
VALGRIND_CHECK_VALUE_IS_DEFINED(gamma);
VALGRIND_CHECK_VALUE_IS_DEFINED(kappa);
VALGRIND_CHECK_VALUE_IS_DEFINED(label);
if (sscanf(buf, "%s %lf %lf %s", typename, &gamma, &kappa, label) < 3)
{
fprintf(stderr, "malformed line\n>>%s<<\n", buf,"\n");
return -1;
}
return 0;
}
$ valgrind --leak-check=yes ./test4
==12942== Memcheck, a memory error detector.
==12942== Copyright (C) 2002-2007, and GNU GPL'd, by Julian Seward et al.
==12942== Using LibVEX rev 1732, a library for dynamic binary translation.
==12942== Copyright (C) 2004-2007, and GNU GPL'd, by OpenWorks LLP.
==12942== Using valgrind-3.2.3, a dynamic binary instrumentation framework.
==12942== Copyright (C) 2000-2007, and GNU GPL'd, by Julian Seward et al.
==12942== For more details, rerun with: -v
==12942==
==12942== Uninitialised byte(s) found during client check request
==12942== at 0x80484CF: main (in /the/cussons/testvalgrind/test4)
==12942== Address 0xBEE0B472 is on thread 1's stack
==12942==
==12942== Uninitialised byte(s) found during client check request
==12942== at 0x8048535: main (in /the/cussons/testvalgrind/test4)
==12942== Address 0xBEE0B368 is on thread 1's stack
==12942==
==12942== Uninitialised byte(s) found during client check request
==12942== at 0x804859B: main (in /the/cussons/testvalgrind/test4)
==12942== Address 0xBEE0B360 is on thread 1's stack
==12942==
==12942== Uninitialised byte(s) found during client check request
==12942== at 0x8048601: main (in /the/cussons/testvalgrind/test4)
==12942== Address 0xBEE0B373 is on thread 1's stack
==12942==
==12942== Conditional jump or move depends on uninitialised value(s)
==12942== at 0x401E66C: rawmemchr (mc_replace_strmem.c:547)
==12942== by 0x4098E61: (within /lib/tls/i686/cmov/libc-2.3.6.so)
==12942== by 0x408DBDC: vsscanf (in /lib/tls/i686/cmov/libc-2.3.6.so)
==12942== by 0x40890AD: sscanf (in /lib/tls/i686/cmov/libc-2.3.6.so)
==12942== by 0x804864D: main (in /the/cussons/testvalgrind/test4)
==12942==
==12942== Conditional jump or move depends on uninitialised value(s)
==12942== at 0x401E673: rawmemchr (mc_replace_strmem.c:547)
==12942== by 0x4098E61: (within /lib/tls/i686/cmov/libc-2.3.6.so)
==12942== by 0x408DBDC: vsscanf (in /lib/tls/i686/cmov/libc-2.3.6.so)
==12942== by 0x40890AD: sscanf (in /lib/tls/i686/cmov/libc-2.3.6.so)
==12942== by 0x804864D: main (in /the/cussons/testvalgrind/test4)
==12942==
==12942== Conditional jump or move depends on uninitialised value(s)
==12942== at 0x407F09A: _IO_vfscanf (in /lib/tls/i686/cmov/libc-2.3.6.so)
==12942== by 0x408DBF8: vsscanf (in /lib/tls/i686/cmov/libc-2.3.6.so)
==12942== by 0x40890AD: sscanf (in /lib/tls/i686/cmov/libc-2.3.6.so)
==12942== by 0x804864D: main (in /the/cussons/testvalgrind/test4)
==12942==
==12942== Use of uninitialised value of size 4
==12942== at 0x407F0B5: _IO_vfscanf (in /lib/tls/i686/cmov/libc-2.3.6.so)
==12942== by 0x408DBF8: vsscanf (in /lib/tls/i686/cmov/libc-2.3.6.so)
==12942== by 0x40890AD: sscanf (in /lib/tls/i686/cmov/libc-2.3.6.so)
==12942== by 0x804864D: main (in /the/cussons/testvalgrind/test4)
==12942==
==12942== Conditional jump or move depends on uninitialised value(s)
==12942== at 0x407F0F9: _IO_vfscanf (in /lib/tls/i686/cmov/libc-2.3.6.so)
==12942== by 0x408DBF8: vsscanf (in /lib/tls/i686/cmov/libc-2.3.6.so)
==12942== by 0x40890AD: sscanf (in /lib/tls/i686/cmov/libc-2.3.6.so)
==12942== by 0x804864D: main (in /the/cussons/testvalgrind/test4)
==12942==
==12942== Conditional jump or move depends on uninitialised value(s)
==12942== at 0x40975EB: _IO_sputbackc (in
/lib/tls/i686/cmov/libc-2.3.6.so)
==12942== by 0x407F112: _IO_vfscanf (in /lib/tls/i686/cmov/libc-2.3.6.so)
==12942== by 0x408DBF8: vsscanf (in /lib/tls/i686/cmov/libc-2.3.6.so)
==12942== by 0x40890AD: sscanf (in /lib/tls/i686/cmov/libc-2.3.6.so)
==12942== by 0x804864D: main (in /the/cussons/testvalgrind/test4)
==12942==
==12942== Conditional jump or move depends on uninitialised value(s)
==12942== at 0x4097605: _IO_sputbackc (in
/lib/tls/i686/cmov/libc-2.3.6.so)
==12942== by 0x407F112: _IO_vfscanf (in /lib/tls/i686/cmov/libc-2.3.6.so)
==12942== by 0x408DBF8: vsscanf (in /lib/tls/i686/cmov/libc-2.3.6.so)
==12942== by 0x40890AD: sscanf (in /lib/tls/i686/cmov/libc-2.3.6.so)
==12942== by 0x804864D: main (in /the/cussons/testvalgrind/test4)
==12942==
==12942== Conditional jump or move depends on uninitialised value(s)
==12942== at 0x407F92C: _IO_vfscanf (in /lib/tls/i686/cmov/libc-2.3.6.so)
==12942== by 0x408DBF8: vsscanf (in /lib/tls/i686/cmov/libc-2.3.6.so)
==12942== by 0x40890AD: sscanf (in /lib/tls/i686/cmov/libc-2.3.6.so)
==12942== by 0x804864D: main (in /the/cussons/testvalgrind/test4)
==12942==
==12942== Conditional jump or move depends on uninitialised value(s)
==12942== at 0x407F955: _IO_vfscanf (in /lib/tls/i686/cmov/libc-2.3.6.so)
==12942== by 0x408DBF8: vsscanf (in /lib/tls/i686/cmov/libc-2.3.6.so)
==12942== by 0x40890AD: sscanf (in /lib/tls/i686/cmov/libc-2.3.6.so)
==12942== by 0x804864D: main (in /the/cussons/testvalgrind/test4)
==12942==
==12942== Use of uninitialised value of size 4
==12942== at 0x407F970: _IO_vfscanf (in /lib/tls/i686/cmov/libc-2.3.6.so)
==12942== by 0x408DBF8: vsscanf (in /lib/tls/i686/cmov/libc-2.3.6.so)
==12942== by 0x40890AD: sscanf (in /lib/tls/i686/cmov/libc-2.3.6.so)
==12942== by 0x804864D: main (in /the/cussons/testvalgrind/test4)
==12942==
==12942== Conditional jump or move depends on uninitialised value(s)
==12942== at 0x407F9AD: _IO_vfscanf (in /lib/tls/i686/cmov/libc-2.3.6.so)
==12942== by 0x408DBF8: vsscanf (in /lib/tls/i686/cmov/libc-2.3.6.so)
==12942== by 0x40890AD: sscanf (in /lib/tls/i686/cmov/libc-2.3.6.so)
==12942== by 0x804864D: main (in /the/cussons/testvalgrind/test4)
==12942==
==12942== Conditional jump or move depends on uninitialised value(s)
==12942== at 0x407F9D6: _IO_vfscanf (in /lib/tls/i686/cmov/libc-2.3.6.so)
==12942== by 0x408DBF8: vsscanf (in /lib/tls/i686/cmov/libc-2.3.6.so)
==12942== by 0x40890AD: sscanf (in /lib/tls/i686/cmov/libc-2.3.6.so)
==12942== by 0x804864D: main (in /the/cussons/testvalgrind/test4)
==12942==
==12942== Use of uninitialised value of size 4
==12942== at 0x407F9F1: _IO_vfscanf (in /lib/tls/i686/cmov/libc-2.3.6.so)
==12942== by 0x408DBF8: vsscanf (in /lib/tls/i686/cmov/libc-2.3.6.so)
==12942== by 0x40890AD: sscanf (in /lib/tls/i686/cmov/libc-2.3.6.so)
==12942== by 0x804864D: main (in /the/cussons/testvalgrind/test4)
==12942==
==12942== Conditional jump or move depends on uninitialised value(s)
==12942== at 0x401E24B: strlen (mc_replace_strmem.c:246)
==12942== by 0x4075163: vfprintf (in /lib/tls/i686/cmov/libc-2.3.6.so)
==12942== by 0x4070C82: (within /lib/tls/i686/cmov/libc-2.3.6.so)
==12942== by 0x407188E: vfprintf (in /lib/tls/i686/cmov/libc-2.3.6.so)
==12942== by 0x407A2E1: fprintf (in /lib/tls/i686/cmov/libc-2.3.6.so)
==12942== by 0x804867A: main (in /the/cussons/testvalgrind/test4)
==12942==
==12942== Conditional jump or move depends on uninitialised value(s)
==12942== at 0x401E255: strlen (mc_replace_strmem.c:246)
==12942== by 0x4075163: vfprintf (in /lib/tls/i686/cmov/libc-2.3.6.so)
==12942== by 0x4070C82: (within /lib/tls/i686/cmov/libc-2.3.6.so)
==12942== by 0x407188E: vfprintf (in /lib/tls/i686/cmov/libc-2.3.6.so)
==12942== by 0x407A2E1: fprintf (in /lib/tls/i686/cmov/libc-2.3.6.so)
==12942== by 0x804867A: main (in /the/cussons/testvalgrind/test4)
==12942==
==12942== Syscall param write(buf) points to uninitialised byte(s)
==12942== at 0x4000792: (within /lib/ld-2.3.6.so)
==12942== by 0x4095394: (within /lib/tls/i686/cmov/libc-2.3.6.so)
==12942== by 0x4095600: _IO_file_xsputn (in
/lib/tls/i686/cmov/libc-2.3.6.so)
==12942== by 0x4070CEA: (within /lib/tls/i686/cmov/libc-2.3.6.so)
==12942== by 0x407188E: vfprintf (in /lib/tls/i686/cmov/libc-2.3.6.so)
==12942== by 0x407A2E1: fprintf (in /lib/tls/i686/cmov/libc-2.3.6.so)
==12942== by 0x804867A: main (in /the/cussons/testvalgrind/test4)
==12942== Address 0xBEE08BE9 is on thread 1's stack
malformed line
>>_��<<
==12942==
==12942== ERROR SUMMARY: 43 errors from 20 contexts (suppressed: 11 from 1)
==12942== malloc/free: in use at exit: 0 bytes in 0 blocks.
==12942== malloc/free: 0 allocs, 0 frees, 0 bytes allocated.
==12942== For counts of detected errors, rerun with: -v
==12942== All heap blocks were freed -- no leaks are possible.
|
|
From: Christoph B. <bar...@or...> - 2007-10-16 14:43:54
|
Am Dienstag, 16. Oktober 2007 schrieb Robert Cussons: > Ok, this is not really like the original thing I had in mind, and I have > found that a number of the other places that I thought were complaints > about my code actually referred to places in included libraries. > > ==9866== Conditional jump or move depends on uninitialised value(s) > ==9866== at 0x401E66C: rawmemchr (mc_replace_strmem.c:547) > ==9866== by 0x4098E61: (within /lib/tls/i686/cmov/libc-2.3.6.so) > ==9866== by 0x408DBDC: vsscanf (in /lib/tls/i686/cmov/libc-2.3.6.so) > ==9866== by 0x40890AD: sscanf (in /lib/tls/i686/cmov/libc-2.3.6.so) > ==9866== by 0x804864D: main (in /the/cussons/testvalgrind/test4) There is no line number shown for main. This indicates that you did not compile with debug symbols. Use -g for memcheck. > I was reading errors like the above to mean that there is a conditional > in main that is dependent on an uninitialised value, which I knew but > thought the problem should be resolved by the value being set during the > function, however the above error can also mean that somewhere in the > rawmemchr function there is a variable used that is uninitialised and > just because I happen to call that function, I get the warning, is that > correct? Now I see the big thing with suppression :-) You are right. The error might happen along the whole path from main to rawmemchr. But you should assume that sscanf and the functions it calls work correctly, if you do not implement them right now. > I have attached the below just in case anyone is interested, the output > I get from valgrind is given at the bottom. I guess that the point here > is that if we satsify the if condition then the variables: typename, > gamma, kappa and label aren't initialised, because the values aren't > there to initialise them to, of course valgrind doesn't know that I > don't care about this eventuality as if it happens the program is going > to exit straight away. To avoid this complaint I suppose I would have to > loop over all the elements in each array giving them an initial value, > or is there an easier way to get valgrind to accept them as initialised? No. Your program is not correct. The array buf is filled with garbage values that are not initialized. The sscanf() call tries to interpret the garbage and this results in the valgrind messages below. The correct approach here is to fill the buffer with a string that sscanf can interpret. Greetings Christoph |