From 60f36b8d0274ce94ae0e2511df625118ce8f9076 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 14 May 2025 19:26:22 -0700 Subject: [PATCH] QTest::CrashHandler: extract the address of the crashing instruction From the user and machine context provided in the signal handler. Linux w/ GDB prints: 0x563bb2ab7346 <_ZN11tst_Crashes5crashEv+28>: movl $0x1,(%rax) FreeBSD w/ LLDB prints: (lldb) x/i 0x0000319a0ae86996 0x319a0ae86996: c7 40 04 01 00 00 00 other movl $0x1, 0x4(%rax) macOS w/ LLDB prints (after disabling the check for SIP): (lldb) x/i 0x00000001054086c8 0x1054086c8: movl $0x1, 0x4(%rax) Done-With: Samuel Gaist Done-With: Ivan Solovev Change-Id: Iac02025b1922b6b4d927fffd3efe210ef51fc759 Reviewed-by: Ahmad Samir Reviewed-by: Edward Welbourne Reviewed-by: Samuel Gaist --- src/testlib/qtestcrashhandler_unix.cpp | 41 +++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/src/testlib/qtestcrashhandler_unix.cpp b/src/testlib/qtestcrashhandler_unix.cpp index ca10efa8e2f..d66a5423797 100644 --- a/src/testlib/qtestcrashhandler_unix.cpp +++ b/src/testlib/qtestcrashhandler_unix.cpp @@ -35,6 +35,13 @@ # if !defined(Q_OS_INTEGRITY) # include # endif +# if __has_include() +# include +# elif __has_include() +# include +# else +using ucontext_t = void; +# endif #if defined(Q_OS_MACOS) #include @@ -361,7 +368,39 @@ void printTestRunTime() static quintptr getProgramCounter(void *ucontext) { quintptr pc = 0; - Q_UNUSED(ucontext); + if ([[maybe_unused]] auto ctx = static_cast(ucontext)) { +#if 0 // keep the list below alphabetical + +#elif defined(Q_OS_DARWIN) && defined(Q_PROCESSOR_ARM_64) + pc = ctx->uc_mcontext->__ss.__pc; +#elif defined(Q_OS_DARWIN) && defined(Q_PROCESSOR_X86_64) + pc = ctx->uc_mcontext->__ss.__rip; + +#elif defined(Q_OS_FREEBSD) && defined(Q_PROCESSOR_X86_32) + pc = ctx->uc_mcontext.mc_eip; +#elif defined(Q_OS_FREEBSD) && defined(Q_PROCESSOR_X86_64) + pc = ctx->uc_mcontext.mc_rip; + +#elif defined(Q_OS_LINUX) && defined(Q_PROCESSOR_ARM_32) + // pc = ctx->uc_mcontext.arm_pc; // untested +#elif defined(Q_OS_LINUX) && defined(Q_PROCESSOR_ARM_64) + pc = ctx->uc_mcontext.pc; +#elif defined(Q_OS_LINUX) && defined(Q_PROCESSOR_MIPS) + // pc = ctx->uc_mcontext.pc; // untested +#elif defined(Q_OS_LINUX) && defined(Q_PROCESSOR_LOONGARCH) + // pc = ctx->uc_mcontext.__pc; // untested +#elif defined(Q_OS_LINUX) && defined(Q_PROCESSOR_POWER_32) + // pc = ctx->uc_mcontext.uc_regs->gregs[PT_NIP]; // untested +#elif defined(Q_OS_LINUX) && defined(Q_PROCESSOR_POWER_64) + // pc = ctx->uc_mcontext.gregs[PT_NIP]; // untested +#elif defined(Q_OS_LINUX) && defined(Q_PROCESSOR_RISCV) + // pc = ctx->uc_mcontext.__gregs[REG_PC]; // untested +#elif defined(Q_OS_LINUX) && defined(Q_PROCESSOR_X86_32) + pc = ctx->uc_mcontext.gregs[REG_EIP]; +#elif defined(Q_OS_LINUX) && defined(Q_PROCESSOR_X86_64) + pc = ctx->uc_mcontext.gregs[REG_RIP]; +#endif + } return pc; }