aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/runtime.c
diff options
context:
space:
mode:
authorRob Pike <r@golang.org>2008-06-18 23:17:39 -0700
committerRob Pike <r@golang.org>2008-06-18 23:17:39 -0700
commitd6f25597bb19b49be3db172f371328ffd174ebf4 (patch)
tree3555bd92ecc71a2362c8f8ca04071f316531c028 /src/runtime/runtime.c
parentddba96aed81ab702b9be4cf0efd4d98ca6f2fe4d (diff)
downloadgo-d6f25597bb19b49be3db172f371328ffd174ebf4.tar.xz
print rudimentary stack traceback after panic
SVN=123524
Diffstat (limited to 'src/runtime/runtime.c')
-rw-r--r--src/runtime/runtime.c50
1 files changed, 50 insertions, 0 deletions
diff --git a/src/runtime/runtime.c b/src/runtime/runtime.c
index ee6f75f09c..73ae1972e2 100644
--- a/src/runtime/runtime.c
+++ b/src/runtime/runtime.c
@@ -102,11 +102,61 @@ sys_printpc(void *p)
void
sys_panicl(int32 lno)
{
+ uint8 *pc;
+ uint8 *sp;
+ uint8 *retpc;
+ int32 spoff;
+ static int8 spmark[] = "\xa7\xf1\xd9\x2a\x82\xc8\xd8\xfe";
+ int8* spp;
+ int32 counter;
+ int32 i;
+
prints("\npanic on line ");
sys_printint(lno);
prints(" ");
sys_printpc(&lno);
prints("\n");
+ sp = (uint8*)&lno;
+ pc = (uint8*)sys_panicl;
+ counter = 0;
+ while((pc = ((uint8**)sp)[-1]) > (uint8*)0x1000) {
+ for(i = 0; i < 3; i++){
+ prints("\tint32[");
+ sys_printint(i);
+ prints("]=");
+ sys_printint(((uint32*)sp)[i]);
+ prints("\tint64*[");
+ sys_printint(i);
+ prints("]=");
+ sys_printpointer(((void**)sp)[i]);
+ prints("\n");
+ }
+ prints("0x");
+ sys_printpointer(pc);
+ prints(" ");
+ /* next word down on stack is PC */
+ retpc = pc;
+ /* find SP offset by stepping back through instructions to SP offset marker */
+ while(pc > (uint8*)0x1000+11) {
+ for(spp = spmark; *spp != '\0' && *pc++ == (uint8)*spp++; )
+ ;
+ if(*spp == '\0'){
+ spoff = *pc++;
+ spoff += *pc++ << 8;
+ spoff += *pc++ << 16;
+ prints((int8*)pc);
+ prints("+");
+ sys_printint(pc-retpc);
+ prints("?zi\n");
+ sp += spoff + 8;
+ break;
+ }
+ }
+ if(counter++ > 100){
+ prints("stack trace terminated\n");
+ break;
+ }
+ }
*(int32*)0 = 0;
}