summaryrefslogtreecommitdiff
path: root/src/gpgpu-sim/gpu-sim.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/gpgpu-sim/gpu-sim.cc')
-rw-r--r--src/gpgpu-sim/gpu-sim.cc56
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();
}