| 311 | } |
| 312 | |
| 313 | static uintptr_t FaultInstructionPointer(void* ctx) |
| 314 | { |
| 315 | if (!ctx) return 0; |
| 316 | ucontext_t* uc = static_cast<ucontext_t*>(ctx); |
| 317 | #if defined(__i386__) |
| 318 | return static_cast<uintptr_t>(uc->uc_mcontext.gregs[14]); // REG_EIP |
| 319 | #elif defined(__x86_64__) |
| 320 | return static_cast<uintptr_t>(uc->uc_mcontext.gregs[16]); // REG_RIP |
| 321 | #elif defined(__aarch64__) |
| 322 | return static_cast<uintptr_t>(uc->uc_mcontext.pc); |
| 323 | #else |
| 324 | return 0; |
| 325 | #endif |
| 326 | } |
| 327 | |
| 328 | // Async-signal-safe: scan /proc/self/maps via raw read() for the mapping containing |
| 329 | // `addr`. Returns its base (0 if not found); dladdr is unreliable on stripped i386. |