summaryrefslogtreecommitdiff
path: root/libguile/threads.c
diff options
context:
space:
mode:
authorAndy Wingo <wingo@pobox.com>2014-02-21 14:42:24 +0100
committerAndy Wingo <wingo@pobox.com>2014-02-21 14:42:24 +0100
commitc65ea594e92ebf6fb30ece92b063501c8abedf72 (patch)
tree4eb82ca2cd616c97d2ad4b18bf6dc627b47f4aff /libguile/threads.c
parentc53d0f01ddebea16f816349c9813fe9ffdd38a1d (diff)
downloadguile-c65ea594e92ebf6fb30ece92b063501c8abedf72.tar.gz
Fix segfault in thread_mark
* libguile/threads.c (thread_mark): There is a window in which the thread has a handle but doesn't yet have the set of pointerless freelists, so don't unconditionally dereference t->pointerless_freelists.
Diffstat (limited to 'libguile/threads.c')
-rw-r--r--libguile/threads.c31
1 files changed, 16 insertions, 15 deletions
diff --git a/libguile/threads.c b/libguile/threads.c
index 7902a9a0d..dd04f6ff9 100644
--- a/libguile/threads.c
+++ b/libguile/threads.c
@@ -100,21 +100,22 @@ thread_mark (GC_word *addr, struct GC_ms_entry *mark_stack_ptr,
but GC doesn't know to trace them (as they are pointerless), so we
need to do that here. See the comments at the top of libgc's
gc_inline.h. */
- {
- size_t n;
- for (n = 0; n < SCM_INLINE_GC_FREELIST_COUNT; n++)
- {
- void *chain = t->pointerless_freelists[n];
- if (chain)
- {
- /* The first link is already marked by the freelist vector,
- so we just have to mark the tail. */
- while ((chain = *(void **)chain))
- mark_stack_ptr = GC_mark_and_push (chain, mark_stack_ptr,
- mark_stack_limit, NULL);
- }
- }
- }
+ if (t->pointerless_freelists)
+ {
+ size_t n;
+ for (n = 0; n < SCM_INLINE_GC_FREELIST_COUNT; n++)
+ {
+ void *chain = t->pointerless_freelists[n];
+ if (chain)
+ {
+ /* The first link is already marked by the freelist vector,
+ so we just have to mark the tail. */
+ while ((chain = *(void **)chain))
+ mark_stack_ptr = GC_mark_and_push (chain, mark_stack_ptr,
+ mark_stack_limit, NULL);
+ }
+ }
+ }
if (t->vp)
mark_stack_ptr = scm_i_vm_mark_stack (t->vp, mark_stack_ptr,