Bug 72 – valgrind: use of unitialized values in the gcx module

Status
RESOLVED
Resolution
WONTFIX
Severity
normal
Priority
P2
Component
dmd
Product
D
Version
D1 (retired)
Platform
x86
OS
Linux
Creation time
2006-03-24T15:01:00Z
Last change time
2015-03-24T14:23:39Z
Assigned to
nobody
Creator
thomas-dloop

Comments

Comment #0 by thomas-dloop — 2006-03-24T15:01:06Z
Context: DStress' next torture step will include running new compiler versions, generated programs and old compiler version with changed/new test cases under valgrind. The aim is to locate usage of uninitialized values and potential GC issues. See also: [email protected]: Tiago Gasiba's "memory leakage in D" [email protected]: Tiago Gasiba's "Garbage Collector Bug?" Potentially related: [email protected]: Johan Gr
Comment #1 by thomas-dloop — 2006-03-25T03:10:17Z
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Walter Bright schrieb am 2006-03-25: > ><[email protected]> wrote in message > news:[email protected]/bugzilla/... >> Use of uninitialised value of size 4 >> at 0x8067370: _D6gcbits6GCBits3setFkZv (in /tmp/dstress/log) >> by 0x8066A24: _D3gcx3Gcx4markFPvPvZv (in /tmp/dstress/log) >> by 0x8066BB7: _D3gcx3Gcx11fullcollectFPvZk (in /tmp/dstress/log) >> by 0x8066A79: _D3gcx3Gcx16fullcollectshellFZk (in /tmp/dstress/log) >> by 0x8065BAF: _D3gcx2GC12mallocNoSyncFkZPv (in /tmp/dstress/log) >> by 0x8065AF6: _D3gcx2GC6mallocFkZPv (in /tmp/dstress/log) >> by 0x806000D: _d_arrayappendc (in /tmp/dstress/log) > > I don't know what to make of this. Here's the code in question: > > void set(uint i) > in > { > assert(i < nbits); > } > body > { > //(cast(bit *)(data + 1))[i] = 1; > data[1 + (i >> BITS_SHIFT)] |= (1 << (i & BITS_MASK)); > } > > Where's the use of an uninitialized value? Seems to be a side effect of the "-release" flag. compiling phobos with no flags: => no uninitialized value messages compiling phobos with "-inline": => no uninitialized value messages compiling phobos with "-O": => no unitialized value messages compiling phobos with "-release": => "_D6gcbits6GCBits3setFkZv" message twice compiling phobos with "-inline -O": => no unitialized value messages compiling phobos with "-inline -release": => "_D6gcbits6GCBits3setFkZv" message twice compiling phobos with "-O -release": => "_D6gcbits6GCBits3setFkZv" message twice compiling phobos with "-inline -O -release": => "_D6gcbits6GCBits3setFkZv" message twice Thomas -----BEGIN PGP SIGNATURE----- iD8DBQFEJRYy3w+/yD4P9tIRAlbtAJ4vez0F6J9sq157uToFxNhX0muxigCgwkD5 QTFqxrhpoQrKAtUd10DmLZ4= =+Idk -----END PGP SIGNATURE-----
Comment #2 by braddr — 2006-03-25T03:40:14Z
Which file(s) in phobos triggers this? I'll create a minimalized test case.
Comment #3 by thomas-dloop — 2006-03-31T08:40:27Z
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Brad Roberts schrieb am 2006-03-25: > Which file(s) in phobos triggers this? I'll create a minimalized test > case. The code below triggers the _D6gcbits6GCBits3setFkZv issue. Phobos compiled without "-release": 2 x Conditional jump or move depends on uninitialised value 2 x Use of uninitialised value of size 4 Phobos compiled with "-release": 2 x Use of uninitialised value of size 4 > int main(){ > char[] dummy; > dummy = "abc".dup; > for(int a=0; a < 120; a++){ > char[] tmp = new char[a % 80]; > for(int b=0; b < a % 10; b++){ > dummy = dummy[0 .. $ % 33] ~ tmp[0 .. $ % 11] ~ dummy[ $ % 33 .. $]; > } > } > return dummy.length / 2000002; > } Setting: DMD-0.150 / Linux / Valgrind-3.1.1 Thomas -----BEGIN PGP SIGNATURE----- iD8DBQFELUuJ3w+/yD4P9tIRAgiZAJ4+F+4Tso6NHhIdemX2s/05b/X7WwCeNVVD OtbaOUNFuyavZggkxBGBbIw= =bR0O -----END PGP SIGNATURE-----
Comment #4 by jason.james.house — 2007-06-11T09:06:19Z
This bug I submitted to gdc may be of interest: https://sourceforge.net/tracker/?func=detail&atid=791252&aid=1734477&group_id=154306 Just calling the garbage collector is enough to generate valgrind issues. Does this issues show up with dmd and gdc both? The problems I've run into have only shown up when using gdc. I haven't, however, tested this issue with dmd. Here's a small piece of the post: $ cat ./valgrindTest.d module valgrindTest; import std.gc; int main (char[][] args){ std.gc.fullCollect(); return 0; }
Comment #5 by bugzilla — 2010-11-07T14:38:03Z
I've never been able to find anything actually wrong with the gc code in question here.
Comment #6 by braddr — 2010-11-07T14:49:08Z
I looked at this one a long time ago. I think it should be closed as won't fix. The problem, as I remember it, is that the gc walks the stack. The stack isn't fully dense, so there's blocks in it that have never had a value assigned. So, when the gc walks those blocks it complains that their values are indeterminate. Two ways to fix it, that I can see: 1) always initialize empty stack slots -- cost performance 2) teach the gc to be precise about it's stack scanning -- complex
Comment #7 by bugzilla — 2010-11-07T16:31:00Z
Makes sense. Will mark as won't fix.
Comment #8 by dlang-bugzilla — 2015-03-24T14:23:39Z
(In reply to Brad Roberts from comment #6) > Two ways to fix it, that I can see: There is a third way. We can use the Valgrind client API to tell Valgrind to pretend that the entire stack is accessible and has well-defined data, using VALGRIND_MAKE_MEM_DEFINED. By itself, this will hide bugs in user code that accesses uninitialized stack values. However, that can also be avoided by using VALGRIND_GET_VBITS and VALGRIND_SET_VBITS to back up and restore the validity state of the stack before and after a GC scan. > 1) always initialize empty stack slots -- cost performance A small performance loss when running under Valgrind is rarely an issue. I think the main difficulty with this approach is that it might not be possible to implement, because we have no control over the stack frames of C functions.