|
|
|
@ -161,60 +161,60 @@ namespace
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endif // defined(HAVE_EXECINFO_H)
|
|
|
|
|
|
|
|
|
|
static void * callerAddress(void * secret)
|
|
|
|
|
{
|
|
|
|
|
# if NV_OS_DARWIN && NV_CPU_PPC
|
|
|
|
|
ucontext_t * ucp = (ucontext_t *)secret;
|
|
|
|
|
return (void *) ucp->uc_mcontext->ss.srr0;
|
|
|
|
|
# elif NV_OS_DARWIN && NV_CPU_X86
|
|
|
|
|
ucontext_t * ucp = (ucontext_t *)secret;
|
|
|
|
|
return (void *) ucp->uc_mcontext->ss.eip;
|
|
|
|
|
# elif NV_CPU_X86_64
|
|
|
|
|
// #define REG_RIP REG_INDEX(rip) // seems to be 16
|
|
|
|
|
ucontext_t * ucp = (ucontext_t *)secret;
|
|
|
|
|
return (void *)ucp->uc_mcontext.gregs[REG_RIP];
|
|
|
|
|
# elif NV_CPU_X86
|
|
|
|
|
ucontext_t * ucp = (ucontext_t *)secret;
|
|
|
|
|
return (void *)ucp->uc_mcontext.gregs[REG_EIP]; // 14
|
|
|
|
|
# elif NV_CPU_PPC
|
|
|
|
|
ucontext_t * ucp = (ucontext_t *)secret;
|
|
|
|
|
return (void *) ucp->uc_mcontext.regs->nip;
|
|
|
|
|
# else
|
|
|
|
|
return NULL;
|
|
|
|
|
# endif
|
|
|
|
|
|
|
|
|
|
// How to obtain the instruction pointers in different platforms, from mlton's source code.
|
|
|
|
|
// http://mlton.org/
|
|
|
|
|
// OpenBSD && NetBSD
|
|
|
|
|
// ucp->sc_eip
|
|
|
|
|
// FreeBSD:
|
|
|
|
|
// ucp->uc_mcontext.mc_eip
|
|
|
|
|
// HPUX:
|
|
|
|
|
// ucp->uc_link
|
|
|
|
|
// Solaris:
|
|
|
|
|
// ucp->uc_mcontext.gregs[REG_PC]
|
|
|
|
|
// Linux hppa:
|
|
|
|
|
// uc->uc_mcontext.sc_iaoq[0] & ~0×3UL
|
|
|
|
|
// Linux sparc:
|
|
|
|
|
// ((struct sigcontext*) secret)->sigc_regs.tpc
|
|
|
|
|
// Linux sparc64:
|
|
|
|
|
// ((struct sigcontext*) secret)->si_regs.pc
|
|
|
|
|
|
|
|
|
|
// potentially correct for other archs:
|
|
|
|
|
// Linux alpha: ucp->m_context.sc_pc
|
|
|
|
|
// Linux arm: ucp->m_context.ctx.arm_pc
|
|
|
|
|
// Linux ia64: ucp->m_context.sc_ip & ~0×3UL
|
|
|
|
|
// Linux mips: ucp->m_context.sc_pc
|
|
|
|
|
// Linux s390: ucp->m_context.sregs->regs.psw.addr
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void * callerAddress(void * secret)
|
|
|
|
|
{
|
|
|
|
|
# if NV_OS_DARWIN && NV_CPU_PPC
|
|
|
|
|
ucontext_t * ucp = (ucontext_t *)secret;
|
|
|
|
|
return (void *) ucp->uc_mcontext->ss.srr0;
|
|
|
|
|
# elif NV_OS_DARWIN && NV_CPU_X86
|
|
|
|
|
ucontext_t * ucp = (ucontext_t *)secret;
|
|
|
|
|
return (void *) ucp->uc_mcontext->ss.eip;
|
|
|
|
|
# elif NV_CPU_X86_64
|
|
|
|
|
// #define REG_RIP REG_INDEX(rip) // seems to be 16
|
|
|
|
|
ucontext_t * ucp = (ucontext_t *)secret;
|
|
|
|
|
return (void *)ucp->uc_mcontext.gregs[REG_RIP];
|
|
|
|
|
# elif NV_CPU_X86
|
|
|
|
|
ucontext_t * ucp = (ucontext_t *)secret;
|
|
|
|
|
return (void *)ucp->uc_mcontext.gregs[14/*REG_EIP*/];
|
|
|
|
|
# elif NV_CPU_PPC
|
|
|
|
|
ucontext_t * ucp = (ucontext_t *)secret;
|
|
|
|
|
return (void *) ucp->uc_mcontext.regs->nip;
|
|
|
|
|
# else
|
|
|
|
|
return NULL;
|
|
|
|
|
# endif
|
|
|
|
|
|
|
|
|
|
// How to obtain the instruction pointers in different platforms, from mlton's source code.
|
|
|
|
|
// http://mlton.org/
|
|
|
|
|
// OpenBSD && NetBSD
|
|
|
|
|
// ucp->sc_eip
|
|
|
|
|
// FreeBSD:
|
|
|
|
|
// ucp->uc_mcontext.mc_eip
|
|
|
|
|
// HPUX:
|
|
|
|
|
// ucp->uc_link
|
|
|
|
|
// Solaris:
|
|
|
|
|
// ucp->uc_mcontext.gregs[REG_PC]
|
|
|
|
|
// Linux hppa:
|
|
|
|
|
// uc->uc_mcontext.sc_iaoq[0] & ~0×3UL
|
|
|
|
|
// Linux sparc:
|
|
|
|
|
// ((struct sigcontext*) secret)->sigc_regs.tpc
|
|
|
|
|
// Linux sparc64:
|
|
|
|
|
// ((struct sigcontext*) secret)->si_regs.pc
|
|
|
|
|
|
|
|
|
|
// potentially correct for other archs:
|
|
|
|
|
// Linux alpha: ucp->m_context.sc_pc
|
|
|
|
|
// Linux arm: ucp->m_context.ctx.arm_pc
|
|
|
|
|
// Linux ia64: ucp->m_context.sc_ip & ~0×3UL
|
|
|
|
|
// Linux mips: ucp->m_context.sc_pc
|
|
|
|
|
// Linux s390: ucp->m_context.sregs->regs.psw.addr
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void nvSigHandler(int sig, siginfo_t *info, void *secret)
|
|
|
|
|
{
|
|
|
|
|
void * pnt = callerAddress(secret);
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
void * pnt = callerAddress(secret);
|
|
|
|
|
|
|
|
|
|
// Do something useful with siginfo_t
|
|
|
|
|
if (sig == SIGSEGV) {
|
|
|
|
|
if (sig == SIGSEGV) {
|
|
|
|
|
if (pnt != NULL) nvDebug("Got signal %d, faulty address is %p, from %p\n", sig, info->si_addr, pnt);
|
|
|
|
|
else nvDebug("Got signal %d, faulty address is %p\n", sig, info->si_addr);
|
|
|
|
|
}
|
|
|
|
@ -231,9 +231,9 @@ namespace
|
|
|
|
|
int size = backtrace(trace, 64);
|
|
|
|
|
|
|
|
|
|
if (pnt != NULL) {
|
|
|
|
|
// Overwrite sigaction with caller's address.
|
|
|
|
|
// Overwrite sigaction with caller's address.
|
|
|
|
|
ucontext_t * uc = (ucontext_t *)secret;
|
|
|
|
|
trace[1] = (void *) uc->uc_mcontext.gregs[REG_EIP];
|
|
|
|
|
trace[1] = pnt;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nvPrintStackTrace(trace, size, 1);
|
|
|
|
@ -469,7 +469,7 @@ void debug::enableSigHandler()
|
|
|
|
|
struct sigaction sa;
|
|
|
|
|
sa.sa_sigaction = nvSigHandler;
|
|
|
|
|
sigemptyset (&sa.sa_mask);
|
|
|
|
|
sa.sa_flags = SA_ONSTACK | SA_RESTART | SA_SIGINFO;
|
|
|
|
|
sa.sa_flags = SA_ONSTACK | SA_RESTART | SA_SIGINFO;
|
|
|
|
|
|
|
|
|
|
sigaction(SIGSEGV, &sa, &s_old_sigsegv);
|
|
|
|
|
sigaction(SIGTRAP, &sa, &s_old_sigtrap);
|
|
|
|
|