]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: fix traceback in cgo programs
authorDmitriy Vyukov <dvyukov@google.com>
Wed, 7 Aug 2013 20:31:52 +0000 (00:31 +0400)
committerDmitriy Vyukov <dvyukov@google.com>
Wed, 7 Aug 2013 20:31:52 +0000 (00:31 +0400)
Fixes #6061.

R=golang-dev, bradfitz
CC=golang-dev
https://golang.org/cl/12609043

src/pkg/runtime/crash_cgo_test.go
src/pkg/runtime/panic.c
src/pkg/runtime/proc.c

index d61de4469facd512097df09b7a506d01d04ab827..4ff0084c2286776900ac543f792a0ad5c93ad363 100644 (file)
@@ -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")
+}
+`
index 36a3c41ba76a11772bde7968196104bbead1f165..3211415266dbbfbf7d877f6a535d28ad2d59cccc 100644 (file)
@@ -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);
 }
index 4d74b570b3a9f18503db25be52060c736fc7f9fe..6eab7dba1bff579f909c7468189fef920a3530ea 100644 (file)
@@ -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);