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
|
ADDQ $8, SP
|
||||||
RET
|
RET
|
||||||
|
|
||||||
|
// marker. must be here; used by traceback() to discover calls to _morestack
|
||||||
|
TEXT _endmorestack(SB), 7, $-8
|
||||||
|
RET
|
||||||
|
|
||||||
TEXT FLUSH(SB),7,$-8
|
TEXT FLUSH(SB),7,$-8
|
||||||
RET
|
RET
|
||||||
|
|
||||||
|
TEXT getu(SB),7,$-8
|
||||||
|
MOVQ R15, AX
|
||||||
|
RET
|
||||||
|
|
||||||
|
|
||||||
GLOBL peruser<>(SB),$64
|
GLOBL peruser<>(SB),$64
|
||||||
|
|
|
||||||
|
|
@ -148,7 +148,7 @@ sighandler(int32 sig, siginfo *info, void *context)
|
||||||
prints("\npc: 0x"); sys·printpointer((void *)ss->__rip);
|
prints("\npc: 0x"); sys·printpointer((void *)ss->__rip);
|
||||||
prints("\n\n");
|
prints("\n\n");
|
||||||
|
|
||||||
traceback((void *)ss->__rip, (void *)ss->__rsp);
|
traceback((void *)ss->__rip, (void *)ss->__rsp, (void*)ss->__r15);
|
||||||
print_thread_state(ss);
|
print_thread_state(ss);
|
||||||
|
|
||||||
sys·exit(2);
|
sys·exit(2);
|
||||||
|
|
|
||||||
|
|
@ -152,7 +152,7 @@ sighandler(int32 sig, siginfo* info, void** context)
|
||||||
prints("\npc: 0x"); sys·printpointer((void *)sc->rip);
|
prints("\npc: 0x"); sys·printpointer((void *)sc->rip);
|
||||||
prints("\n\n");
|
prints("\n\n");
|
||||||
|
|
||||||
traceback((void *)sc->rip, (void *)sc->rsp);
|
traceback((void *)sc->rip, (void *)sc->rsp, (void *)sc->r15);
|
||||||
print_sigcontext(sc);
|
print_sigcontext(sc);
|
||||||
|
|
||||||
sys·breakpoint();
|
sys·breakpoint();
|
||||||
|
|
|
||||||
|
|
@ -8,22 +8,54 @@ extern int32 debug;
|
||||||
|
|
||||||
static int8 spmark[] = "\xa7\xf1\xd9\x2a\x82\xc8\xd8\xfe";
|
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
|
void
|
||||||
traceback(uint8 *pc, uint8 *sp)
|
traceback(uint8 *pc, uint8 *sp, void* r15)
|
||||||
{
|
{
|
||||||
int32 spoff;
|
int32 spoff;
|
||||||
int8* spp;
|
int8* spp;
|
||||||
|
uint8* callpc;
|
||||||
int32 counter;
|
int32 counter;
|
||||||
int32 i;
|
int32 i;
|
||||||
int8* name;
|
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;
|
counter = 0;
|
||||||
name = "panic";
|
name = "panic";
|
||||||
for(;;){
|
for(;;){
|
||||||
prints("0x");
|
callpc = pc;
|
||||||
sys·printpointer(pc);
|
if((uint8*)_morestack < pc && pc < (uint8*)_endmorestack) {
|
||||||
prints("?zi\n");
|
// 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 */
|
/* find SP offset by stepping back through instructions to SP offset marker */
|
||||||
while(pc > (uint8*)0x1000+sizeof spmark-1) {
|
while(pc > (uint8*)0x1000+sizeof spmark-1) {
|
||||||
for(spp = spmark; *spp != '\0' && *pc++ == (uint8)*spp++; )
|
for(spp = spmark; *spp != '\0' && *pc++ == (uint8)*spp++; )
|
||||||
|
|
@ -43,7 +75,11 @@ traceback(uint8 *pc, uint8 *sp)
|
||||||
}
|
}
|
||||||
if((pc = ((uint8**)sp)[-1]) <= (uint8*)0x1000)
|
if((pc = ((uint8**)sp)[-1]) <= (uint8*)0x1000)
|
||||||
break;
|
break;
|
||||||
/* print args for this frame */
|
|
||||||
|
/* print this frame */
|
||||||
|
prints("0x");
|
||||||
|
sys·printpointer(callpc);
|
||||||
|
prints("?zi\n");
|
||||||
prints("\t");
|
prints("\t");
|
||||||
prints(name);
|
prints(name);
|
||||||
prints("(");
|
prints("(");
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ sys·panicl(int32 lno)
|
||||||
sys·printpc(&lno);
|
sys·printpc(&lno);
|
||||||
prints("\n");
|
prints("\n");
|
||||||
sp = (uint8*)&lno;
|
sp = (uint8*)&lno;
|
||||||
traceback(sys·getcallerpc(&lno), sp);
|
traceback(sys·getcallerpc(&lno), sp, getu());
|
||||||
sys·breakpoint();
|
sys·breakpoint();
|
||||||
sys·exit(2);
|
sys·exit(2);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -93,13 +93,14 @@ extern int32 debug;
|
||||||
* very low level c-called
|
* very low level c-called
|
||||||
*/
|
*/
|
||||||
void FLUSH(void*);
|
void FLUSH(void*);
|
||||||
|
void* getu(void);
|
||||||
void throw(int8*);
|
void throw(int8*);
|
||||||
void prints(int8*);
|
void prints(int8*);
|
||||||
void mcpy(byte*, byte*, uint32);
|
void mcpy(byte*, byte*, uint32);
|
||||||
void* mal(uint32);
|
void* mal(uint32);
|
||||||
uint32 cmpstring(string, string);
|
uint32 cmpstring(string, string);
|
||||||
void initsig(void);
|
void initsig(void);
|
||||||
void traceback(uint8 *pc, uint8 *sp);
|
void traceback(uint8 *pc, uint8 *sp, void* up);
|
||||||
int32 open(byte*, int32);
|
int32 open(byte*, int32);
|
||||||
int32 read(int32, void*, int32);
|
int32 read(int32, void*, int32);
|
||||||
void close(int32);
|
void close(int32);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue