Re: [Gc] Re: (Win32) attempt to unregister first GC thread will cause acrash.

Ivan Maidanski ivmai at mail.ru
Thu Dec 17 06:05:33 PST 2009


Hi!
Jean-Claude Beaudoin <jean.claude.beaudoin at gmail.com> wrote:
> Ivan Maidanski wrote:
> > Hi!
> > "Boehm, Hans" <hans.boehm at hp.com> wrote:
> >> Under normal circumstances, this shouldn't be an issue, right?  The structure for the main thread should be statically allocated when the GC is initialized.  And GC_unregister_my_thread() shouldn't be called on the main thread.
> >>
> >> The patch looks fine.  I just wonder whether there is correct client code that really needs it.
> >>
>  >> Hans
>
> The situation that led me to this came up while debugging the shutdown code
> of the Common Lisp environment I am currently porting to mingw32 from linux
> where it seems to work just fine.  During the CL world shutdown each thread
> must have its stack properly unwound with its unwind-protects properly executed.
> In order to conveniently achieve this a dedicated thread is spawned with
> sole mission to see that each and all of the other threads wrap-up their
> business and terminate. Once that is assured, the shutdown thread with
> its very limited and controlled context itself terminates.
>
> (BTW, the shutdown thread code is currently written in Common Lisp).
>
> In this process the 'initial' thread is not the last one to terminate,
> thus the need to somehow "unregister" it just before it terminates.
> If you don't unregister it before its termination then you are very likely to
> get a crash of an other kind on a following GC collect.
>
> I don't know if you consider this correct client code but it sure feels
> legitimate to me.
>
> The 'initial' thread does not have a special status in pthreads or Win32
> (short of what happens on return from main()) and I don't see why it
> should be considered any differently than any other thread.
>
> That the registration of the initial thread through GC_init() is
> implicit rather than explicit does not change much to its reality.
> The registration is very well there and must be undone before
> the thread terminates.
>
> Regards,
>
> Jean-Claude Beaudoin

Q: Does that patch work for you?

---

Hans -
I found pthread's GC_unregister_my_thread could be called many times (for a thread while not detached) and this is not consistent with Win32.
Should I add assertion (me->flags&FINISHED)==0 (after me=...) or alternatively try to provide similar behavior to win32 (and change gc.h docs)?

>
>
> >>
> >>> -----Original Message-----
> >>> From: gc-bounces at napali.hpl.hp.com
> >>> [mailto:gc-bounces at napali.hpl.hp.com] On Behalf Of
> >>> Jean-Claude Beaudoin
> >>> Sent: Wednesday, December 16, 2009 4:30 AM
> >>> To: gc at napali.hpl.hp.com
> >>> Subject: [Gc] (Win32) attempt to unregister first GC thread
> >>> will cause a crash.
> >>>
> >>>
> >>> Hello BDW-GC maintainers,
> >>>
> >>> In file win32_threads.c there is a special case for the
> >>> static allocation of the first GC_thread structure.
> >>>
> >>> If someone calls GC_unregister_my_thread() on that very first
> >>> GC thread there will be a segmentation violation inside
> >>> GC_delete_thread() when it tries to call GC_INTERNAL_FREE().
> >
> > The docs cleanly say it's not allowed:
> >
> > /* Unregister the current thread.  Only an explicity registered thread  */
> > /* (i.e. for which GC_register_my_thread() returns GC_SUCCESS) is       */
> > /* allowed (and required) to call this function.  The thread may no     */
> > /* longer allocate garbage collected memory or manipulate pointers to   */
> > /* the garbage collected heap after making this call.                   */
> > /* Specifically, if it wants to return or otherwise communicate a       */
> > /* pointer to the garbage-collected heap to another thread, it must     */
> > /* do this before calling GC_unregister_my_thread, most probably        */
> > /* by saving it in a global data structure.  Must not be called inside  */
> > /* a GC callback function (except for GC_call_with_stack_base() one).   */
> > GC_API int GC_CALL GC_unregister_my_thread(void);
> >
> > The rule is: if you registered a thread then you, nobody else, are allowed and obliged to unregister it.
> > The primordial thread is registered by the collector itself, so if someone calls C_register_my_thread() in it, the returned value would not be GC_SUCCESS.
> >
> > Of course, we may change the docs and the behavior, but is it worth (as Hans asked above)?
> >
> >>> I attached to this message a patch against 7.2alpha4 that
> >>> seems to fix the problem.
> >>>
> >>> Cheers,
> >>>
> >>> Jean-Claude Beaudoin

Bye.


More information about the Gc mailing list