summaryrefslogtreecommitdiffstats
path: root/crawl-ref
diff options
context:
space:
mode:
authorzelgadis <zelgadis@c06c8d41-db1a-0410-9941-cceddc491573>2009-01-28 16:23:06 +0000
committerzelgadis <zelgadis@c06c8d41-db1a-0410-9941-cceddc491573>2009-01-28 16:23:06 +0000
commit0371e07ab64fc457f74a6640f06a5b439038ceee (patch)
treedda15773f5bce673944f1a61f578c22f0c70cdb6 /crawl-ref
parentfec3e431ad8d5c47c29a20c4dc81820f867fda23 (diff)
downloadcrawl-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.lua7
-rw-r--r--crawl-ref/source/dat/clua/util.lua26
-rw-r--r--crawl-ref/source/debug.cc164
-rw-r--r--crawl-ref/source/mapmark.cc19
-rw-r--r--crawl-ref/source/mapmark.h2
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;