1
0
mirror of https://github.com/golang/go synced 2024-11-19 03:14:42 -07:00

better debuggers:

- follow through segmented stacks
	- a couple of fixes to db

R=rsc
DELTA=72  (62 added, 0 deleted, 10 changed)
OCL=15713
CL=15717
This commit is contained in:
Rob Pike 2008-09-23 15:08:39 -07:00
parent 1101d406ec
commit 7c48a39423

View File

@ -30,6 +30,9 @@
#include <libc.h>
#include <bio.h>
#include <mach_amd64.h>
#include <ureg_amd64.h>
typedef struct Ureg Ureg_amd64;
/*
* i386-specific debugger interface
@ -46,8 +49,10 @@ static int i386das(Map*, uvlong, char*, int);
static int i386instlen(Map*, uvlong);
static char STARTSYM[] = "_main";
static char GOSTARTSYM[] = "sys·goexit";
static char PROFSYM[] = "_mainp";
static char FRAMENAME[] = ".frame";
static char RETFROMNEWSTACK[] = "retfromnewstack";
static char *excname[] =
{
[0] "divide error",
@ -119,13 +124,46 @@ i386excep(Map *map, Rgetter rget)
return excname[c];
}
// borrowed from src/runtime/runtime.h
struct Stktop
{
uint8* oldbase;
uint8* oldsp;
uint64 magic;
uint8* oldguard;
};
struct G
{
uvlong stackguard; // must not move
uvlong stackbase; // must not move
uvlong stack0; // first stack segment
// rest not needed
};
static int
i386trace(Map *map, uvlong pc, uvlong sp, uvlong link, Tracer trace)
{
int i;
uvlong osp;
Symbol s, f;
Symbol s, f, s1;
extern Mach mamd64;
int isamd64;
struct Stktop *stktop;
struct G g;
uvlong r15;
uvlong retfromnewstack;
isamd64 = (mach == &mamd64);
retfromnewstack = 0;
if(isamd64) {
get8(map, offsetof(Ureg_amd64, r15), &r15);
get8(map, r15+offsetof(struct G, stackguard), &g.stackguard);
get8(map, r15+offsetof(struct G, stackbase), &g.stackbase);
get8(map, r15+offsetof(struct G, stack0), &g.stack0);
if(lookup(0, RETFROMNEWSTACK, &s))
retfromnewstack = s.value;
}
USED(link);
osp = 0;
i = 0;
@ -134,9 +172,24 @@ i386trace(Map *map, uvlong pc, uvlong sp, uvlong link, Tracer trace)
break;
osp = sp;
if(strcmp(STARTSYM, s.name) == 0 || strcmp(PROFSYM, s.name) == 0)
if(strcmp(STARTSYM, s.name) == 0 ||
strcmp(GOSTARTSYM, s.name) == 0 ||
strcmp(PROFSYM, s.name) == 0)
break;
if(pc == retfromnewstack) {
stktop = (struct Stktop*)g.stackbase;
get8(map, (uvlong)&stktop->oldbase, &g.stackbase);
get8(map, (uvlong)&stktop->oldguard, &g.stackguard);
get8(map, (uvlong)&stktop->oldsp, &sp);
get8(map, sp+8, &pc);
(*trace)(map, pc, sp + 8, &s1);
sp += 16; // two irrelevant calls on stack - morestack, plus the call morestack made
continue;
break;
}
s1 = s;
if(pc != s.value) { /* not at first instruction */
if(findlocal(&s, FRAMENAME, &f) == 0)
break;
@ -148,7 +201,8 @@ i386trace(Map *map, uvlong pc, uvlong sp, uvlong link, Tracer trace)
if(pc == 0)
break;
(*trace)(map, pc, sp, &s);
if (pc != retfromnewstack)
(*trace)(map, pc, sp, &s1);
sp += mach->szaddr;
if(++i > 1000)