diff options
author | zelgadis <zelgadis@c06c8d41-db1a-0410-9941-cceddc491573> | 2009-01-28 16:23:06 +0000 |
---|---|---|
committer | zelgadis <zelgadis@c06c8d41-db1a-0410-9941-cceddc491573> | 2009-01-28 16:23:06 +0000 |
commit | 0371e07ab64fc457f74a6640f06a5b439038ceee (patch) | |
tree | dda15773f5bce673944f1a61f578c22f0c70cdb6 /crawl-ref | |
parent | fec3e431ad8d5c47c29a20c4dc81820f867fda23 (diff) | |
download | crawl-ref-0371e07ab64fc457f74a6640f06a5b439038ceee.tar.gz crawl-ref-0371e07ab64fc457f74a6640f06a5b439038ceee.zip |
On a crash, do consistency checking on the level's markers, dump the level's
markers, and dump the persistant Lua data.
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@8839 c06c8d41-db1a-0410-9941-cceddc491573
Diffstat (limited to 'crawl-ref')
-rw-r--r-- | crawl-ref/source/dat/clua/dungeon.lua | 7 | ||||
-rw-r--r-- | crawl-ref/source/dat/clua/util.lua | 26 | ||||
-rw-r--r-- | crawl-ref/source/debug.cc | 164 | ||||
-rw-r--r-- | crawl-ref/source/mapmark.cc | 19 | ||||
-rw-r--r-- | crawl-ref/source/mapmark.h | 2 |
5 files changed, 215 insertions, 3 deletions
diff --git a/crawl-ref/source/dat/clua/dungeon.lua b/crawl-ref/source/dat/clua/dungeon.lua index 12b1af5665..cea1849ad3 100644 --- a/crawl-ref/source/dat/clua/dungeon.lua +++ b/crawl-ref/source/dat/clua/dungeon.lua @@ -355,4 +355,9 @@ function portal_next(e, next) for _, feat in ipairs({ "]", ")", "}" }) do e.lua_marker(feat, portal_stair_dst(next)) end -end
\ No newline at end of file +end + +-- Turn persistant data into a human readable string +function persist_to_string() + return table_to_string(dgn.persist) +end diff --git a/crawl-ref/source/dat/clua/util.lua b/crawl-ref/source/dat/clua/util.lua index fab5720a7a..2aa4f2fe85 100644 --- a/crawl-ref/source/dat/clua/util.lua +++ b/crawl-ref/source/dat/clua/util.lua @@ -250,4 +250,28 @@ function util.Timer:mark(what) local now = crawl.millis() crawl.mpr(what .. ": " .. (now - last) .. " ms") self.last = now -end
\ No newline at end of file +end + +-- Turn contents of a table into a human readable string +function table_to_string(table, depth) + depth = depth or 0 + + local indent = string.rep(" ", depth * 4) + + local str = "" + + for key, value in pairs(table) do + str = str .. indent .. key .. ": " + + if type(value) == "table" then + str = str .. "\n" .. table_to_string(value, depth + 1) + elseif type(value) == "function" then + str = str .. "function" + else + str = str .. value + end + str = str .. "\n" + end + + return str +end diff --git a/crawl-ref/source/debug.cc b/crawl-ref/source/debug.cc index fc95ef6529..e97faf6575 100644 --- a/crawl-ref/source/debug.cc +++ b/crawl-ref/source/debug.cc @@ -59,6 +59,7 @@ REVISION("$Rev$"); #include "makeitem.h" #include "mapdef.h" +#include "mapmark.h" #include "maps.h" #include "message.h" #include "misc.h" @@ -5587,6 +5588,7 @@ static void _dump_level_info(FILE* file) } } + static void _dump_player(FILE *file) { // Only dump player info during arena mode if the player is likely @@ -5843,6 +5845,146 @@ static void _dump_player(FILE *file) fprintf(file, "}}}}}}}}}}}" EOL EOL); } +static void _debug_marker_scan() +{ + std::vector<map_marker*> markers = env.markers.get_all(); + + for (unsigned int i = 0; i < markers.size(); i++) + { + map_marker* marker = markers[i]; + + if (marker == NULL) + { + mprf(MSGCH_ERROR, "Marker #%d is NULL", i); + continue; + } + + map_marker_type type = marker->get_type(); + + if (type < MAT_FEATURE || type >= NUM_MAP_MARKER_TYPES) + mprf(MSGCH_ERROR, "Makrer #%d at (%d, %d) has invalid type %d", + i, marker->pos.x, marker->pos.y, (int) type); + + if (!in_bounds(marker->pos)) + { + mprf(MSGCH_ERROR, "Marker #%d, type %d at (%d, %d) out of bounds", + i, (int) type, marker->pos.x, marker->pos.y); + continue; + } + + bool found = false; + std::vector<map_marker*> at_pos + = env.markers.get_markers_at(marker->pos); + + for (unsigned int j = 0; j < at_pos.size(); j++) + { + map_marker* tmp = at_pos[i]; + + if (tmp == NULL) + continue; + + if (tmp == marker) + { + found = true; + break; + } + } + if (!found) + mprf(MSGCH_ERROR, "Marker #%d, type %d at (%d, %d) unlinked", + i, (int) type, marker->pos.x, marker->pos.y); + } + + for (int x = MAPGEN_BORDER; x < (GXM - MAPGEN_BORDER - 1); x++) + for (int y = MAPGEN_BORDER; y < (GYM - MAPGEN_BORDER - 1); y++) + { + coord_def pos(x, y); + + std::vector<map_marker*> at_pos + = env.markers.get_markers_at(pos); + + for (unsigned int i = 0; i < at_pos.size(); i++) + { + map_marker *marker = at_pos[i]; + + if (marker == NULL) + { + mprf(MSGCH_ERROR, "Marker #%d at (%d, %d) NULL", + i, x, y); + continue; + } + if (marker->pos != pos) + { + mprf(MSGCH_ERROR, "Marker #%d, type %d at (%d, %d) " + "thinks it's at (%d, %d)", + i, (int) marker->get_type(), x, y, + marker->pos.x, marker->pos.y); + if (!in_bounds(marker->pos)) + mpr("Further, it thinks it's out of bounds.", + MSGCH_ERROR); + } + } + } +} // _debug_marker_scan() + +static void _debug_dump_markers() +{ + std::vector<map_marker*> markers = env.markers.get_all(); + + for (unsigned int i = 0; i < markers.size(); i++) + { + map_marker* marker = markers[i]; + + if (marker == NULL || marker->get_type() == MAT_LUA_MARKER) + continue; + + mprf(MSGCH_DIAGNOSTICS, "Marker %d at (%d, %d): %s", + i, marker->pos.x, marker->pos.y, + marker->debug_describe().c_str()); + } +} // _debug_dump_markers() + +static void _debug_dump_lua_markers() +{ + std::vector<map_marker*> markers = env.markers.get_all(); + + for (unsigned int i = 0; i < markers.size(); i++) + { + map_marker* marker = markers[i]; + + if (marker == NULL || marker->get_type() != MAT_LUA_MARKER) + continue; + + map_lua_marker* lua_marker = dynamic_cast<map_lua_marker*>(marker); + + std::string result = lua_marker->debug_to_string(); + + if (result.size() > 0 && result[result.size() - 1] == '\n') + result = result.substr(0, result.size() - 1); + + mprf(MSGCH_DIAGNOSTICS, "Lua marker %d at (%d, %d):", + i, marker->pos.x, marker->pos.y); + mprf(MSGCH_DIAGNOSTICS, "{{{{"); + mprf(MSGCH_DIAGNOSTICS, result.c_str()); + mprf(MSGCH_DIAGNOSTICS, "}}}}"); + } +} + +static void _debug_dump_lua_persist() +{ + lua_stack_cleaner cln(dlua); + + std::string result; + if (!dlua.callfn("persist_to_string", 0, 1)) + result = make_stringf("error (persist_to_string): %s", + dlua.error.c_str()); + else if (lua_isstring(dlua, -1)) + result = lua_tostring(dlua, -1); + else + result = "persist_to_string() returned nothing"; + + mprf(MSGCH_DIAGNOSTICS, "%s", result.c_str()); +} + void do_crash_dump() { std::string dir = (!Options.morgue_dir.empty() ? Options.morgue_dir : @@ -5908,6 +6050,14 @@ void do_crash_dump() // generation info if the crash happened during level generation. _dump_level_info(file); + // Dumping information on marker inconsistancy is unlikely to crash, + // as is dumping the descriptions of non-Lua markers. + fprintf(file, "Markers:" EOL); + fprintf(file, "<<<<<<<<<<<<<<<<<<<<<<" EOL); + _debug_marker_scan(); + _debug_dump_markers(); + fprintf(file, ">>>>>>>>>>>>>>>>>>>>>>" EOL); + // Dumping current messages is unlikely to crash. if (file != stderr) { @@ -5933,13 +6083,25 @@ void do_crash_dump() #endif // If anything has screwed up the Lua runtime stacks then trying to - // print those stacks will likely crash, so do this last. + // print those stacks will likely crash, so do this after the others. fprintf(file, "clua stack:" EOL); print_clua_stack(); fprintf(file, "dlua stack:" EOL); print_dlua_stack(); + // Lastly try to dump the Lua persistant data and the contents of the Lua + // markers, since actually running Lua code has the greatest chance of + // crashing. + fprintf(file, "Lua persistant data:" EOL); + fprintf(file, "<<<<<<<<<<<<<<<<<<<<<<" EOL); + _debug_dump_lua_persist(); + fprintf(file, ">>>>>>>>>>>>>>>>>>>>>>" EOL EOL); + fprintf(file, "Lua marker contents:" EOL); + fprintf(file, "<<<<<<<<<<<<<<<<<<<<<<" EOL); + _debug_dump_lua_markers(); + fprintf(file, ">>>>>>>>>>>>>>>>>>>>>>" EOL); + set_msg_dump_file(NULL); if (file != stderr) diff --git a/crawl-ref/source/mapmark.cc b/crawl-ref/source/mapmark.cc index 38fd93a997..b6137c3d2e 100644 --- a/crawl-ref/source/mapmark.cc +++ b/crawl-ref/source/mapmark.cc @@ -407,6 +407,25 @@ std::string map_lua_marker::property(const std::string &pname) const return (result); } +std::string map_lua_marker::debug_to_string() const +{ + lua_stack_cleaner cln(dlua); + + if (!get_table()) + return ("Unable to get table for lua marker."); + + if (!dlua.callfn("table_to_string", 1, 1)) + return make_stringf("error (table_to_string): %s", + dlua.error.c_str()); + + std::string result; + if (lua_isstring(dlua, -1)) + result = lua_tostring(dlua, -1); + else + result = "table_to_string() returned nothing"; + return (result); +} + map_marker *map_lua_marker::parse( const std::string &s, const std::string &ctx) throw (std::string) { diff --git a/crawl-ref/source/mapmark.h b/crawl-ref/source/mapmark.h index c21cb1e30c..8f01388d61 100644 --- a/crawl-ref/source/mapmark.h +++ b/crawl-ref/source/mapmark.h @@ -124,6 +124,8 @@ public: static map_marker *read(reader &, map_marker_type); static map_marker *parse(const std::string &s, const std::string &) throw (std::string); + + std::string debug_to_string() const; private: bool initialised; std::auto_ptr<lua_datum> marker_table; |