aboutsummaryrefslogtreecommitdiff
path: root/src/pkg
diff options
context:
space:
mode:
authorDmitriy Vyukov <dvyukov@google.com>2013-08-08 00:31:52 +0400
committerDmitriy Vyukov <dvyukov@google.com>2013-08-08 00:31:52 +0400
commit326ae8d14e17227086239757ef2f131028997a72 (patch)
tree76eacdaf52c6ed5a6859f2e28c133fc2d4b85797 /src/pkg
parent1590abef0371ffa5b37a760b7cde74e2d5f18d2f (diff)
downloadgo-326ae8d14e17227086239757ef2f131028997a72.tar.xz
runtime: fix traceback in cgo programs
Fixes #6061. R=golang-dev, bradfitz CC=golang-dev https://golang.org/cl/12609043
Diffstat (limited to 'src/pkg')
-rw-r--r--src/pkg/runtime/crash_cgo_test.go27
-rw-r--r--src/pkg/runtime/panic.c2
-rw-r--r--src/pkg/runtime/proc.c10
3 files changed, 36 insertions, 3 deletions
diff --git a/src/pkg/runtime/crash_cgo_test.go b/src/pkg/runtime/crash_cgo_test.go
index d61de4469f..4ff0084c22 100644
--- a/src/pkg/runtime/crash_cgo_test.go
+++ b/src/pkg/runtime/crash_cgo_test.go
@@ -26,6 +26,14 @@ func TestCgoSignalDeadlock(t *testing.T) {
}
}
+func TestCgoTraceback(t *testing.T) {
+ got := executeTest(t, cgoTracebackSource, nil)
+ want := "OK\n"
+ if got != want {
+ t.Fatalf("expected %q, but got %q", want, got)
+ }
+}
+
const cgoSignalDeadlockSource = `
package main
@@ -90,3 +98,22 @@ func main() {
fmt.Printf("OK\n")
}
`
+
+const cgoTracebackSource = `
+package main
+
+/* void foo(void) {} */
+import "C"
+
+import (
+ "fmt"
+ "runtime"
+)
+
+func main() {
+ C.foo()
+ buf := make([]byte, 1)
+ runtime.Stack(buf, true)
+ fmt.Printf("OK\n")
+}
+`
diff --git a/src/pkg/runtime/panic.c b/src/pkg/runtime/panic.c
index 36a3c41ba7..3211415266 100644
--- a/src/pkg/runtime/panic.c
+++ b/src/pkg/runtime/panic.c
@@ -415,6 +415,8 @@ runtime·startpanic(void)
runtime·exit(3);
}
m->dying = 1;
+ if(g != nil)
+ g->writebuf = nil;
runtime·xadd(&runtime·panicking, 1);
runtime·lock(&paniclk);
}
diff --git a/src/pkg/runtime/proc.c b/src/pkg/runtime/proc.c
index 4d74b570b3..6eab7dba1b 100644
--- a/src/pkg/runtime/proc.c
+++ b/src/pkg/runtime/proc.c
@@ -712,11 +712,18 @@ runtime·newextram(void)
gp->sched.sp = gp->stackbase;
gp->sched.lr = 0;
gp->sched.g = gp;
+ gp->syscallpc = gp->sched.pc;
+ gp->syscallsp = gp->sched.sp;
+ gp->syscallstack = gp->stackbase;
+ gp->syscallguard = gp->stackguard;
gp->status = Gsyscall;
mp->curg = gp;
mp->locked = LockInternal;
mp->lockedg = gp;
gp->lockedm = mp;
+ gp->goid = runtime·xadd64(&runtime·sched.goidgen, 1);
+ if(raceenabled)
+ gp->racectx = runtime·racegostart(runtime·newextram);
// put on allg for garbage collector
runtime·lock(&runtime·sched);
if(runtime·lastg == nil)
@@ -725,9 +732,6 @@ runtime·newextram(void)
runtime·lastg->alllink = gp;
runtime·lastg = gp;
runtime·unlock(&runtime·sched);
- gp->goid = runtime·xadd64(&runtime·sched.goidgen, 1);
- if(raceenabled)
- gp->racectx = runtime·racegostart(runtime·newextram);
// Add m to the extra list.
mnext = lockextra(true);