diff options
author | Adam Borowski <kilobyte@angband.pl> | 2012-03-05 19:17:39 +0100 |
---|---|---|
committer | Adam Borowski <kilobyte@angband.pl> | 2012-03-05 19:25:55 +0100 |
commit | 76630604fa2a2f19690e6fe40d53b5fd2d4911fc (patch) | |
tree | efb6855a5e10793c856eee25e33c6153948aafd8 /crawl-ref/source/crash.cc | |
parent | 038d441b01987ec5288f1f3604d3cf0dc99e3160 (diff) | |
download | crawl-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.cc | 37 |
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 |