|
From: Alexander P. <gl...@go...> - 2009-12-09 17:13:45
|
Hi everyone, Debugging ThreadSanitizer for Mac OS (http://code.google.com/p/data-race-test) I've came up with a small piece of code that makes Valgrind-based threading tools act in a weird manner. The attached code exploits NSOperationQueue from the Foundation library. To build it, just run: $ g++ nsop.mm -o nsop -framework Foundation If I run ./nsop natively, I get something like: 2009-12-09 19:58:33.021 nsop[64614:10b] *** _NSAutoreleaseNoPool(): Object 0x106580 of class __NSFastEnumerationEnumerator autoreleased with no pool in place - just leaking Stack: (0x92a01f0f 0x9290e442 0x929a41d2 0x929a4597) 2009-12-09 19:58:33.022 nsop[64614:10b] *** _NSAutoreleaseNoPool(): Object 0x10c490 of class NSCFSet autoreleased with no pool in place - just leaking Stack: (0x92a01f0f 0x9290e442 0x92926e63 0x92926b3c 0x929267b8 0x92926493 0x92926242 0x92925e3e 0x929a420f 0x929a4597) 2009-12-09 19:58:33.022 nsop[64614:10b] *** _NSAutoreleaseNoPool(): Object 0x10ce40 of class NSCFSet autoreleased with no pool in place - just leaking Stack: (0x92a01f0f 0x9290e442 0x92926e63 0x92926b3c 0x929267b8 0x92926493 0x92926242 0x92925e3e 0x929a420f 0x929a4597) Printer::Print() BYE Task::Run() But neither DRD nor Helgrind cannot cope with this binary: $ inst/bin/valgrind --tool=drd /Users/glider/src/worker_vex_test/nsop 2>&1 ==68403== drd, a thread error detector ... --68403-- /Users/glider/src/worker_vex_test/nsop: --68403-- dSYM directory is missing; consider using --dsymutil=yes 2009-12-09 20:02:14.368 nsop[68403:50b] *** _NSAutoreleaseNoPool(): Object 0x1cb4d40 of class __NSFastEnumerationEnumerator autoreleased with no pool in place - just leaking Stack: (0x4d1f0f 0x3de442 0x4741d2 0x474597) 2009-12-09 20:02:14.617 nsop[68403:50b] *** _NSAutoreleaseNoPool(): Object 0x1cbcff0 of class NSCFSet autoreleased with no pool in place - just leaking Stack: (0x4d1f0f 0x3de442 0x3f6e63 0x3f6b3c 0x3f67b8 0x3f6493 0x3f6242 0x3f5e3e 0x47420f 0x474597) 2009-12-09 20:02:14.659 nsop[68403:50b] *** _NSAutoreleaseNoPool(): Object 0x1cc12e0 of class NSCFSet autoreleased with no pool in place - just leaking Stack: (0x4d1f0f 0x3de442 0x3f6e63 0x3f6b3c 0x3f67b8 0x3f6493 0x3f6242 0x3f5e3e 0x47420f 0x474597) drd: drd_thread.c:584 (vgDrd_thread_set_vg_running_tid): Assertion 'vg_tid != VG_INVALID_THREADID' failed. ==68403== at 0xF009DCBD: ??? ==68403== by 0xF009DF71: ??? ... sched status: running_tid=0 Thread 1: status = VgTs_WaitSys ==68403== at 0x7DDC62: ioctl (in /usr/lib/libSystem.B.dylib) ==68403== by 0x7EB00A: __smakebuf (in /usr/lib/libSystem.B.dylib) ==68403== by 0x7EAF0C: __swsetup (in /usr/lib/libSystem.B.dylib) ==68403== by 0x7BAF8D: __sfvwrite (in /usr/lib/libSystem.B.dylib) ==68403== by 0x82618F: puts (in /usr/lib/libSystem.B.dylib) ==68403== by 0x1D0E: Printer::Print() (in /Users/glider/src/worker_vex_test/nsop) ==68403== by 0x1BAD: main (in /Users/glider/src/worker_vex_test/nsop) Thread 2: status = VgTs_Init ==68403== at 0x81E2A4: start_wqthread (in /usr/lib/libSystem.B.dylib) Looks like Valgrind tries to execute code in a previously unknown thread without calling the pre_thread_ll_create method for this thread. Does anyone know whether this is a real bug in VEX or just a NSOperationQueue misuse? Thanks, Alexander Potapenko Software Engineer Google Moscow PS. I've filed https://bugs.kde.org/show_bug.cgi?id=216837 some time ago. There is a more practical example of NSOperationQueue use that crashes Helgrind/DRD/TSan as well. |