diff options
Diffstat (limited to 'src/gpgpu-sim/gpu-sim.cc')
| -rw-r--r-- | src/gpgpu-sim/gpu-sim.cc | 56 |
1 files changed, 56 insertions, 0 deletions
diff --git a/src/gpgpu-sim/gpu-sim.cc b/src/gpgpu-sim/gpu-sim.cc index c858c50..1c0c6c6 100644 --- a/src/gpgpu-sim/gpu-sim.cc +++ b/src/gpgpu-sim/gpu-sim.cc @@ -1342,7 +1342,52 @@ void gpgpu_sim::print_stats(unsigned long long streamID) { } } +// Static pointer + signal handler for MEMCO_DBG_DEADLOCK. When a +// SIGSEGV / SIGABRT fires before the deadlock detector triggers, dump +// per-warp state for the most recently active gpgpu_sim and re-raise. +static gpgpu_sim *g_dbg_sim_for_handler = NULL; +static volatile int g_dbg_sim_handler_in_progress = 0; +static void memco_dbg_signal_handler(int sig) { + if (g_dbg_sim_handler_in_progress) { + // already dumping; if we got here again, give up and re-raise the + // default to avoid infinite recursion in handler. + signal(sig, SIG_DFL); + raise(sig); + return; + } + g_dbg_sim_handler_in_progress = 1; + fprintf(stdout, + "\n\n[DEADLOCK_DUMP] caught signal %d — dumping warp state " + "before crash\n", sig); + fflush(stdout); + if (g_dbg_sim_for_handler) g_dbg_sim_for_handler->dbg_dump_all_warps(); + fflush(stdout); + signal(sig, SIG_DFL); + raise(sig); +} + +void gpgpu_sim::dbg_dump_all_warps() { + for (unsigned i = 0; i < m_shader_config->n_simt_clusters; i++) { + if (m_cluster[i]->get_not_completed() > 0) { + m_cluster[i]->dump_warps_at_deadlock(stdout); + } + } +} + void gpgpu_sim::deadlock_check() { + // Lazy installer for the signal handler (only when MEMCO_DBG_DEADLOCK + // is set). Once installed, future signals are caught. + static bool sig_handler_installed = false; + if (!sig_handler_installed && getenv("MEMCO_DBG_DEADLOCK") != NULL) { + sig_handler_installed = true; + g_dbg_sim_for_handler = this; + signal(SIGSEGV, memco_dbg_signal_handler); + signal(SIGABRT, memco_dbg_signal_handler); + } else if (getenv("MEMCO_DBG_DEADLOCK") != NULL) { + // Keep the static pointer up to date in case multiple gpgpu_sim + // instances are created (rare). + g_dbg_sim_for_handler = this; + } if (m_config.gpu_deadlock_detect && gpu_deadlock) { fflush(stdout); printf( @@ -1382,6 +1427,17 @@ void gpgpu_sim::deadlock_check() { printf( "\nRe-run the simulator in gdb and use debug routines in .gdbinit to " "debug this\n"); + // MEMCO_DBG_DEADLOCK: dump per-warp state for any non-empty cluster + // before aborting. Helps localize which specific warp(s) are stuck + // and why (scoreboard / simt-table / ibuffer state). + if (getenv("MEMCO_DBG_DEADLOCK") != NULL) { + for (unsigned i = 0; i < m_shader_config->n_simt_clusters; i++) { + if (m_cluster[i]->get_not_completed() > 0) { + m_cluster[i]->dump_warps_at_deadlock(stdout); + } + } + fflush(stdout); + } fflush(stdout); abort(); } |
