]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: better trace for fault due to nil pointer call
authorRuss Cox <rsc@golang.org>
Wed, 14 Apr 2010 05:31:47 +0000 (22:31 -0700)
committerRuss Cox <rsc@golang.org>
Wed, 14 Apr 2010 05:31:47 +0000 (22:31 -0700)
R=r
CC=golang-dev
https://golang.org/cl/854048

src/pkg/runtime/darwin/386/signal.c
src/pkg/runtime/darwin/amd64/signal.c
src/pkg/runtime/freebsd/386/signal.c
src/pkg/runtime/freebsd/amd64/signal.c
src/pkg/runtime/linux/386/signal.c
src/pkg/runtime/linux/amd64/signal.c
src/pkg/runtime/linux/arm/signal.c

index 65c217b4e0ea171b7eb4919d909f784b8db5d400..5161796dc3f190286c53ae74c6b08d755866dfc3 100644 (file)
@@ -66,10 +66,18 @@ sighandler(int32 sig, Siginfo *info, void *context)
                gp->sigcode0 = info->si_code;
                gp->sigcode1 = (uintptr)info->si_addr;
 
-               sp = (uintptr*)r->esp;
-               *--sp = r->eip;
+               // Only push sigpanic if r->eip != 0.
+               // If r->eip == 0, probably panicked because of a
+               // call to a nil func.  Not pushing that onto sp will
+               // make the trace look like a call to sigpanic instead.
+               // (Otherwise the trace will end at sigpanic and we
+               // won't get to see who faulted.)
+               if(r->eip != 0) {
+                       sp = (uintptr*)r->esp;
+                       *--sp = r->eip;
+                       r->esp = (uintptr)sp;
+               }
                r->eip = (uintptr)sigpanic;
-               r->esp = (uintptr)sp;
                return;
        }
 
index 9c4f0dc147e5f89e479760b3b0a61413b78f0e07..56f02e56dc5fee95a74937e89c82c4b2bb435ae3 100644 (file)
@@ -74,11 +74,19 @@ sighandler(int32 sig, Siginfo *info, void *context)
                gp->sig = sig;
                gp->sigcode0 = info->si_code;
                gp->sigcode1 = (uintptr)info->si_addr;
-
-               sp = (uintptr*)r->rsp;
-               *--sp = r->rip;
+               
+               // Only push sigpanic if r->rip != 0.
+               // If r->rip == 0, probably panicked because of a
+               // call to a nil func.  Not pushing that onto sp will
+               // make the trace look like a call to sigpanic instead.
+               // (Otherwise the trace will end at sigpanic and we
+               // won't get to see who faulted.)
+               if(r->rip != 0) {
+                       sp = (uintptr*)r->rsp;
+                       *--sp = r->rip;
+                       r->rsp = (uintptr)sp;
+               }
                r->rip = (uintptr)sigpanic;
-               r->rsp = (uintptr)sp;
                return;
        }
 
index ec8ac3a7d4dd44b5dee507a91bfc7c4d3c6bcd4c..be2f4ce6ffaa4da2734f189537db31bbf2abc7e7 100644 (file)
@@ -64,10 +64,18 @@ sighandler(int32 sig, Siginfo* info, void* context)
                gp->sigcode0 = info->si_code;
                gp->sigcode1 = (uintptr)info->si_addr;
 
-               sp = (uintptr*)r->mc_esp;
-               *--sp = r->mc_eip;
+               // Only push sigpanic if r->mc_eip != 0.
+               // If r->mc_eip == 0, probably panicked because of a
+               // call to a nil func.  Not pushing that onto sp will
+               // make the trace look like a call to sigpanic instead.
+               // (Otherwise the trace will end at sigpanic and we
+               // won't get to see who faulted.)
+               if(r->mc_eip != 0) {
+                       sp = (uintptr*)r->mc_esp;
+                       *--sp = r->mc_eip;
+                       r->mc_esp = (uintptr)sp;
+               }
                r->mc_eip = (uintptr)sigpanic;
