|
From: Konstantin S. <kon...@gm...> - 2009-12-09 23:09:07
|
Thanks a lot, Greg. I think your explanation is enough to fix the problem in Helgrind/DRD/TSan --kcc On Thu, Dec 10, 2009 at 1:36 AM, Greg Parker <gp...@ap...> wrote: > On Dec 9, 2009, at 1:50 PM, Konstantin Serebryany wrote: > > On Wed, Dec 9, 2009 at 11:42 PM, Greg Parker <gp...@ap...> wrote: > >> On Dec 9, 2009, at 9:13 AM, Alexander Potapenko wrote: > >>> > >>> drd: drd_thread.c:584 (vgDrd_thread_set_vg_running_tid): Assertion > >>> vg_tid != VG_INVALID_THREADID' failed. > >>> ==68403== at 0xF009DCBD: ??? > >>> ==68403== by 0xF009DF71: ??? > >> > >> First guess: either Valgrind or those tools aren't correctly handling > the thread-creation mechanisms used by NSOperationQueue. Work queues don't > go through the normal thread entry points. > > > > You mean that NSOperationQueue can create a thread w/o calling > pthread_create()? > > That's right. (There's also pthread_create_suspended_np(), but I don't know > of anyone who uses that.) > > > > Than yes, the tools don't know anything about that. > > Could you point to any piece of documentation and/or source code which > explains how threads are created by NSOperationQueue? > > Valgrind works at the kernel interface. At this level, pthreads mostly > don't exist; the kernel deals in Mach threads, and pthreads are built on top > by Libc. In particular, there is no pthread_create() system call. > > Workqueue threads are another kernel construct used to support > NSOperationQueue and Grand Central Dispatch. Most of the time a workqueue > thread does get a pthread built atop it, just like most Mach threads are > wrapped in a pthread. But the construction process is different, and does > not call Libc's pthread_create(). > > Workqueue threads are created at the kernel's whim. They simply appear in > the process without an explicit user-space request. Each workqueue thread > starts its execution de novo in a function provided by Libc, which builds > the pthread if necessary and executes a work item. > > During process startup, Libc calls the bsdthread_register() syscall, which > among other things tells the kernel the entry point for new workqueue > threads (_pthread_wqthread()). Valgrind traps bsdthread_register() and > substitutes its own function wqthread_hijack_asm(). When the kernel starts a > workqueue thread in a Valgrind process, it starts in wqthread_hijack_asm() > on the real CPU, which in turn bootstraps the thread into Valgrind's > simulator and calls Libc's entry point. > > Valgrind's pthread-tracing system would need to do its work inside > wqthread_hijack(). I think workqueue threads call the ordinary > pthread_exit() on their way out, so you might not need extra handling there. > > I don't know of any documentation for any of this; like the rest of the > kernel-libc interface, it's private and subject to change at any time. > Everything I know I learned from reading xnu and Libc source. > > > -- > Greg Parker gp...@ap... Runtime Wrangler > > > |