mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
makes stack traces work for segmented stacks
SVN=125371
This commit is contained in:
parent
8e82a673db
commit
d3204ef19f
6 changed files with 58 additions and 12 deletions
|
|
@ -175,7 +175,16 @@ easy:
|
|||
ADDQ $8, SP
|
||||
RET
|
||||
|
||||
// marker. must be here; used by traceback() to discover calls to _morestack
|
||||
TEXT _endmorestack(SB), 7, $-8
|
||||
RET
|
||||
|
||||
TEXT FLUSH(SB),7,$-8
|
||||
RET
|
||||
|
||||
TEXT getu(SB),7,$-8
|
||||
MOVQ R15, AX
|
||||
RET
|
||||
|
||||
|
||||
GLOBL peruser<>(SB),$64
|
||||
|
|
|
|||
|
|
@ -145,11 +145,11 @@ sighandler(int32 sig, siginfo *info, void *context)
|
|||
_STRUCT_X86_THREAD_STATE64 *ss = get___ss(uc_mcontext);
|
||||
|
||||
prints("\nFaulting address: 0x"); sys·printpointer(info->si_addr);
|
||||
prints("\npc: 0x"); sys·printpointer((void *)ss->__rip);
|
||||
prints("\n\n");
|
||||
prints("\npc: 0x"); sys·printpointer((void *)ss->__rip);
|
||||
prints("\n\n");
|
||||
|
||||
traceback((void *)ss->__rip, (void *)ss->__rsp);
|
||||
print_thread_state(ss);
|
||||
traceback((void *)ss->__rip, (void *)ss->__rsp, (void*)ss->__r15);
|
||||
print_thread_state(ss);
|
||||
|
||||
sys·exit(2);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -152,7 +152,7 @@ sighandler(int32 sig, siginfo* info, void** context)
|
|||
prints("\npc: 0x"); sys·printpointer((void *)sc->rip);
|
||||
prints("\n\n");
|
||||
|
||||
traceback((void *)sc->rip, (void *)sc->rsp);
|
||||
traceback((void *)sc->rip, (void *)sc->rsp, (void *)sc->r15);
|
||||
print_sigcontext(sc);
|
||||
|
||||
sys·breakpoint();
|
||||
|
|
|
|||
|
|
@ -8,22 +8,54 @@ extern int32 debug;
|
|||
|
||||
static int8 spmark[] = "\xa7\xf1\xd9\x2a\x82\xc8\xd8\xfe";
|
||||
|
||||
typedef struct U U;
|
||||
struct U {
|
||||
uint8* stackguard;
|
||||
uint8* stackbase;
|
||||
uint8* istackguard;
|
||||
uint8* istackbase;
|
||||
};
|
||||
|
||||
typedef struct Stktop Stktop;
|
||||
struct Stktop {
|
||||
uint8* oldbase;
|
||||
uint8* oldsp;
|
||||
uint8* magic;
|
||||
uint8* oldguard;
|
||||
};
|
||||
|
||||
extern void _morestack();
|
||||
extern void _endmorestack();
|
||||
|
||||
void
|
||||
traceback(uint8 *pc, uint8 *sp)
|
||||
traceback(uint8 *pc, uint8 *sp, void* r15)
|
||||
{
|
||||
int32 spoff;
|
||||
int8* spp;
|
||||
uint8* callpc;
|
||||
int32 counter;
|
||||
int32 i;
|
||||
int8* name;
|
||||
U u;
|
||||
Stktop *stktop;
|
||||
|
||||
// store local copy of per-process data block that we can write as we unwind
|
||||
mcpy((byte*)&u, (byte*)r15, sizeof(U));
|
||||
|
||||
counter = 0;
|
||||
name = "panic";
|
||||
for(;;){
|
||||
prints("0x");
|
||||
sys·printpointer(pc);
|
||||
prints("?zi\n");
|
||||
callpc = pc;
|
||||
if((uint8*)_morestack < pc && pc < (uint8*)_endmorestack) {
|
||||
// call site in _morestack(); pop to earlier stack block to get true caller
|
||||
stktop = (Stktop*)u.stackbase;
|
||||
u.stackbase = stktop->oldbase;
|
||||
u.stackguard = stktop->oldguard;
|
||||
sp = stktop->oldsp;
|
||||
pc = ((uint8**)sp)[1];
|
||||
sp += 16; // two irrelevant calls on stack - morestack, plus the call morestack made
|
||||
continue;
|
||||
}
|
||||
/* find SP offset by stepping back through instructions to SP offset marker */
|
||||
while(pc > (uint8*)0x1000+sizeof spmark-1) {
|
||||
for(spp = spmark; *spp != '\0' && *pc++ == (uint8)*spp++; )
|
||||
|
|
@ -43,7 +75,11 @@ traceback(uint8 *pc, uint8 *sp)
|
|||
}
|
||||
if((pc = ((uint8**)sp)[-1]) <= (uint8*)0x1000)
|
||||
break;
|
||||
/* print args for this frame */
|
||||
|
||||
/* print this frame */
|
||||
prints("0x");
|
||||
sys·printpointer(callpc);
|
||||
prints("?zi\n");
|
||||
prints("\t");
|
||||
prints(name);
|
||||
prints("(");
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ sys·panicl(int32 lno)
|
|||
sys·printpc(&lno);
|
||||
prints("\n");
|
||||
sp = (uint8*)&lno;
|
||||
traceback(sys·getcallerpc(&lno), sp);
|
||||
traceback(sys·getcallerpc(&lno), sp, getu());
|
||||
sys·breakpoint();
|
||||
sys·exit(2);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -93,13 +93,14 @@ extern int32 debug;
|
|||
* very low level c-called
|
||||
*/
|
||||
void FLUSH(void*);
|
||||
void* getu(void);
|
||||
void throw(int8*);
|
||||
void prints(int8*);
|
||||
void mcpy(byte*, byte*, uint32);
|
||||
void* mal(uint32);
|
||||
uint32 cmpstring(string, string);
|
||||
void initsig(void);
|
||||
void traceback(uint8 *pc, uint8 *sp);
|
||||
void traceback(uint8 *pc, uint8 *sp, void* up);
|
||||
int32 open(byte*, int32);
|
||||
int32 read(int32, void*, int32);
|
||||
void close(int32);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue