|
From: Stewart S. <st...@fl...> - 2009-11-27 04:42:39
|
Hi!
I have the following code snippet
char nf= *null_flags;
char r1nf= *(null_flags + s->rec_buff_length);
int eq= nf==r1nf;
fprintf(stderr, "man compare: %x\n", eq);
fprintf(stderr, "byte compare: %d\n",
(char)((char)*(char*)(null_flags)) == (char)(*(char*)(null_flags +
s->rec_buff_length)));
fprintf(stderr, "memcmp compare: %d\n", memcmp(null_flags ,
null_flags + s->rec_buff_length, 1));
Where the first printf (and the code leading to it) runs fine. No
problem at all.
The second and third printf calls here get a valgrind warning.
First printf:
==18960== Use of uninitialised value of size 8
==18960== at 0x792485B: _itoa_word (_itoa.c:195)
==18960== by 0x7926474: vfprintf (vfprintf.c:1600)
==18960== by 0x792A19F: buffered_vfprintf (vfprintf.c:2241)
==18960== by 0x7924FAD: vfprintf (vfprintf.c:1306)
==18960== by 0x792FB47: fprintf (fprintf.c:33)
==18960== by 0x5C3953: Table::compare_record() (table.cc:3522)
==18960== by 0x55CAFC: write_record(Session*, Table*,
st_copy_info*) (sql_insert.cc:846)
==18960== Conditional jump or move depends on uninitialised value(s)
==18960== at 0x7924865: _itoa_word (_itoa.c:195)
==18960== by 0x7926474: vfprintf (vfprintf.c:1600)
==18960== by 0x792A19F: buffered_vfprintf (vfprintf.c:2241)
==18960== by 0x7924FAD: vfprintf (vfprintf.c:1306)
==18960== by 0x792FB47: fprintf (fprintf.c:33)
==18960== by 0x5C3953: Table::compare_record() (table.cc:3522)
And the second in the memcmp() call (which if i copy the valgrind
implementation in, it gets the warning on the if(res) line of it:
res = ((int)a0) - ((int)b0); \
-->> if (res != 0) \
return res; \
I've disassembled both parts, and it looks correct (although perhaps
I'm wrong, help welcome)
leading up to first printf:
90 nop
48 8b 45 d8 mov -0x28(%rbp),%rax
48 8b 80 e0 00 00 00 mov 0xe0(%rax),%rax
0f b6 00 movzbl (%rax),%eax
88 45 ff mov %al,-0x1(%rbp)
48 8b 45 d8 mov -0x28(%rbp),%rax
48 8b 90 e0 00 00 00 mov 0xe0(%rax),%rdx
48 8b 45 d8 mov -0x28(%rbp),%rax
48 8b 00 mov (%rax),%rax
8b 80 24 02 00 00 mov 0x224(%rax),%eax
89 c0 mov %eax,%eax
48 8d 04 02 lea (%rdx,%rax,1),%rax
0f b6 00 movzbl (%rax),%eax
88 45 fe mov %al,-0x2(%rbp)
0f b6 45 ff movzbl -0x1(%rbp),%eax
3a 45 fe cmp -0x2(%rbp),%al
0f 94 c0 sete %al
0f b6 c0 movzbl %al,%eax
89 45 f0 mov %eax,-0x10(%rbp)
48 8b 05 ef 6b 62 00 mov 0x626bef(%rip),%rax # bf86f8 <stderr>
8b 55 f0 mov -0x10(%rbp),%edx
be d5 d1 8b 00 mov $0x8bd1d5,%esi
48 89 c7 mov %rax,%rdi
b8 00 00 00 00 mov $0x0,%eax
e8 12 10 42 00 callq 9f2b30 <fprintf@plt>
for the 2nd:
48 8b 45 d8 mov -0x28(%rbp),%rax
48 8b 80 e0 00 00 00 mov 0xe0(%rax),%rax
0f b6 10 movzbl (%rax),%edx
48 8b 45 d8 mov -0x28(%rbp),%rax
48 8b 80 98 00 00 00 mov 0x98(%rax),%rax
0f b6 00 movzbl (%rax),%eax
38 c2 cmp %al,%dl
0f 94 c0 sete %al
0f b6 d0 movzbl %al,%edx
48 8b 05 ae 6b 62 00 mov 0x626bae(%rip),%rax # bf86f8 <stderr>
be e6 d1 8b 00 mov $0x8bd1e6,%esi
48 89 c7 mov %rax,%rdi
b8 00 00 00 00 mov $0x0,%eax
e8 d4 0f 42 00 callq 9f2b30 <fprintf@plt>
So I'm a bit stuck... at first I thought we could in fact have
unitialized data... but doing the manual compare there (the first one)
and not getting a warning as well as inspecting the code and memory
contents for sanity, I'm quite stuck.
There has been no difference between gcc 4.3 and 4.4 nor between
valgrind 3.5 and trunk.
Does anybody have any ideas on what I can look at next? or tips on
debugging valgrind? perhaps tracking back as to exactly which operand
to what instruction it's complaining about? or if can get it to warn earlier?
--
Stewart Smith
|
|
From: Dan K. <da...@ke...> - 2009-11-27 05:08:26
|
On Thu, Nov 26, 2009 at 8:24 PM, Stewart Smith <st...@fl...> wrote: > I have the following code snippet > > char nf= *null_flags; > char r1nf= *(null_flags + s->rec_buff_length); > int eq= nf==r1nf; > fprintf(stderr, "man compare: %x\n", eq); > > fprintf(stderr, "byte compare: %d\n", > (char)((char)*(char*)(null_flags)) == (char)(*(char*)(null_flags + > s->rec_buff_length))); ... Please post a compilable minimal test case, it's hard to guess without seeing that. - Dan |
|
From: Kaz K. <kky...@gm...> - 2009-11-27 05:32:30
|
On Thu, Nov 26, 2009 at 8:24 PM, Stewart Smith <st...@fl...> wrote:
> The second and third printf calls here get a valgrind warning.
>
> First printf:
> ==18960== Use of uninitialised value of size 8
> ==18960== Conditional jump or move depends on uninitialised value(s)
Valgrind diagnoses places where uninitialized data is used in some way
that could have a side effect or alter the control flow.
Newer versions of Valgrind have an option that you should use:
--track-origins
Just like Valgrind tracks the origins of which call stack allocated
some misused memory, it also tracks the origin of some uninitialized
value. This could help you quickly find the answer.
It's possible that the uninitialized value originated quite far away
from where it is manifested.
Valgrind doesn't show uninitialized uses right at the origin because
that would lead to false
positives. For instance, structures have gaps in them which are left
uninitialized sometimes.
Or what if you are using unions?
union u { char big_array[256]; short little_int; }
If you make an instance of u, and initialize the ``little_int''
member, that leaves most of the big_array space uninitialized (perhaps
254 bytes out of 256). You can assign one such union to another; that
is well-defined C code:
union u a, b;
a.little_int = 42;
b = a; /* b.little_int is 42 now, perfectly valid */
So at this line b = a, a whole lot of uninitialized bits get copied.
We don't want valgrind to be bothering us with that. But the
``undefinedness'' of those bits gets copied along with them.
|