@@ -412,6 +412,27 @@ void dumpSignalInfo(int signum, siginfo_t* siginfo) {
412412 print (" ), stack trace: ***\n " );
413413}
414414
415+ void dumpContext (void * uctx) {
416+ #if FOLLY_X64
417+ print (" *** Uctx (TSC_AUX " );
418+ {
419+ unsigned a, d, aux;
420+ __asm__ volatile (" rdtscp" : " =a" (a), " =d" (d), " =c" (aux) :: " memory" );
421+ printHex (aux);
422+ }
423+
424+ auto & gregs = static_cast <ucontext_t *>(uctx)->uc_mcontext .gregs ;
425+ print (" ) (RIP " );
426+ printHex (gregs[REG_RIP]);
427+ print (" , RSP " );
428+ printHex (gregs[REG_RSP]);
429+ print (" , RBP " );
430+ printHex (gregs[REG_RBP]);
431+ print (" )\n " );
432+ flush ();
433+ #endif
434+ }
435+
415436// On Linux, pthread_t is a pointer, so 0 is an invalid value, which we
416437// take to indicate "no thread in the signal handler".
417438//
@@ -422,7 +443,7 @@ std::atomic<pthread_t> gSignalThread(kInvalidThreadId);
422443std::atomic<bool > gInRecursiveSignalHandler (false );
423444
424445// Here be dragons.
425- void innerSignalHandler (int signum, siginfo_t * info, void * /* uctx */ ) {
446+ void innerSignalHandler (int signum, siginfo_t * info, void * uctx) {
426447 // First, let's only let one thread in here at a time.
427448 pthread_t myId = pthread_self ();
428449
@@ -451,6 +472,7 @@ void innerSignalHandler(int signum, siginfo_t* info, void* /* uctx */) {
451472 dumpTimeInfo ();
452473 dumpSignalInfo (signum, info);
453474 gStackTracePrinter ->printStackTrace (true ); // with symbolization
475+ dumpContext (uctx);
454476
455477 // Run user callbacks
456478 auto callbacks = gFatalSignalCallbackRegistry .load (std::memory_order_acquire);
0 commit comments