summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source/state.cc
diff options
context:
space:
mode:
authorzelgadis <zelgadis@c06c8d41-db1a-0410-9941-cceddc491573>2009-01-18 05:12:24 +0000
committerzelgadis <zelgadis@c06c8d41-db1a-0410-9941-cceddc491573>2009-01-18 05:12:24 +0000
commitddb951a57ed0ac94c749e971f4c0556794110275 (patch)
treeb43fb8c51041edf4f9f846ede3aa0a6c79a0ffb3 /crawl-ref/source/state.cc
parentb8f4f50faab8b771ad053c154e781d129ef55005 (diff)
downloadcrawl-ref-ddb951a57ed0ac94c749e971f4c0556794110275.tar.gz
crawl-ref-ddb951a57ed0ac94c749e971f4c0556794110275.zip
Implemented crash data reporting, though it's only some stubs on Windows and
DOS. On UNIX with USE_UNIX_SIGNALS defined, when any crash causing signal happens it will dump to a file the current crawl_state, anything caught by the items and monsters scans, and level building info if the crash happened during level generation. Also, if crawl is linked against the GNU C library (and the exectuable is in ELF format) it will dump the stack trace. The code attempts to automatically detect the presence of glibc, but that might not work on all systems. This should work on OS X, since there's an OS X man page for the glibc functions that get the stack trace. Don't know if it would work with MinGW. Actually getting function names for the stack trace requires the use of the "-rdynamic" linker option, which increases the size of the stripped executable by 27% (yikes!), but still prints the function names even when stripped. All of the function names in the stack trace are mangled C++ ones, but that shouldn't be too much of a problem. git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@8532 c06c8d41-db1a-0410-9941-cceddc491573
Diffstat (limited to 'crawl-ref/source/state.cc')
-rw-r--r--crawl-ref/source/state.cc76
1 files changed, 75 insertions, 1 deletions
diff --git a/crawl-ref/source/state.cc b/crawl-ref/source/state.cc
index febc6e872d..1b2e1f773e 100644
--- a/crawl-ref/source/state.cc
+++ b/crawl-ref/source/state.cc
@@ -19,12 +19,13 @@ REVISION("$Rev$");
#include "mon-util.h"
#include "output.h"
#include "player.h"
+#include "religion.h"
#include "state.h"
#include "tutorial.h"
#include "view.h"
game_state::game_state()
- : mouse_enabled(false), waiting_for_command(false),
+ : game_crashed(false), mouse_enabled(false), waiting_for_command(false),
terminal_resized(false), io_inited(false), need_save(false),
saving_game(false), updating_scores(false), seen_hups(0),
map_stat_gen(false), arena(false), arena_suspended(false),
@@ -372,3 +373,76 @@ std::vector<god_act_state> game_state::other_gods_acting() const
ASSERT(is_god_acting());
return god_act_stack;
}
+
+void game_state::dump(FILE* file)
+{
+ fprintf(file, "\r\nGame state:\r\n\r\n");
+
+ fprintf(file, "mouse_enabled: %d, waiting_for_command: %d "
+ "terminal_resized: %d\r\n",
+ mouse_enabled, waiting_for_command, terminal_resized);
+ fprintf(file, "io_inited: %d, need_save: %d, saving_game: %d, "
+ "updating_scores: %d\r\n:",
+ io_inited, need_save, saving_game, updating_scores);
+ fprintf(file, "seen_hups: %d, map_stat_gen: %d, arena: %d, "
+ "arena_suspended: %d, unicode_ok: %d\r\n",
+ seen_hups, map_stat_gen, arena, arena_suspended, unicode_ok);
+
+ fprintf(file, "\r\n");
+
+ if (!startup_errors.empty())
+ {
+ fprintf(file, "Startup errors:\r\n");
+ for (unsigned int i = 0; i < startup_errors.size(); i++)
+ fprintf(file, "%s\n", startup_errors[i].c_str());
+ fprintf(file, "\r\n");
+ }
+
+ fprintf(file, "prev_cmd = %s\r\n", command_to_name(prev_cmd).c_str());
+
+ if (doing_prev_cmd_again)
+ {
+ fprintf(file, "Doing prev_cmd again with keys: ");
+ for (unsigned int i = 0; i < prev_cmd_keys.size(); i++)
+ fprintf(file, "%d, ", prev_cmd_keys[i]);
+ fprintf(file, "\r\n");
+ fprintf(file, "As ASCII keys: ");
+ for (unsigned int i = 0; i < prev_cmd_keys.size(); i++)
+ fprintf(file, "%c", (char) prev_cmd_keys[i]);
+ fprintf(file, "\r\n\r\n");
+ }
+ fprintf(file, "repeat_cmd = %s\r\n", command_to_name(repeat_cmd).c_str());
+
+ if (cmd_repeat_count > 0 || cmd_repeat_goal > 0)
+ {
+ fprintf(file, "Doing command repitition: \r\n");
+ fprintf(file, "cmd_repeat_start:%d, cmd_repeat_count: %d, "
+ "cmd_repeat_goal:%d\r\nprev_cmd_repeat_goal: %d\r\n",
+ cmd_repeat_start, cmd_repeat_count, cmd_repeat_goal,
+ prev_cmd_repeat_goal);
+ fprintf(file, "Keys being repeated: ");
+ for (unsigned int i = 0; i < repeat_cmd_keys.size(); i++)
+ fprintf(file, "%d, ", repeat_cmd_keys[i]);
+ fprintf(file, "\r\n");
+ fprintf(file, "As ASCII keys: ");
+ for (unsigned int i = 0; i < repeat_cmd_keys.size(); i++)
+ fprintf(file, "%c", (char) repeat_cmd_keys[i]);
+ fprintf(file, "\r\n\r\n");
+ }
+
+ if (god_act.which_god != GOD_NO_GOD || god_act.depth != 0)
+ {
+ fprintf(file, "God %s currently acting with depth %d\r\n\r\n",
+ god_name(god_act.which_god).c_str(), god_act.depth);
+ }
+
+ if (god_act_stack.size() != 0)
+ {
+ fprintf(file, "Other gods acting: \r\n");
+ for (unsigned int i = 0; i < god_act_stack.size(); i++)
+ fprintf(file, "God %s with depth %d\r\n",
+ god_name(god_act_stack[i].which_god).c_str(),
+ god_act_stack[i].depth);
+ fprintf(file, "\r\n");
+ }
+}