From 47ba04ab544664fefe22f0e49e2307647bc33af5 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Sat, 22 Jan 2011 02:59:24 +0000 Subject: Avoid crash when M structure free just before thread exit. From-SVN: r169121 --- libgo/runtime/go-go.c | 7 +++++++ libgo/runtime/thread.c | 16 ++++++++++------ 2 files changed, 17 insertions(+), 6 deletions(-) (limited to 'libgo') diff --git a/libgo/runtime/go-go.c b/libgo/runtime/go-go.c index 3146268..8c2de28 100644 --- a/libgo/runtime/go-go.c +++ b/libgo/runtime/go-go.c @@ -94,6 +94,13 @@ remove_current_thread (void) runtime_MCache_ReleaseAll (mcache); + /* As soon as we release this look, a GC could run. Since this + thread is no longer on the list, the GC will not find our M + structure, so it could get freed at any time. That means that + any code from here to thread exit must not assume that the m is + valid. */ + m = NULL; + i = pthread_mutex_unlock (&__go_thread_ids_lock); __go_assert (i == 0); diff --git a/libgo/runtime/thread.c b/libgo/runtime/thread.c index 99a0d68..c4e7f6c 100644 --- a/libgo/runtime/thread.c +++ b/libgo/runtime/thread.c @@ -38,9 +38,11 @@ runtime_lock_full(Lock *l) void runtime_lock(Lock *l) { - if(m->locks < 0) - runtime_throw("lock count"); - m->locks++; + if(m != nil) { + if(m->locks < 0) + runtime_throw("lock count"); + m->locks++; + } if(runtime_xadd(&l->key, 1) > 1) // someone else has it; wait runtime_lock_full(l); @@ -58,9 +60,11 @@ runtime_unlock_full(Lock *l) void runtime_unlock(Lock *l) { - m->locks--; - if(m->locks < 0) - runtime_throw("lock count"); + if(m != nil) { + m->locks--; + if(m->locks < 0) + runtime_throw("lock count"); + } if(runtime_xadd(&l->key, -1) > 0) // someone else is waiting runtime_unlock_full(l); -- cgit v1.1