diff options
| author | Russ Cox <rsc@golang.org> | 2014-04-03 15:39:48 -0400 |
|---|---|---|
| committer | Russ Cox <rsc@golang.org> | 2014-04-03 15:39:48 -0400 |
| commit | b2cbf49343a89cc76a17a0b8361f9e977699aa5d (patch) | |
| tree | 38d9a5c0a647664c0a1f88380af5a7650ddb0300 /src/pkg/runtime/panic.c | |
| parent | 9dbb185fb6902d9a1308f709deaa67460ccd6c02 (diff) | |
| download | go-b2cbf49343a89cc76a17a0b8361f9e977699aa5d.tar.xz | |
runtime: fix fault during arm software floating point
The software floating point runs with m->locks++
to avoid being preempted; recognize this case in panic
and undo it so that m->locks is maintained correctly
when panicking.
Fixes #7553.
LGTM=dvyukov
R=golang-codereviews, dvyukov
CC=golang-codereviews
https://golang.org/cl/84030043
Diffstat (limited to 'src/pkg/runtime/panic.c')
| -rw-r--r-- | src/pkg/runtime/panic.c | 16 |
1 files changed, 15 insertions, 1 deletions
diff --git a/src/pkg/runtime/panic.c b/src/pkg/runtime/panic.c index 0bf3b6a140..3af8cb67aa 100644 --- a/src/pkg/runtime/panic.c +++ b/src/pkg/runtime/panic.c @@ -498,7 +498,7 @@ runtime·canpanic(G *gp) // and not stuck in a system call. if(gp == nil || gp != m->curg) return false; - if(m->locks != 0 || m->mallocing != 0 || m->throwing != 0 || m->gcing != 0 || m->dying != 0) + if(m->locks-m->softfloat != 0 || m->mallocing != 0 || m->throwing != 0 || m->gcing != 0 || m->dying != 0) return false; if(gp->status != Grunning || gp->syscallsp != 0) return false; @@ -526,6 +526,16 @@ runtime·panicstring(int8 *s) { Eface err; + // m->softfloat is set during software floating point, + // which might cause a fault during a memory load. + // It increments m->locks to avoid preemption. + // If we're panicking, the software floating point frames + // will be unwound, so decrement m->locks as they would. + if(m->softfloat) { + m->locks--; + m->softfloat = 0; + } + if(m->mallocing) { runtime·printf("panic: %s\n", s); runtime·throw("panic during malloc"); @@ -534,6 +544,10 @@ runtime·panicstring(int8 *s) runtime·printf("panic: %s\n", s); runtime·throw("panic during gc"); } + if(m->locks) { + runtime·printf("panic: %s\n", s); + runtime·throw("panic holding locks"); + } runtime·newErrorCString(s, &err); runtime·panic(err); } |
