summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source/crash.cc
diff options
context:
space:
mode:
authorAdam Borowski <kilobyte@angband.pl>2012-03-05 19:17:39 +0100
committerAdam Borowski <kilobyte@angband.pl>2012-03-05 19:25:55 +0100
commit76630604fa2a2f19690e6fe40d53b5fd2d4911fc (patch)
treeefb6855a5e10793c856eee25e33c6153948aafd8 /crawl-ref/source/crash.cc
parent038d441b01987ec5288f1f3604d3cf0dc99e3160 (diff)
downloadcrawl-ref-76630604fa2a2f19690e6fe40d53b5fd2d4911fc.tar.gz
crawl-ref-76630604fa2a2f19690e6fe40d53b5fd2d4911fc.zip
In DGL, give games stuck for 60s CPU time the finger (the Nethack level 7 one).
There's a new crop of infinite loop bugs, they're hard to debug in DGL due to permissions (only Napkin can attach gdb) so backtraces would be nice, and taking 100% CPU on a public server is very detrimental to players.
Diffstat (limited to 'crawl-ref/source/crash.cc')
-rw-r--r--crawl-ref/source/crash.cc37
1 files changed, 37 insertions, 0 deletions
diff --git a/crawl-ref/source/crash.cc b/crawl-ref/source/crash.cc
index 4a4e519809..d89ebc7534 100644
--- a/crawl-ref/source/crash.cc
+++ b/crawl-ref/source/crash.cc
@@ -7,6 +7,7 @@
#ifdef USE_UNIX_SIGNALS
#include <signal.h>
+#include <sys/time.h>
#endif
#if defined(UNIX)
@@ -142,6 +143,30 @@ static void _crash_signal_handler(int sig_num)
console_shutdown();
#endif
+#ifdef DGAMELAUNCH
+ /* Infinite loop protection.
+
+ Not tickling the watchdog for 60 seconds of user CPU time (not wall
+ time!) means something is terribly wrong. Even worst hogs like
+ pre-0.6 god renouncement or current Time Step in the Abyss don't take
+ more than several seconds.
+
+ DGL only -- local players will notice the game is stuck and be able
+ to kill it.
+
+ It's likely to die horribly -- it's one of signals that is often
+ received while in non-signal safe functions, especially malloc()
+ which _will_ fuck the process up (remember, C++ can't blink without
+ malloc()ing something). In such cases, alarm() above will kill us.
+ That's nasty and random, but at least should give us backtraces most
+ of the time, and avoid dragging down the servers. And even if for
+ some odd reason SIGALRM won't kill us, the worst that can happen is
+ wasting 100% CPU which is precisely what happens right now.
+ */
+ if (sig_num == SIGVTALRM)
+ die_noline("Stuck game with 100%% CPU use\n");
+#endif
+
do_crash_dump();
if (crawl_state.game_wants_emergency_save && crawl_state.need_save
@@ -341,3 +366,15 @@ void disable_other_crashes()
// going down so blocking the other thread is ok.
mutex_lock(crash_mutex);
}
+
+#ifdef DGAMELAUNCH
+void watchdog()
+{
+ struct itimerval t;
+ t.it_interval.tv_sec = 0;
+ t.it_interval.tv_usec = 0;
+ t.it_value.tv_sec = 60;
+ t.it_value.tv_usec = 0;
+ setitimer(ITIMER_VIRTUAL, &t, 0);
+}
+#endif