This is the mail archive of the
gdb-prs@sourceware.org
mailing list for the GDB project.
[Bug gdb/15573] Decode fatal signals to show faulting address, access type, etc.
- From: "luto at mit dot edu" <sourceware-bugzilla at sourceware dot org>
- To: gdb-prs at sourceware dot org
- Date: Sat, 15 Jun 2013 04:44:01 +0000
- Subject: [Bug gdb/15573] Decode fatal signals to show faulting address, access type, etc.
- Auto-submitted: auto-generated
- References: <bug-15573-4717 at http dot sourceware dot org/bugzilla/>
http://sourceware.org/bugzilla/show_bug.cgi?id=15573
--- Comment #3 from Andy Lutomirski <luto at mit dot edu> ---
It looks more or less like this. I can provide some kind of license if it'll
be useful.
static void HandleFatalSignal(int sig, siginfo_t *info, void *context)
{
/*
* This is x86-specific and insanely poorly (wrongly?) documented.
* I figured it by reading the kernel source. --luto
*/
struct ucontext *uc = (struct ucontext *)context;
struct sigcontext *sc = (struct sigcontext *)&uc->uc_mcontext;
psiginfo(info, "Caught fatal signal");
std::cerr << "Dying due to fatal signal " << strsignal(sig)
<< " in pid " << getpid() << " / tid "
<< syscall(SYS_gettid) << std::endl;
char causebuf[128];
sprintf(causebuf, "code %d", info->si_code);
const char *cause = causebuf;
if (info->si_code == SI_USER)
cause = "kill/raise";
else if (info->si_code == SI_KERNEL)
cause = "generic error from kernel";
else if (info->si_code == SI_QUEUE)
cause = "sigqueue";
else if (info->si_code == SI_TKILL)
cause = "tkill/tgkill";
if (sig == SIGSEGV || sig == SIGBUS) {
if (sig == SIGSEGV && info->si_code == SEGV_MAPERR)
cause = "not mapped";
else if (sig == SIGSEGV && info->si_code == SEGV_ACCERR)
cause = "access error";
else if (sig == SIGBUS && info->si_code == BUS_ADRALN)
cause = "alignment error";
else if (sig == SIGBUS && info->si_code == BUS_ADRERR)
cause = "bad physical address";
else if (sig == SIGBUS && info->si_code == BUS_OBJERR)
cause = "object error";
/* damnit, glibc
else if (sig == SIGBUS && info->si_code == BUS_MCEERR_AR)
cause = "mce; action required";
else if (sig == SIGBUS && info->si_code == BUS_MCEERR_AO)
cause = "mce; action optional";
*/
void *cr2 = (void *)sc->cr2;
// Decode the CPU error code (see Intel or AMD manual)
const char *hw_reason = (sc->err & 1)
? "protection violation"
: "page not present";
const char *access_type;
if (sc->err & 0x10)
access_type = "executing from";
else if (sc->err & 0x2)
access_type = "writing to";
else
access_type = "reading from";
std::cerr << "The error was \"" << cause << "\" at address "
<< (void *)info->si_addr << ". The CPU reported "
<< hw_reason << ' ' << access_type << ' '
<< cr2 << '.' << std::endl;
} else if (sig == SIGTRAP) {
if (info->si_code == TRAP_BRKPT)
cause = "breakpoint";
else if (info->si_code == TRAP_TRACE)
cause = "trace trap";
/* damnit, glibc
else if (info->si_code == TRAP_BRANCH)
cause = "process taken branch trap"; // whatever that is...
else if (info->si_code == TRAP_HWBKPT)
cause = "hw breakpoint/watchpoint";
*/
std::cerr << "The error was " << cause << std::endl;
} else if (sig == SIGILL) {
if (info->si_code == ILL_ILLOPC)
cause = "illegal opcode";
else if (info->si_code == ILL_ILLOPN)
cause = "illegal operand";
else if (info->si_code == ILL_ILLADR)
cause = "illegal addressing mode";
else if (info->si_code == ILL_ILLTRP)
cause = "illegal trap";
else if (info->si_code == ILL_PRVOPC)
cause = "privileged opcode";
else if (info->si_code == ILL_PRVREG)
cause = "privileged register"; // not on x86...
else if (info->si_code == ILL_COPROC)
cause = "coprocessor error"; // yay '80s
else if (info->si_code == ILL_BADSTK)
cause = "internal stack error";
std::cerr << "The error was " << cause << std::endl;
} else {
// TODO: We could also decode SIGFPE.
std::cerr << "The error was " << cause << std::endl;
}
#define SC(x) " " #x " = " << (void *)(uintptr_t)sc->x
std::cerr << "Signal context:" << SC(rip) << '\n'
<< SC(rax) << SC(rbx) << SC(rcx) << SC(rdx) << '\n'
<< SC(rsi) << SC(rdi) << SC(rbp) << SC(rsp) << '\n'
<< SC(r8) << SC(r9) << SC(r10) << SC(r11) << '\n'
<< SC(r12) << SC(r13) << SC(r14) << SC(r15) << '\n'
<< SC(eflags) << SC(cs) << SC(gs) << SC(fs);
#undef SC
}
--
You are receiving this mail because:
You are on the CC list for the bug.