[Gc] GC_INIT? Threads?
The Devils Jester
thedevilsjester at gmail.com
Mon Aug 19 23:08:37 PDT 2013
I apologize, I do not mean "crash" in the literal sense. I appreciate the
help finding a solution to my problem.
The commands supplied, causes the program to lock up and consume all of the
CPU.
The code I have is as follows. I am unsure about the stack_base or how it
is used.
In my primary thread:
GC_INIT();
GC_allow_register_threads();
ClassFromMyLib * myclass = new ClassFromMyLib();
In my new thread:
struct GC_stack_base *my_sb;
GC_get_stack_base(my_sb);
GC_register_my_thread(my_sb);
myclass->myfunction();
GC_unregister_my_thread();
Without the special GC_ functions, everything works fine until GC tries to
reclaim memory, with them it locks up.
Am I doing something wrong?
On Tue, Aug 20, 2013 at 12:00 AM, Bruce Hoult <bruce at hoult.org> wrote:
> Once again, it's not crashing, it's a controlled exit because it detected
> something wrong.
>
> Try using these (from gc.h)
>
> call GC_allow_register_threads() from your main program, after GC_INIT()
> call GC_register_my_thread() at the start of the main function for each
> thread you create. (and GC_unregister_my_thread() at the end)
>
> You may also find GC_call_with_stack_base() useful.
>
> /* Explicitly enable GC_register_my_thread() invocation. */
> /* Done implicitly if a GC thread-creation function is called (or */
> /* implicit thread registration is activated). Otherwise, it must */
> /* be called from the main (or any previously registered) thread */
> /* between the collector initialization and the first explicit */
> /* registering of a thread (it should be called as late as possible). */
> GC_API void GC_CALL GC_allow_register_threads(void);
>
> /* Register the current thread, with the indicated stack base, as */
> /* a new thread whose stack(s) should be traced by the GC. If it */
> /* is not implicitly called by the GC, this must be called before a */
> /* thread can allocate garbage collected memory, or assign pointers */
> /* to the garbage collected heap. Once registered, a thread will be */
> /* stopped during garbage collections. */
> /* This call must be previously enabled (see above). */
> /* This should never be called from the main thread, where it is */
> /* always done implicitly. This is normally done implicitly if GC_ */
> /* functions are called to create the thread, e.g. by including gc.h */
> /* (which redefines some system functions) before calling the system */
> /* thread creation function. Nonetheless, thread cleanup routines */
> /* (eg., pthread key destructor) typically require manual thread */
> /* registering (and unregistering) if pointers to GC-allocated */
> /* objects are manipulated inside. */
> /* It is also always done implicitly on some platforms if */
> /* GC_use_threads_discovery() is called at start-up. Except for the */
> /* latter case, the explicit call is normally required for threads */
> /* created by third-party libraries. */
> /* A manually registered thread requires manual unregistering. */
> GC_API int GC_CALL GC_register_my_thread(const struct GC_stack_base *);
>
> /* Unregister the current thread. Only an explicitly registered */
> /* thread (i.e. for which GC_register_my_thread() returns GC_SUCCESS) */
> /* is allowed (and required) to call this function. (As a special */
> /* exception, it is also allowed to once unregister the main thread.) */
> /* 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);
>
>
>
> On Tue, Aug 20, 2013 at 4:48 PM, The Devils Jester <
> thedevilsjester at gmail.com> wrote:
>
>> The only output I get, aside from the stack trace is:
>> Collecting from unknown thread
>> Abort trap: 6
>>
>> My application is organized as follows:
>>
>> MAIN APP (does not use GC)
>> GC_INIT()
>> NEW THREAD
>> CALL LIBRARY FUNCTION (library uses GC)
>>
>> This crashes, while
>>
>> MAIN APP (does not use GC)
>> GC_INIT()
>> CALL LIBRARY FUNCTION (library uses GC)
>>
>> Works perfectly fine.
>>
>> What am I doing wrong? Do I have to initialize the GC in some special
>> fashion?
>>
>>
>> On Mon, Aug 19, 2013 at 11:35 PM, Bruce Hoult <bruce at hoult.org> wrote:
>>
>>> That's not a crash, it's a deliberate abort because some sanity-checking
>>> code found that your world was insane. There are several things that can go
>>> wrong inside GC_push_all_stacks, so it would be helpful to have the
>>> message that GC_abort() printed.
>>>
>>> However, you should always call GC_INIT() from your main program, and as
>>> early as possible.
>>>
>>> On some versions and platforms GC_INIT() installs code that registers
>>> threads in a GC data structure because it's not possible to ask the OS for
>>> all your threads. If you call GC_INIT() from a new thread on those
>>> platforms then that thread will remain unregistered, which is one of the
>>> things that will make GC_push_all_stacks abort later.
>>>
>>>
>>>
>>> On Tue, Aug 20, 2013 at 4:10 PM, The Devils Jester <
>>> thedevilsjester at gmail.com> wrote:
>>>
>>>> I have a library that makes heavy use of of the GC, and it works quite
>>>> well when everything (the app, and the library) is in one thread. I call
>>>> GC_INIT in the app, and all is well.
>>>>
>>>> If, however, the app creates a new thread that calls the library
>>>> function, then it crashes when the GC does its magic (below I have pasted
>>>> some relevant output).
>>>>
>>>> Is there some trick to using GC on a separate thread? Do I call
>>>> GC_INIT from the main thread, or the one that calls the library functions?
>>>>
>>>>
>>>> 0 libsystem_kernel.dylib 0x00007fff8ad14212 __pthread_kill +
>>>> 10
>>>> 1 libsystem_c.dylib 0x00007fff90d01b54 pthread_kill + 90
>>>> 2 libsystem_c.dylib 0x00007fff90d45dce abort + 143
>>>> 3 libgc.1.dylib 0x000000010357676e GC_abort + 97
>>>> 4 libgc.1.dylib 0x000000010357b413
>>>> GC_push_all_stacks + 285
>>>> 5 libgc.1.dylib 0x000000010357396e GC_mark_some + 377
>>>> 6 libgc.1.dylib 0x000000010356d73e GC_stopped_mark +
>>>> 148
>>>> 7 libgc.1.dylib 0x000000010356d645
>>>> GC_try_to_collect_inner + 245
>>>> 8 libgc.1.dylib 0x000000010356e302
>>>> GC_collect_or_expand + 147
>>>> 9 libgc.1.dylib 0x000000010356e51a GC_allocobj + 228
>>>> 10 libgc.1.dylib 0x0000000103572515
>>>> GC_generic_malloc_inner + 249
>>>> 11 libgc.1.dylib 0x00000001035725dd GC_generic_malloc
>>>> + 79
>>>> 12 libgc.1.dylib 0x00000001035728c0 GC_core_malloc +
>>>> 196
>>>>
>>>> --
>>>> This message has been scanned for viruses and
>>>> dangerous content by *MailScanner* <http://www.mailscanner.info/>, and
>>>> is
>>>> believed to be clean.
>>>> _______________________________________________
>>>> Gc mailing list
>>>> Gc at linux.hpl.hp.com
>>>> http://www.hpl.hp.com/hosted/linux/mail-archives/gc/
>>>>
>>>
>>>
>>
>> --
>> This message has been scanned for viruses and
>> dangerous content by *MailScanner* <http://www.mailscanner.info/>, and
>> is
>> believed to be clean.
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://napali.hpl.hp.com/pipermail/gc/attachments/20130820/2d5cd2ec/attachment.htm
More information about the Gc
mailing list