|
From: Robert W. <rj...@du...> - 2006-04-09 19:20:56
|
Hi all,
One of my co-workers is seeing some unhappy warnings from Valgrind when
we compile the following piece of code with our compiler (the PathScale
compiler):
#include <stdio.h>
=20
typedef struct ss {
int type :8; /* Data type of repeated value */
unsigned ndchar :1; /* 1 if prev type was nondelim char *=
/
unsigned item1 :1; /* 1 if first item in I/O list */
unsigned ldwinit :1; /* 1 if first call to _ld_write */
} S;
=20
void foo(S *p){
if (p->ldwinit)
printf("pass\n");
}
=20
main(void) {
S x;
x.ldwinit =3D 1;
foo(&x);
}
Valgrind says:
=3D=3D9412=3D=3D Conditional jump or move depends on uninitialised =
value(s)
=3D=3D9412=3D=3D at 0x8048398: foo (t.c:11)
=3D=3D9412=3D=3D by 0x80483ED: main (t.c:18)
As it turns out, the code we were generating for these bitfield
operations was not very optimal (which we will fix) but were still
correct operations. Valgrind gets confused, though.
The code that writes the bitfield is:
# 17 x.ldwinit =3D 1;
movl $1,%edx #
movl -16(%ebp),%ecx # x
movl %ecx,%eax #
shrl $10,%eax #
xorl %eax,%edx #
shll $31,%edx #
shrl $21,%edx #
xorl %ecx,%edx #
movl %edx,-16(%ebp) # x
The code that reads the bitfield (and causes the warning) in the foo
function looks like this:
# 11 if (p->ldwinit)
movl 8(%ebp),%eax # p
movl 0(%eax),%eax #
shll $21,%eax #
shrl $31,%eax #
testl %eax,%eax #
je .L_0_3 #
As I said, both pieces of code are suboptimal, but nothing logically
wrong with them. Any idea why Valgrind is giving a warning here?
This happens on Valgrind 2.2.0 and the latest svn trunk for Valgrind 3.
This doesn't happen with gcc, but it does generate completely different
code here.
Regards,
Robert.
--=20
Robert Walsh
Amalgamated Durables, Inc. - "We don't make the things you buy."
Email: rj...@du...
|
> typedef struct ss {
> int type :8; /* Data type of repeated value */
> unsigned ndchar :1; /* 1 if prev type was nondelim char */
> unsigned item1 :1; /* 1 if first item in I/O list */
> unsigned ldwinit :1; /* 1 if first call to _ld_write */
> } S;
>
> void foo(S *p){
> if (p->ldwinit)
> printf("pass\n");
> }
>
> main(void) {
> S x;
> x.ldwinit = 1;
> foo(&x);
> }
>
> Valgrind says:
>
> ==9412== Conditional jump or move depends on uninitialised value(s)
> ==9412== at 0x8048398: foo (t.c:11)
> ==9412== by 0x80483ED: main (t.c:18)
>
> As it turns out, the code we were generating for these bitfield
> operations was not very optimal (which we will fix) but were still
> correct operations. Valgrind gets confused, though.
>
> The code that writes the bitfield is:
>
> # 17 x.ldwinit = 1;
> movl $1,%edx #
> movl -16(%ebp),%ecx # x
> movl %ecx,%eax #
> shrl $10,%eax #
> xorl %eax,%edx #
> shll $31,%edx #
> shrl $21,%edx #
> xorl %ecx,%edx #
> movl %edx,-16(%ebp) # x
Valgrind does not recognize that the _same_ uninitialized bit
has been XORed twice into bit 10 (the 1<<10 bit), along with a 1.
Therefore valgrind believes that bit 10 still is uninitialized.
Even simpler, valgrind does not recognize that ((a + u) - u)
is just as initialized as 'a', even though 'u' is uninitialized
[assuming of course that compiler has not optimized away
the integer add and subtract]:
$ cat vgtest.c
int
main(int argc, char *argv[])
{
int u; /* uninitialized */
if (argc==((argc + u) - u))
return 5;
return 7;
}
$ gcc -O0 -g vgtest.c
$ gdb a.out
(gdb) x/15i main
0x8048364 <main+28>: mov 0xfffffffc(%ebp),%eax # u
0x8048367 <main+31>: add 0x8(%ebp),%eax # argc
0x804836a <main+34>: sub 0xfffffffc(%ebp),%eax # u
0x804836d <main+37>: cmp 0x8(%ebp),%eax # argc
0x8048370 <main+40>: jne 0x804837b <main+51>
$ valgrind ./a.out
==8452== Using valgrind-3.1.1, a dynamic binary instrumentation framework.
==8452== Conditional jump or move depends on uninitialised value(s)
==8452== at 0x8048370: main (vgtest.c:5)
Such behavior by valgrind is excusable; it's just too cumbersome
(and slow) to track that must history.
--
|
|
From: Julian S. <js...@ac...> - 2006-04-18 01:24:24
|
Robert > Valgrind does not recognize that the _same_ uninitialized bit > has been XORed twice into bit 10 (the 1<<10 bit), along with a 1. > Therefore valgrind believes that bit 10 still is uninitialized. That's going to be hard to fix - to be honest I don't even know how to go about fixing it right now. Certainly any fix that did appear is likely to slow down xors in general, so .. maybe we'll have to pass on this. J |