From 95332efaa2682367e87ded0ec1b07e6e95d33122 Mon Sep 17 00:00:00 2001 From: castano Date: Tue, 29 May 2007 09:43:30 +0000 Subject: [PATCH] Fixes to compute the instruction pointer correctly after a signal. Not sure it works properly. --- src/nvcore/Debug.cpp | 78 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 63 insertions(+), 15 deletions(-) diff --git a/src/nvcore/Debug.cpp b/src/nvcore/Debug.cpp index 55d4c8b..2edbd0f 100644 --- a/src/nvcore/Debug.cpp +++ b/src/nvcore/Debug.cpp @@ -121,7 +121,7 @@ namespace return EXCEPTION_CONTINUE_SEARCH; } -#elif !NV_OS_WIN32 && defined(HAVE_SIGNAL_H) // NV_OS_LINUX || NV_OS_OSX +#elif !NV_OS_WIN32 && defined(HAVE_SIGNAL_H) // NV_OS_LINUX || NV_OS_DARWIN #if defined(HAVE_EXECINFO_H) // NV_OS_LINUX @@ -160,17 +160,65 @@ namespace } #endif // defined(HAVE_EXECINFO_H) - + + static void * callerAddress(void * secret) + { +# if NV_OS_DARWIN && NV_CPU_PPC + return NULL; +# elif NV_OS_DARWIN && NV_CPU_X86 + return NULL; +# elif NV_CPU_X86_64 + ucontext_t * uc = (ucontext_t *)secret; + return (void *)uc->uc_mcontext.gregs[REG_RIP]; +# elif NV_CPU_X86 + ucontext_t * uc = (ucontext_t *)secret; + return (void *)uc->uc_mcontext.gregs[REG_EIP]; +# elif NV_CPU_PPC + ucontext_t* uc = (ucontext_t*) secret; + return (void*) uc->uc_mcontext.regs->nip; +#else + return NULL; +#endif + + // From http://www.miriamruiz.es/weblog/?p=14 + + // #elif defined(__hppa__) + // ucontext_t* uc = (ucontext_t*) secret; + // pnt = (void*) uc->uc_mcontext.sc_iaoq[0] & ~0×3UL ; + // #elif defined(__sparc__) + // struct sigcontext* sc = (struct sigcontext*) secret; + // #if __WORDSIZE == 64 + // pnt = (void*) scp->sigc_regs.tpc ; + // #else + // pnt = (void*) scp->si_regs.pc ; + // #endif + + // potentially correct for other archs: + // alpha: ucp->m_context.sc_pc + // arm: ucp->m_context.ctx.arm_pc + // ia64: ucp->m_context.sc_ip & ~0×3UL + // mips: ucp->m_context.sc_pc + // s390: ucp->m_context.sregs->regs.psw.addr + + // #ifndef EIP + // #define EIP 14 + // #endif + + // #if (defined (__x86_64__)) + // #ifndef REG_RIP + // #define REG_RIP REG_INDEX(rip) /* seems to be 16 */ + // #endif + // #endif + } + static void nvSigHandler(int sig, siginfo_t *info, void *secret) - { + { + void * pnt = callerAddress(secret); + // Do something useful with siginfo_t - if (sig == SIGSEGV) { -# if NV_CPU_X86 - ucontext_t * uc = (ucontext_t *)secret; - nvDebug("Got signal %d, faulty address is %p, from %p\n", sig, info->si_addr, (void *)uc->uc_mcontext.gregs[REG_EIP]); -# else - nvDebug("Got signal %d, faulty address is %p\n", sig, info->si_addr); -# endif + 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); } else if(sig == SIGTRAP) { nvDebug("Breakpoint hit.\n"); @@ -184,11 +232,11 @@ namespace void * trace[64]; int size = backtrace(trace, 64); -# if NV_CPU_X86 - // Overwrite sigaction with caller's address. - ucontext_t * uc = (ucontext_t *)secret; - trace[1] = (void *) uc->uc_mcontext.gregs[REG_EIP]; -# endif // NV_CPU_X86 + if (pnt != NULL) { + // Overwrite sigaction with caller's address. + ucontext_t * uc = (ucontext_t *)secret; + trace[1] = (void *) uc->uc_mcontext.gregs[REG_EIP]; + } nvPrintStackTrace(trace, size, 1);