aboutsummaryrefslogtreecommitdiff
path: root/src/pkg/runtime/panic.c
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2014-04-03 15:39:48 -0400
committerRuss Cox <rsc@golang.org>2014-04-03 15:39:48 -0400
commitb2cbf49343a89cc76a17a0b8361f9e977699aa5d (patch)
tree38d9a5c0a647664c0a1f88380af5a7650ddb0300 /src/pkg/runtime/panic.c
parent9dbb185fb6902d9a1308f709deaa67460ccd6c02 (diff)
downloadgo-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.c16
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);
}