From d42a180a16bfde48d1b4b198db0d64c097ab93a7 Mon Sep 17 00:00:00 2001 From: zelgadis Date: Thu, 22 Jan 2009 05:17:56 +0000 Subject: Put platform dependant crash handling code into crash-X.cc files, and link against them in the make files like libunix/libgui/etc are. git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@8675 c06c8d41-db1a-0410-9941-cceddc491573 --- crawl-ref/source/acr.cc | 1 + crawl-ref/source/crash-d.cc | 24 +++++ crawl-ref/source/crash-u.cc | 176 +++++++++++++++++++++++++++++++++++ crawl-ref/source/crash-w.cc | 24 +++++ crawl-ref/source/crash.h | 18 ++++ crawl-ref/source/debug.cc | 1 + crawl-ref/source/libdos.cc | 12 --- crawl-ref/source/libdos.h | 4 - crawl-ref/source/libgui.cc | 12 --- crawl-ref/source/libgui.h | 4 - crawl-ref/source/libunix.cc | 154 ------------------------------ crawl-ref/source/libunix.h | 4 - crawl-ref/source/libw32c.cc | 12 --- crawl-ref/source/libw32c.h | 4 - crawl-ref/source/makefile.dos | 2 +- crawl-ref/source/makefile.mgw | 2 +- crawl-ref/source/makefile.unix | 2 +- crawl-ref/source/makefile_tiles.mgw | 2 +- crawl-ref/source/makefile_tiles.unix | 2 +- 19 files changed, 249 insertions(+), 211 deletions(-) create mode 100644 crawl-ref/source/crash-d.cc create mode 100644 crawl-ref/source/crash-u.cc create mode 100644 crawl-ref/source/crash-w.cc create mode 100644 crawl-ref/source/crash.h (limited to 'crawl-ref') diff --git a/crawl-ref/source/acr.cc b/crawl-ref/source/acr.cc index 343cf55052..050ccd29f4 100644 --- a/crawl-ref/source/acr.cc +++ b/crawl-ref/source/acr.cc @@ -51,6 +51,7 @@ REVISION("$Rev$"); #include "cloud.h" #include "clua.h" #include "command.h" +#include "crash.h" #include "database.h" #include "debug.h" #include "delay.h" diff --git a/crawl-ref/source/crash-d.cc b/crawl-ref/source/crash-d.cc new file mode 100644 index 0000000000..0feffe4abc --- /dev/null +++ b/crawl-ref/source/crash-d.cc @@ -0,0 +1,24 @@ +/* + * File: crash-d.cc + * Summary: Dos specific crash handling functions. + * Written by: ?? + * + * Modified for Crawl Reference by $Author$ on $Date$ + */ + +#include "AppHdr.h" +REVISION("$Rev$"); + +#include "crash.h" + +void init_crash_handler() +{ +} + +void dump_crash_info(FILE* file) +{ +} + +void write_stack_trace(FILE* file, int ignore_count) +{ +} diff --git a/crawl-ref/source/crash-u.cc b/crawl-ref/source/crash-u.cc new file mode 100644 index 0000000000..fba87d64fb --- /dev/null +++ b/crawl-ref/source/crash-u.cc @@ -0,0 +1,176 @@ +/* + * File: crash-u.cc + * Summary: UNIX specific crash handling functions. + * Written by: Matthew Cline + * + * Modified for Crawl Reference by $Author$ on $Date$ + */ + +#include "AppHdr.h" +REVISION("$Rev$"); + +#ifdef USE_UNIX_SIGNALS +#include +#endif + +#ifdef __GLIBC__ +#include +#endif + +#include "crash.h" + +#include "externs.h" +#include "state.h" +#include "initfile.h" + +///////////////////////////////////////////////////////////////////////////// +// Code for printing out debugging info on a crash. +//////////////////////////////////////////////////////////////////////////// +static int _crash_signal = 0; +static int _recursion_depth = 0; + +static void _crash_signal_handler(int sig_num) +{ + if (crawl_state.game_crashed) + { + if (_recursion_depth > 0) + return; + _recursion_depth++; + + fprintf(stderr, "Recursive crash." EOL); + + std::string dir = (!Options.morgue_dir.empty() ? Options.morgue_dir : + !SysEnv.crawl_dir.empty() ? SysEnv.crawl_dir + : ""); + + if (!dir.empty() && dir[dir.length() - 1] != FILE_SEPARATOR) + dir += FILE_SEPARATOR; + + char name[180]; + + sprintf(name, "%scrash-recursive-%s-%d.txt", dir.c_str(), + you.your_name, (int) time(NULL)); + + FILE* file = fopen(name, "w"); + + if (file == NULL) + file = stderr; + + write_stack_trace(file, 0); + + if (file != stderr) + fclose(file); + return; + } + + _crash_signal = sig_num; + crawl_state.game_crashed = true; + + // In case the crash dumper is unable to open a file and has to dump + // to stderr. +#ifndef USE_TILE + unixcurses_shutdown(); +#endif + + do_crash_dump(); + + // Now crash for real. + signal(sig_num, SIG_DFL); + raise(sig_num); +} + +void init_crash_handler() +{ +#if defined(USE_UNIX_SIGNALS) + + for (int i = 1; i <= 64; i++) + { +#ifdef SIGHUP_SAVE + if (i == SIGHUP) + continue; +#endif +#ifdef SIGQUIT + if (i == SIGQUIT) + continue; +#endif +#ifdef SIGINT + if (i == SIGINT) + continue; +#endif +#ifdef SIGCHLD + if (i == SIGCHLD) + continue; +#endif +#ifdef SIGTSTP + if (i == SIGTSTP) + continue; +#endif +#ifdef SIGCONT + if (i == SIGCONT) + continue; +#endif +#ifdef SIGIO + if (i == SIGIO) + continue; +#endif +#ifdef SIGPROF + if (i == SIGPROF) + continue; +#endif + if (i == SIGWINCH) + continue; + + signal(i, _crash_signal_handler); + } + +#endif // if defined(USE_UNIX_SIGNALS) +} + +void dump_crash_info(FILE* file) +{ + const char *name = strsignal(_crash_signal); + if (name == NULL) + name = "INVALID"; + + fprintf(file, "Crash caused by signal #%d: %s" EOL, _crash_signal, + name); +} + +#ifdef __GLIBC__ +// NOTE: This should work on OS X, according to +// http://developer.apple.com/DOCUMENTATION/DARWIN/Reference/ManPages/man3/backtrace_symbols.3.html + +void write_stack_trace(FILE* file, int ignore_count) +{ + void* frames[50]; + + int num_frames = backtrace(frames, ARRAYSZ(frames)); + + char **symbols = backtrace_symbols(frames, num_frames); + + if (symbols == NULL) + { + fprintf(stderr, "Out of memroy." EOL); + fprintf(file, "Out of memory." EOL); + + // backtrace_symbols_fd() can print out the stack trace even if + // malloc() can't find any free memory. + backtrace_symbols_fd(frames, num_frames, fileno(file)); + return; + } + + for (int i = ignore_count; i < num_frames; i++) + { + fprintf(file, "%s" EOL, symbols[i]); + } + + free(symbols); +} +#else // ifdef __GLIBC__ +void write_stack_trace(FILE* file, int ignore_count) +{ + const char* msg = "Unable to get stack trace on this platform." EOL; + fprintf(stderr, msg); + fprintf(file, msg); +} +#endif diff --git a/crawl-ref/source/crash-w.cc b/crawl-ref/source/crash-w.cc new file mode 100644 index 0000000000..b23b1ca800 --- /dev/null +++ b/crawl-ref/source/crash-w.cc @@ -0,0 +1,24 @@ +/* + * File: crash-w.cc + * Summary: Windows specific crash handling functions. + * Written by: ?? + * + * Modified for Crawl Reference by $Author$ on $Date$ + */ + +#include "AppHdr.h" +REVISION("$Rev$"); + +#include "crash.h" + +void init_crash_handler() +{ +} + +void dump_crash_info(FILE* file) +{ +} + +void write_stack_trace(FILE* file, int ignore_count) +{ +} diff --git a/crawl-ref/source/crash.h b/crawl-ref/source/crash.h new file mode 100644 index 0000000000..6a2e618cb2 --- /dev/null +++ b/crawl-ref/source/crash.h @@ -0,0 +1,18 @@ +/* + * File: crash.h + * Summary: Platform specific crash handling functions. + * Written by: Matthew cline + * + * Modified for Crawl Reference by $Author$ on $Date$ + */ + +#ifndef CRASH_H +#define CRASH_H + +#include + +void init_crash_handler(); +void dump_crash_info(FILE* file); +void write_stack_trace(FILE* file, int ignore_count); + +#endif diff --git a/crawl-ref/source/debug.cc b/crawl-ref/source/debug.cc index af34b6ac43..28477c50dc 100644 --- a/crawl-ref/source/debug.cc +++ b/crawl-ref/source/debug.cc @@ -34,6 +34,7 @@ REVISION("$Rev$"); #include "branch.h" #include "chardump.h" #include "cio.h" +#include "crash.h" #include "decks.h" #include "delay.h" #include "describe.h" diff --git a/crawl-ref/source/libdos.cc b/crawl-ref/source/libdos.cc index f9683ff8c8..8442bf9e06 100644 --- a/crawl-ref/source/libdos.cc +++ b/crawl-ref/source/libdos.cc @@ -139,16 +139,4 @@ void putwch(unsigned c) putch(static_cast(c)); } -void init_crash_handler() -{ -} - -void dump_crash_info(FILE* file) -{ -} - -void write_stack_trace(FILE* file, int ignore_count) -{ -} - #endif /* #if defined(DOS) */ diff --git a/crawl-ref/source/libdos.h b/crawl-ref/source/libdos.h index e9a7941563..1d68d0084f 100644 --- a/crawl-ref/source/libdos.h +++ b/crawl-ref/source/libdos.h @@ -45,8 +45,4 @@ inline void put_colour_ch(int colour, unsigned ch) putwch(ch); } -void init_crash_handler(); -void dump_crash_info(FILE* file); -void write_stack_trace(FILE* file, int ignore_count); - #endif diff --git a/crawl-ref/source/libgui.cc b/crawl-ref/source/libgui.cc index 89059f72fe..751392004e 100644 --- a/crawl-ref/source/libgui.cc +++ b/crawl-ref/source/libgui.cc @@ -417,16 +417,4 @@ int stricmp(const char *str1, const char *str2) return (strcmp(str1, str2)); } -void init_crash_handler() -{ -} - -void dump_crash_info(FILE* file) -{ -} - -void write_stack_trace(FILE* file, int ignore_count) -{ -} - #endif // #ifdef UNIX diff --git a/crawl-ref/source/libgui.h b/crawl-ref/source/libgui.h index 1ca73e103c..302d14f1e8 100644 --- a/crawl-ref/source/libgui.h +++ b/crawl-ref/source/libgui.h @@ -73,9 +73,5 @@ int itoa(int value, char *strptr, int radix); int stricmp(const char *str1, const char *str2); #endif -void init_crash_handler(); -void dump_crash_info(FILE* file); -void write_stack_trace(FILE* file, int ignore_count); - #endif // USE_TILE #endif // LIBGUI_H diff --git a/crawl-ref/source/libunix.cc b/crawl-ref/source/libunix.cc index 8c26e5842b..99b0d2ef90 100644 --- a/crawl-ref/source/libunix.cc +++ b/crawl-ref/source/libunix.cc @@ -70,10 +70,6 @@ static struct termios game_term; #include CURSES_INCLUDE_FILE #endif -#ifdef __GLIBC__ -#include -#endif - // Globals holding current text/backg. colors static short FG_COL = WHITE; static short BG_COL = BLACK; @@ -1142,154 +1138,4 @@ extern "C" { } } -///////////////////////////////////////////////////////////////////////////// -// Code for printing out debugging info on a crash. -//////////////////////////////////////////////////////////////////////////// -static int _crash_signal = 0; -static int _recursion_depth = 0; - -static void _crash_signal_handler(int sig_num) -{ - if (crawl_state.game_crashed) - { - if (_recursion_depth > 0) - return; - _recursion_depth++; - - fprintf(stderr, "Recursive crash." EOL); - - std::string dir = (!Options.morgue_dir.empty() ? Options.morgue_dir : - !SysEnv.crawl_dir.empty() ? SysEnv.crawl_dir - : ""); - - if (!dir.empty() && dir[dir.length() - 1] != FILE_SEPARATOR) - dir += FILE_SEPARATOR; - - char name[180]; - - sprintf(name, "%scrash-recursive-%s-%d.txt", dir.c_str(), - you.your_name, (int) time(NULL)); - - FILE* file = fopen(name, "w"); - - if (file == NULL) - file = stderr; - - write_stack_trace(file, 0); - - if (file != stderr) - fclose(file); - return; - } - _crash_signal = sig_num; - crawl_state.game_crashed = true; - - // In case the crash dumper is unable to open a file and has to dump - // to stderr. -#ifndef USE_TILE - unixcurses_shutdown(); -#endif - - do_crash_dump(); - - // Now crash for real. - signal(sig_num, SIG_DFL); - raise(sig_num); -} - -void init_crash_handler() -{ -#if defined(USE_UNIX_SIGNALS) - - for (int i = 1; i <= 64; i++) - { -#ifdef SIGHUP_SAVE - if (i == SIGHUP) - continue; -#endif -#ifdef SIGQUIT - if (i == SIGQUIT) - continue; -#endif -#ifdef SIGINT - if (i == SIGINT) - continue; -#endif -#ifdef SIGCHLD - if (i == SIGCHLD) - continue; -#endif -#ifdef SIGTSTP - if (i == SIGTSTP) - continue; -#endif -#ifdef SIGCONT - if (i == SIGCONT) - continue; -#endif -#ifdef SIGIO - if (i == SIGIO) - continue; -#endif -#ifdef SIGPROF - if (i == SIGPROF) - continue; -#endif - if (i == SIGWINCH) - continue; - - signal(i, _crash_signal_handler); - } - -#endif // if defined(USE_UNIX_SIGNALS) -} - -void dump_crash_info(FILE* file) -{ - const char *name = strsignal(_crash_signal); - if (name == NULL) - name = "INVALID"; - - fprintf(file, "Crash caused by signal #%d: %s" EOL, _crash_signal, - name); -} - -#ifdef __GLIBC__ -// NOTE: This should work on OS X, according to -// http://developer.apple.com/DOCUMENTATION/DARWIN/Reference/ManPages/man3/backtrace_symbols.3.html - -void write_stack_trace(FILE* file, int ignore_count) -{ - void* frames[50]; - - int num_frames = backtrace(frames, ARRAYSZ(frames)); - - char **symbols = backtrace_symbols(frames, num_frames); - - if (symbols == NULL) - { - fprintf(stderr, "Out of memroy." EOL); - fprintf(file, "Out of memory." EOL); - - // backtrace_symbols_fd() can print out the stack trace even if - // malloc() can't find any free memory. - backtrace_symbols_fd(frames, num_frames, fileno(file)); - return; - } - - for (int i = ignore_count; i < num_frames; i++) - { - fprintf(file, "%s" EOL, symbols[i]); - } - - free(symbols); -} -#else // ifdef __GLIBC__ -void write_stack_trace(FILE* file, int ignore_count) -{ - const char* msg = "Unable to get stack trace on this platform." EOL; - fprintf(stderr, msg); - fprintf(file, msg); -} -#endif diff --git a/crawl-ref/source/libunix.h b/crawl-ref/source/libunix.h index 12602014fb..4816e43a87 100644 --- a/crawl-ref/source/libunix.h +++ b/crawl-ref/source/libunix.h @@ -68,10 +68,6 @@ inline bool is_smart_cursor_enabled() { return (false); } void set_mouse_enabled(bool enabled); -void init_crash_handler(); -void dump_crash_info(FILE* file); -void write_stack_trace(FILE* file, int ignore_count); - #ifndef _LIBUNIX_IMPLEMENTATION /* Some stuff from curses, to remove compiling warnings.. */ extern "C" diff --git a/crawl-ref/source/libw32c.cc b/crawl-ref/source/libw32c.cc index e0b612b4ad..73d1701873 100644 --- a/crawl-ref/source/libw32c.cc +++ b/crawl-ref/source/libw32c.cc @@ -1147,16 +1147,4 @@ int ftruncate(int fp, int size) #endif /* #if _MSC_VER */ -void init_crash_handler() -{ -} - -void dump_crash_info(FILE* file) -{ -} - -void write_stack_trace(FILE* file, int ignore_count) -{ -} - #endif /* #if defined(WIN32CONSOLE) */ diff --git a/crawl-ref/source/libw32c.h b/crawl-ref/source/libw32c.h index 500e69f131..5d6b7f1900 100644 --- a/crawl-ref/source/libw32c.h +++ b/crawl-ref/source/libw32c.h @@ -61,8 +61,4 @@ inline void put_colour_ch(int colour, unsigned ch) putwch(ch); } -void init_crash_handler(); -void dump_crash_info(FILE* file); -void write_stack_trace(FILE* file, int ignore_count); - #endif diff --git a/crawl-ref/source/makefile.dos b/crawl-ref/source/makefile.dos index 999c9321ef..4a9f96b6b5 100644 --- a/crawl-ref/source/makefile.dos +++ b/crawl-ref/source/makefile.dos @@ -48,7 +48,7 @@ CFOTHERS := -D$(OS_TYPE) $(EXTRA_FLAGS) -fsigned-char -fstrict-aliasing \ CFLAGS := $(INCLUDES) $(CFWARN) $(CFOTHERS) YCFLAGS := $(INCLUDES) $(CFOTHERS) -OBJECTS += libdos.o +OBJECTS += libdos.o crash-d.o LDFLAGS = diff --git a/crawl-ref/source/makefile.mgw b/crawl-ref/source/makefile.mgw index 1e1ce1c96f..0ccf5ccd0c 100644 --- a/crawl-ref/source/makefile.mgw +++ b/crawl-ref/source/makefile.mgw @@ -55,7 +55,7 @@ CFOTHERS := -fsigned-char \ CFLAGS := $(INCLUDES) $(CFWARN) $(CFOTHERS) YCFLAGS := $(INCLUDES) $(CFOTHERS) -OBJECTS := $(OBJECTS) libw32c.o +OBJECTS := $(OBJECTS) libw32c.o crash-w.o LDFLAGS = diff --git a/crawl-ref/source/makefile.unix b/crawl-ref/source/makefile.unix index c5b3e9fcf6..aee1a194c8 100644 --- a/crawl-ref/source/makefile.unix +++ b/crawl-ref/source/makefile.unix @@ -10,7 +10,7 @@ GAME = crawl # it will make a variable called OBJECTS that contains all the libraries include makefile.obj -OBJECTS += libunix.o +OBJECTS += libunix.o crash-u.o CXX = g++ DELETE = rm -f diff --git a/crawl-ref/source/makefile_tiles.mgw b/crawl-ref/source/makefile_tiles.mgw index b8cc376aed..a9d5e31f36 100644 --- a/crawl-ref/source/makefile_tiles.mgw +++ b/crawl-ref/source/makefile_tiles.mgw @@ -80,7 +80,7 @@ CFOTHERS := -fsigned-char \ CFLAGS := $(INCLUDES) $(CFWARN) $(CFOTHERS) $(SDL_CFLAGS) YCFLAGS := $(INCLUDES) $(CFOTHERS) -OBJECTS := $(OBJECTS) libgui.o tilepick.o tile2.o tilereg.o tilesdl.o tilefont.o tiletex.o tilemcache.o tilebuf.o +OBJECTS := $(OBJECTS) libgui.o tilepick.o tile2.o tilereg.o tilesdl.o tilefont.o tiletex.o tilemcache.o tilebuf.o crash-w.o LDFLAGS = diff --git a/crawl-ref/source/makefile_tiles.unix b/crawl-ref/source/makefile_tiles.unix index ed6998aa73..b3d23bde14 100644 --- a/crawl-ref/source/makefile_tiles.unix +++ b/crawl-ref/source/makefile_tiles.unix @@ -10,7 +10,7 @@ GAME = crawl # it will make a variable called OBJECTS that contains all the libraries include makefile.obj -OBJECTS += libgui.o tilepick.o tile2.o tilereg.o tilesdl.o tilefont.o tiletex.o tilemcache.o tilebuf.o +OBJECTS += libgui.o tilepick.o tile2.o tilereg.o tilesdl.o tilefont.o tiletex.o tilemcache.o tilebuf.o crash-u.o SDL_CFLAGS := $(shell sdl-config --cflags) SDL_LDFLAGS := $(shell sdl-config --libs) -lSDLmain -- cgit v1.2.3-54-g00ecf