-               r->mc_esp = (uintptr)sp;
                return;
        }
 
index ba8a5cfdb57735fafa6eb1d823e31316bb3f3dbd..b0ac650a3bf4053b66015b1c03fc9bd1080fba9a 100644 (file)
@@ -72,10 +72,18 @@ sighandler(int32 sig, Siginfo* info, void* context)
                gp->sigcode0 = info->si_code;
                gp->sigcode1 = (uintptr)info->si_addr;
 
-               sp = (uintptr*)r->mc_rsp;
-               *--sp = r->mc_rip;
+               // Only push sigpanic if r->mc_rip != 0.
+               // If r->mc_rip == 0, probably panicked because of a
+               // call to a nil func.  Not pushing that onto sp will
+               // make the trace look like a call to sigpanic instead.
+               // (Otherwise the trace will end at sigpanic and we
+               // won't get to see who faulted.)
+               if(r->mc_rip != 0) {
+                       sp = (uintptr*)r->mc_rsp;
+                       *--sp = r->mc_rip;
+                       r->mc_rsp = (uintptr)sp;
+               }
                r->mc_rip = (uintptr)sigpanic;
-               r->mc_rsp = (uintptr)sp;
                return;
        }
 
index fed052f63ede6fa76b6efefe14eb2bc1a8879a00..8c76ec366affbfc9375c7693cce6cdd946e3c6ce 100644 (file)
@@ -61,10 +61,18 @@ sighandler(int32 sig, Siginfo* info, void* context)
                gp->sigcode0 = info->si_code;
                gp->sigcode1 = ((uintptr*)info)[3];
 
-               sp = (uintptr*)r->esp;
-               *--sp = r->eip;
+               // Only push sigpanic if r->eip != 0.
+               // If r->eip == 0, probably panicked because of a
+               // call to a nil func.  Not pushing that onto sp will
+               // make the trace look like a call to sigpanic instead.
+               // (Otherwise the trace will end at sigpanic and we
+               // won't get to see who faulted.)
+               if(r->eip != 0) {
+                       sp = (uintptr*)r->esp;
+                       *--sp = r->eip;
+                       r->esp = (uintptr)sp;
+               }
                r->eip = (uintptr)sigpanic;
-               r->esp = (uintptr)sp;
                return;
        }
 
index 57cdea1322a91a1df1fe6ec3589a909225ff4a16..fbe6599f6c9a3fe7bfe07084d4d6c0df0a1d82cd 100644 (file)
@@ -71,10 +71,18 @@ sighandler(int32 sig, Siginfo* info, void* context)
                gp->sigcode0 = info->si_code;
                gp->sigcode1 = ((uintptr*)info)[2];
 
-               sp = (uintptr*)r->rsp;
-               *--sp = r->rip;
+               // Only push sigpanic if r->rip != 0.
+               // If r->rip == 0, probably panicked because of a
+               // call to a nil func.  Not pushing that onto sp will
+               // make the trace look like a call to sigpanic instead.
+               // (Otherwise the trace will end at sigpanic and we
+               // won't get to see who faulted.)
+               if(r->rip != 0) {
+                       sp = (uintptr*)r->rsp;
+                       *--sp = r->rip;
+                       r->rsp = (uintptr)sp;
+               }
                r->rip = (uintptr)sigpanic;
-               r->rsp = (uintptr)sp;
                return;
        }
 
index 6cc4ac9bea48e5961e9d79d8185a0759a04191e4..4d315cc808c154e793918052d8e61690043ab794 100644 (file)
@@ -70,7 +70,11 @@ sighandler(int32 sig, Siginfo *info, void *context)
 
                // If this is a leaf function, we do smash LR,
                // but we're not going back there anyway.
-               r->arm_lr = r->arm_pc;
+               // Don't bother smashing if r->arm_pc is 0,
+               // which is probably a call to a nil func: the
+               // old link register is more useful in the stack trace.
+               if(r->arm_pc != 0)
+                       r->arm_lr = r->arm_pc;
                r->arm_pc = (uintptr)sigpanic;
                return;
        }