fix up linux trap handling - INTB 5 gives SEGV

R=rsc
OCL=15244
CL=15244
This commit is contained in:
Rob Pike 2008-09-12 12:35:06 -07:00
parent c8e18767e8
commit ab9f27b227
4 changed files with 60 additions and 38 deletions

View File

@ -6,9 +6,6 @@
#include "amd64_darwin.h"
#include "signals.h"
extern void _rt0_amd64_darwin();
byte* startsym = (byte*)_rt0_amd64_darwin;
typedef uint64 __uint64_t;
/* From /usr/include/mach/i386/_structs.h */
@ -133,6 +130,37 @@ typedef struct sigaction {
int32 sa_flags; /* see signal options below */
} sigaction;
/*
* For trace traps, disassemble instruction to see if it's INTB of known type.
*/
int32
inlinetrap(int32 sig, byte* pc)
{
extern void etext();
extern void _rt0_amd64_darwin();
if(sig != 5) /* INTB 5 looks like TRAP */
return 0;
pc -= 2; // mac steps across INTB
if(pc < (byte*)_rt0_amd64_darwin || pc+2 >= (byte*)etext)
return 0;
if(pc[0] != 0xcd) /* INTB */
return 0;
switch(pc[1]) {
case 5:
prints("\nTRAP: array out of bounds\n");
break;
case 6:
prints("\nTRAP: leaving function with returning a value\n");
break;
default:
prints("\nTRAP: unknown run-time trap ");
sys·printint(pc[1]);
prints("\n");
}
return 1;
}
void
sighandler(int32 sig, siginfo *info, void *context)
{

View File

@ -6,9 +6,6 @@
#include "amd64_linux.h"
#include "signals.h"
extern void _rt0_amd64_linux();
byte* startsym = (byte*)_rt0_amd64_linux;
/* From /usr/include/asm-x86_64/sigcontext.h */
struct _fpstate {
uint16 cwd;
@ -137,6 +134,35 @@ typedef struct sigaction {
void (*sa_restorer) (void); /* unused here; needed to return from trap? */
} sigaction;
/*
* For trace traps, disassemble instruction to see if it's INTB of known type.
*/
int32
inlinetrap(int32 sig, byte* pc)
{
extern void etext();
extern void _rt0_amd64_linux();
if(sig != 5 && sig != 11) /* 5 is for trap, but INTB 5 looks like SEGV */
return 0;
if(pc < (byte*)_rt0_amd64_linux || pc+2 >= (byte*)etext)
return 0;
if(pc[0] != 0xcd) /* INTB */
return 0;
switch(pc[1]) {
case 5:
prints("\nTRAP: array out of bounds\n");
break;
case 6:
prints("\nTRAP: leaving function with returning a value\n");
break;
default:
prints("\nTRAP: unknown run-time trap ");
sys·printint(pc[1]);
prints("\n");
}
return 1;
}
void
sighandler(int32 sig, siginfo* info, void** context)
@ -167,7 +193,6 @@ sighandler(int32 sig, siginfo* info, void** context)
sys·exit(2);
}
static sigaction a;
void

View File

@ -86,32 +86,3 @@ traceback(uint8 *pc, uint8 *sp, void* r15)
prints(", ...)\n");
}
}
/*
* For trace traps, disassemble instruction to see if it's INTB of known type.
*/
int32
inlinetrap(int32 sig, byte* pc)
{
extern void etext();
if(sig != 5) /* SIGTRAP */
return 0;
if(pc-2 < startsym || pc >= (byte*)etext)
return 0;
if(pc[-2] != 0xcd) /* INTB */
return 0;
switch(pc[-1]) {
case 5:
prints("\nTRAP: array out of bounds\n");
break;
case 6:
prints("\nTRAP: leaving function with returning a value\n");
break;
default:
prints("\nTRAP: unknown run-time trap ");
sys·printint(pc[-1]);
prints("\n");
}
return 1;
}

View File

@ -208,7 +208,6 @@ G* allg;
int32 goidgen;
extern int32 gomaxprocs;
extern int32 panicking;
extern byte *startsym;
/*
* common functions and data
@ -238,7 +237,6 @@ uint32 cmpstring(string, string);
void initsig(void);
void traceback(uint8 *pc, uint8 *sp, G* gp);
void tracebackothers(G*);
int32 inlinetrap(int32 sig, byte* pc);
int32 open(byte*, int32, ...);
int32 read(int32, void*, int32);
int32 write(int32, void*, int32);