]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: ensure forward progress when unwinding an arm stack frame
authorCarl Shapiro <cshapiro@google.com>
Tue, 26 Mar 2013 18:43:09 +0000 (11:43 -0700)
committerCarl Shapiro <cshapiro@google.com>
Tue, 26 Mar 2013 18:43:09 +0000 (11:43 -0700)
The arm gentraceback mishandled frame linkage values pointing
to the assembly return function.  This function is special as
its frame size is zero and it contains only one instruction.
These conditions would preserve the frame pointer and result
in an off by one error when unwinding the caller.

Fixes #5124

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

misc/cgo/test/callback.go
src/pkg/runtime/traceback_arm.c

index 3feec134b70dcefa2111801a8817767682068b87..b6e2e3c1ce00dae4b673f970fabf49e321ebc089 100644 (file)
@@ -160,9 +160,7 @@ func testCallbackCallers(t *testing.T) {
        nestedCall(func() {
                n = runtime.Callers(2, pc)
        })
-       // The ARM cannot unwind all the way down to runtime.goexit.
-       // See issue 5124.
-       if n != len(name) && runtime.GOARCH != "arm" {
+       if n != len(name) {
                t.Errorf("expected %d frames, got %d", len(name), n)
        }
        for i := 0; i < n; i++ {
@@ -179,10 +177,5 @@ func testCallbackCallers(t *testing.T) {
                if fname != name[i] {
                        t.Errorf("expected function name %s, got %s", name[i], fname)
                }
-               // The ARM cannot unwind frames past runtime.cgocall.
-               // See issue 5124.
-               if runtime.GOARCH == "arm" && i == 4 {
-                       break
-               }
        }
 }
index dd85cc02c4a43c0e095cfdb9be1b1b6192b42c05..9c351db6054dceb261a4362297395f5c58bde92b 100644 (file)
@@ -74,8 +74,9 @@ runtime·gentraceback(byte *pc0, byte *sp, byte *lr0, G *gp, int32 skip, uintptr
                        lr = *(uintptr*)sp;
                if(fp == nil) {
                        fp = sp;
-                       if(pc > f->entry && f->frame >= 0)
-                               fp += f->frame;
+                       if(pc > f->entry && f->frame >= sizeof(uintptr))
+                               fp += f->frame - sizeof(uintptr);
+                       fp += sizeof(uintptr);
                }
 
                if(skip > 0)