util/debug.lua
author Jonas Schäfer <jonas@wielicki.name>
Mon, 10 Jan 2022 18:23:54 +0100
branch0.11
changeset 12185 783056b4e448
parent 11181 37dc2a6144d1
child 12254 e157e5c79daa
permissions -rw-r--r--
util.xml: Do not allow doctypes, comments or processing instructions Yes. This is as bad as it sounds. CVE pending. In Prosody itself, this only affects mod_websocket, which uses util.xml to parse the <open/> frame, thus allowing unauthenticated remote DoS using Billion Laughs. However, third-party modules using util.xml may also be affected by this. This commit installs handlers which disallow the use of doctype declarations and processing instructions without any escape hatch. It, by default, also introduces such a handler for comments, however, there is a way to enable comments nontheless. This is because util.xml is used to parse human-facing data, where comments are generally a desirable feature, and also because comments are generally harmless.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
4412
5d7d9a60bc7f util.debug: Experimental new library for producing more extensive debug tracebacks
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     1
-- Variables ending with these names will not
5d7d9a60bc7f util.debug: Experimental new library for producing more extensive debug tracebacks
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     2
-- have their values printed ('password' includes
5d7d9a60bc7f util.debug: Experimental new library for producing more extensive debug tracebacks
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     3
-- 'new_password', etc.)
7185
858ccafbd823 util.debug: Silence luacheck warning about modifying 'debug' lib
Kim Alvefur <zash@zash.se>
parents: 6780
diff changeset
     4
--
858ccafbd823 util.debug: Silence luacheck warning about modifying 'debug' lib
Kim Alvefur <zash@zash.se>
parents: 6780
diff changeset
     5
-- luacheck: ignore 122/debug
858ccafbd823 util.debug: Silence luacheck warning about modifying 'debug' lib
Kim Alvefur <zash@zash.se>
parents: 6780
diff changeset
     6
4412
5d7d9a60bc7f util.debug: Experimental new library for producing more extensive debug tracebacks
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     7
local censored_names = {
5d7d9a60bc7f util.debug: Experimental new library for producing more extensive debug tracebacks
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     8
	password = true;
5d7d9a60bc7f util.debug: Experimental new library for producing more extensive debug tracebacks
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     9
	passwd = true;
5d7d9a60bc7f util.debug: Experimental new library for producing more extensive debug tracebacks
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    10
	pass = true;
5d7d9a60bc7f util.debug: Experimental new library for producing more extensive debug tracebacks
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    11
	pwd = true;
5d7d9a60bc7f util.debug: Experimental new library for producing more extensive debug tracebacks
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    12
};
4522
29f75c2af90e util.debug: Move optimal line length (default 65) into a variable
Matthew Wild <mwild1@gmail.com>
parents: 4521
diff changeset
    13
local optimal_line_length = 65;
4412
5d7d9a60bc7f util.debug: Experimental new library for producing more extensive debug tracebacks
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    14
4523
d733bde93074 util.debug: Add a bit of colour
Matthew Wild <mwild1@gmail.com>
parents: 4522
diff changeset
    15
local termcolours = require "util.termcolours";
d733bde93074 util.debug: Add a bit of colour
Matthew Wild <mwild1@gmail.com>
parents: 4522
diff changeset
    16
local getstring = termcolours.getstring;
d733bde93074 util.debug: Add a bit of colour
Matthew Wild <mwild1@gmail.com>
parents: 4522
diff changeset
    17
local styles;
d733bde93074 util.debug: Add a bit of colour
Matthew Wild <mwild1@gmail.com>
parents: 4522
diff changeset
    18
do
6780
5de6b93d0190 util.*: Remove use of module() function, make all module functions local and return them in a table at the end
Kim Alvefur <zash@zash.se>
parents: 5787
diff changeset
    19
	local _ = termcolours.getstyle;
4523
d733bde93074 util.debug: Add a bit of colour
Matthew Wild <mwild1@gmail.com>
parents: 4522
diff changeset
    20
	styles = {
4699
c66179261551 util.debug: Remove 'white' from boundary style (leave at default colour)
Matthew Wild <mwild1@gmail.com>
parents: 4693
diff changeset
    21
		boundary_padding = _("bright");
4523
d733bde93074 util.debug: Add a bit of colour
Matthew Wild <mwild1@gmail.com>
parents: 4522
diff changeset
    22
		filename         = _("bright", "blue");
d733bde93074 util.debug: Add a bit of colour
Matthew Wild <mwild1@gmail.com>
parents: 4522
diff changeset
    23
		level_num        = _("green");
d733bde93074 util.debug: Add a bit of colour
Matthew Wild <mwild1@gmail.com>
parents: 4522
diff changeset
    24
		funcname         = _("yellow");
4524
816c319a09d8 util.debug: Add a touch of colour to source locations
Matthew Wild <mwild1@gmail.com>
parents: 4523
diff changeset
    25
		location         = _("yellow");
4523
d733bde93074 util.debug: Add a bit of colour
Matthew Wild <mwild1@gmail.com>
parents: 4522
diff changeset
    26
	};
d733bde93074 util.debug: Add a bit of colour
Matthew Wild <mwild1@gmail.com>
parents: 4522
diff changeset
    27
end
4680
8834f220ab91 util.debug: Turn into a real-ish module ('debugx'), and require you call use() to override debug.traceback()
Matthew Wild <mwild1@gmail.com>
parents: 4465
diff changeset
    28
6780
5de6b93d0190 util.*: Remove use of module() function, make all module functions local and return them in a table at the end
Kim Alvefur <zash@zash.se>
parents: 5787
diff changeset
    29
local function get_locals_table(thread, level)
4412
5d7d9a60bc7f util.debug: Experimental new library for producing more extensive debug tracebacks
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    30
	local locals = {};
5d7d9a60bc7f util.debug: Experimental new library for producing more extensive debug tracebacks
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    31
	for local_num = 1, math.huge do
5787
9a22586f67eb util.debug: Fix level of locals when inspecting a coroutine
Matthew Wild <mwild1@gmail.com>
parents: 5786
diff changeset
    32
		local name, value;
9a22586f67eb util.debug: Fix level of locals when inspecting a coroutine
Matthew Wild <mwild1@gmail.com>
parents: 5786
diff changeset
    33
		if thread then
9a22586f67eb util.debug: Fix level of locals when inspecting a coroutine
Matthew Wild <mwild1@gmail.com>
parents: 5786
diff changeset
    34
			name, value = debug.getlocal(thread, level, local_num);
9a22586f67eb util.debug: Fix level of locals when inspecting a coroutine
Matthew Wild <mwild1@gmail.com>
parents: 5786
diff changeset
    35
		else
9a22586f67eb util.debug: Fix level of locals when inspecting a coroutine
Matthew Wild <mwild1@gmail.com>
parents: 5786
diff changeset
    36
			name, value = debug.getlocal(level+1, local_num);
9a22586f67eb util.debug: Fix level of locals when inspecting a coroutine
Matthew Wild <mwild1@gmail.com>
parents: 5786
diff changeset
    37
		end
4412
5d7d9a60bc7f util.debug: Experimental new library for producing more extensive debug tracebacks
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    38
		if not name then break; end
5d7d9a60bc7f util.debug: Experimental new library for producing more extensive debug tracebacks
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    39
		table.insert(locals, { name = name, value = value });
5d7d9a60bc7f util.debug: Experimental new library for producing more extensive debug tracebacks
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    40
	end
5d7d9a60bc7f util.debug: Experimental new library for producing more extensive debug tracebacks
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    41
	return locals;
5d7d9a60bc7f util.debug: Experimental new library for producing more extensive debug tracebacks
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    42
end
5d7d9a60bc7f util.debug: Experimental new library for producing more extensive debug tracebacks
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    43
6780
5de6b93d0190 util.*: Remove use of module() function, make all module functions local and return them in a table at the end
Kim Alvefur <zash@zash.se>
parents: 5787
diff changeset
    44
local function get_upvalues_table(func)
4412
5d7d9a60bc7f util.debug: Experimental new library for producing more extensive debug tracebacks
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    45
	local upvalues = {};
4418
70b5e533325d util.debug: Fix potential traceback
Matthew Wild <mwild1@gmail.com>
parents: 4412
diff changeset
    46
	if func then
70b5e533325d util.debug: Fix potential traceback
Matthew Wild <mwild1@gmail.com>
parents: 4412
diff changeset
    47
		for upvalue_num = 1, math.huge do
70b5e533325d util.debug: Fix potential traceback
Matthew Wild <mwild1@gmail.com>
parents: 4412
diff changeset
    48
			local name, value = debug.getupvalue(func, upvalue_num);
70b5e533325d util.debug: Fix potential traceback
Matthew Wild <mwild1@gmail.com>
parents: 4412
diff changeset
    49
			if not name then break; end
8325
cd15fc505b62 util.debug: Produce a sensible name for nameless upvalues to C functions
Kim Alvefur <zash@zash.se>
parents: 7185
diff changeset
    50
			if name == "" then name = ("[%d]"):format(upvalue_num); end
4418
70b5e533325d util.debug: Fix potential traceback
Matthew Wild <mwild1@gmail.com>
parents: 4412
diff changeset
    51
			table.insert(upvalues, { name = name, value = value });
70b5e533325d util.debug: Fix potential traceback
Matthew Wild <mwild1@gmail.com>
parents: 4412
diff changeset
    52
		end
4412
5d7d9a60bc7f util.debug: Experimental new library for producing more extensive debug tracebacks
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    53
	end
5d7d9a60bc7f util.debug: Experimental new library for producing more extensive debug tracebacks
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    54
	return upvalues;
5d7d9a60bc7f util.debug: Experimental new library for producing more extensive debug tracebacks
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    55
end
5d7d9a60bc7f util.debug: Experimental new library for producing more extensive debug tracebacks
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    56
6780
5de6b93d0190 util.*: Remove use of module() function, make all module functions local and return them in a table at the end
Kim Alvefur <zash@zash.se>
parents: 5787
diff changeset
    57
local function string_from_var_table(var_table, max_line_len, indent_str)
4412
5d7d9a60bc7f util.debug: Experimental new library for producing more extensive debug tracebacks
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    58
	local var_string = {};
5d7d9a60bc7f util.debug: Experimental new library for producing more extensive debug tracebacks
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    59
	local col_pos = 0;
5d7d9a60bc7f util.debug: Experimental new library for producing more extensive debug tracebacks
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    60
	max_line_len = max_line_len or math.huge;
5d7d9a60bc7f util.debug: Experimental new library for producing more extensive debug tracebacks
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    61
	indent_str = "\n"..(indent_str or "");
5d7d9a60bc7f util.debug: Experimental new library for producing more extensive debug tracebacks
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    62
	for _, var in ipairs(var_table) do
5d7d9a60bc7f util.debug: Experimental new library for producing more extensive debug tracebacks
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    63
		local name, value = var.name, var.value;
5d7d9a60bc7f util.debug: Experimental new library for producing more extensive debug tracebacks
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    64
		if name:sub(1,1) ~= "(" then
5d7d9a60bc7f util.debug: Experimental new library for producing more extensive debug tracebacks
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    65
			if type(value) == "string" then
5d7d9a60bc7f util.debug: Experimental new library for producing more extensive debug tracebacks
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    66
				if censored_names[name:match("%a+$")] then
5d7d9a60bc7f util.debug: Experimental new library for producing more extensive debug tracebacks
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    67
					value = "<hidden>";
5d7d9a60bc7f util.debug: Experimental new library for producing more extensive debug tracebacks
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    68
				else
5d7d9a60bc7f util.debug: Experimental new library for producing more extensive debug tracebacks
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    69
					value = ("%q"):format(value);
5d7d9a60bc7f util.debug: Experimental new library for producing more extensive debug tracebacks
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    70
				end
5d7d9a60bc7f util.debug: Experimental new library for producing more extensive debug tracebacks
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    71
			else
5d7d9a60bc7f util.debug: Experimental new library for producing more extensive debug tracebacks
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    72
				value = tostring(value);
5d7d9a60bc7f util.debug: Experimental new library for producing more extensive debug tracebacks
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    73
			end
5d7d9a60bc7f util.debug: Experimental new library for producing more extensive debug tracebacks
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    74
			if #value > max_line_len then
5d7d9a60bc7f util.debug: Experimental new library for producing more extensive debug tracebacks
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    75
				value = value:sub(1, max_line_len-3).."…";
5d7d9a60bc7f util.debug: Experimental new library for producing more extensive debug tracebacks
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    76
			end
5d7d9a60bc7f util.debug: Experimental new library for producing more extensive debug tracebacks
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    77
			local str = ("%s = %s"):format(name, tostring(value));
5d7d9a60bc7f util.debug: Experimental new library for producing more extensive debug tracebacks
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    78
			col_pos = col_pos + #str;
5d7d9a60bc7f util.debug: Experimental new library for producing more extensive debug tracebacks
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    79
			if col_pos > max_line_len then
5d7d9a60bc7f util.debug: Experimental new library for producing more extensive debug tracebacks
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    80
				table.insert(var_string, indent_str);
5d7d9a60bc7f util.debug: Experimental new library for producing more extensive debug tracebacks
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    81
				col_pos = 0;
5d7d9a60bc7f util.debug: Experimental new library for producing more extensive debug tracebacks
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    82
			end
5d7d9a60bc7f util.debug: Experimental new library for producing more extensive debug tracebacks
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    83
			table.insert(var_string, str);
5d7d9a60bc7f util.debug: Experimental new library for producing more extensive debug tracebacks
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    84
		end
5d7d9a60bc7f util.debug: Experimental new library for producing more extensive debug tracebacks
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    85
	end
5d7d9a60bc7f util.debug: Experimental new library for producing more extensive debug tracebacks
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    86
	if #var_string == 0 then
5d7d9a60bc7f util.debug: Experimental new library for producing more extensive debug tracebacks
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    87
		return nil;
5d7d9a60bc7f util.debug: Experimental new library for producing more extensive debug tracebacks
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    88
	else
5d7d9a60bc7f util.debug: Experimental new library for producing more extensive debug tracebacks
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    89
		return "{ "..table.concat(var_string, ", "):gsub(indent_str..", ", indent_str).." }";
5d7d9a60bc7f util.debug: Experimental new library for producing more extensive debug tracebacks
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    90
	end
5d7d9a60bc7f util.debug: Experimental new library for producing more extensive debug tracebacks
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    91
end
5d7d9a60bc7f util.debug: Experimental new library for producing more extensive debug tracebacks
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    92
6780
5de6b93d0190 util.*: Remove use of module() function, make all module functions local and return them in a table at the end
Kim Alvefur <zash@zash.se>
parents: 5787
diff changeset
    93
local function get_traceback_table(thread, start_level)
4412
5d7d9a60bc7f util.debug: Experimental new library for producing more extensive debug tracebacks
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    94
	local levels = {};
5d7d9a60bc7f util.debug: Experimental new library for producing more extensive debug tracebacks
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    95
	for level = start_level, math.huge do
5d7d9a60bc7f util.debug: Experimental new library for producing more extensive debug tracebacks
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    96
		local info;
5d7d9a60bc7f util.debug: Experimental new library for producing more extensive debug tracebacks
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    97
		if thread then
5785
b2d6c5f94aa5 util.debug: Fixes to make coroutine tracebacks work properly
Matthew Wild <mwild1@gmail.com>
parents: 5776
diff changeset
    98
			info = debug.getinfo(thread, level);
4412
5d7d9a60bc7f util.debug: Experimental new library for producing more extensive debug tracebacks
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    99
		else
4693
7ef4faa056fb util.debug: Some more magic constant fiddling. Don't ask me.
Matthew Wild <mwild1@gmail.com>
parents: 4684
diff changeset
   100
			info = debug.getinfo(level+1);
4412
5d7d9a60bc7f util.debug: Experimental new library for producing more extensive debug tracebacks
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   101
		end
5d7d9a60bc7f util.debug: Experimental new library for producing more extensive debug tracebacks
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   102
		if not info then break; end
5776
bd0ff8ae98a8 Remove all trailing whitespace
Florian Zeitz <florob@babelmonkeys.de>
parents: 4778
diff changeset
   103
4412
5d7d9a60bc7f util.debug: Experimental new library for producing more extensive debug tracebacks
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   104
		levels[(level-start_level)+1] = {
5d7d9a60bc7f util.debug: Experimental new library for producing more extensive debug tracebacks
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   105
			level = level;
5d7d9a60bc7f util.debug: Experimental new library for producing more extensive debug tracebacks
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   106
			info = info;
11181
37dc2a6144d1 util.debug: Fix locals being reported under wrong stack frame in some cases (+tests!!)
Matthew Wild <mwild1@gmail.com>
parents: 8385
diff changeset
   107
			locals = get_locals_table(thread, level+1);
4412
5d7d9a60bc7f util.debug: Experimental new library for producing more extensive debug tracebacks
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   108
			upvalues = get_upvalues_table(info.func);
5d7d9a60bc7f util.debug: Experimental new library for producing more extensive debug tracebacks
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   109
		};
5776
bd0ff8ae98a8 Remove all trailing whitespace
Florian Zeitz <florob@babelmonkeys.de>
parents: 4778
diff changeset
   110
	end
4412
5d7d9a60bc7f util.debug: Experimental new library for producing more extensive debug tracebacks
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   111
	return levels;
5d7d9a60bc7f util.debug: Experimental new library for producing more extensive debug tracebacks
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   112
end
5d7d9a60bc7f util.debug: Experimental new library for producing more extensive debug tracebacks
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   113
4523
d733bde93074 util.debug: Add a bit of colour
Matthew Wild <mwild1@gmail.com>
parents: 4522
diff changeset
   114
local function build_source_boundary_marker(last_source_desc)
d733bde93074 util.debug: Add a bit of colour
Matthew Wild <mwild1@gmail.com>
parents: 4522
diff changeset
   115
	local padding = string.rep("-", math.floor(((optimal_line_length - 6) - #last_source_desc)/2));
8385
e5d00bf4a4d5 util: Various minor changes to please [luacheck]
Kim Alvefur <zash@zash.se>
parents: 8325
diff changeset
   116
	return getstring(styles.boundary_padding, "v"..padding).." "..
e5d00bf4a4d5 util: Various minor changes to please [luacheck]
Kim Alvefur <zash@zash.se>
parents: 8325
diff changeset
   117
		getstring(styles.filename, last_source_desc).." "..
e5d00bf4a4d5 util: Various minor changes to please [luacheck]
Kim Alvefur <zash@zash.se>
parents: 8325
diff changeset
   118
		getstring(styles.boundary_padding, padding..(#last_source_desc%2==0 and "-v" or "v "));
4523
d733bde93074 util.debug: Add a bit of colour
Matthew Wild <mwild1@gmail.com>
parents: 4522
diff changeset
   119
end
d733bde93074 util.debug: Add a bit of colour
Matthew Wild <mwild1@gmail.com>
parents: 4522
diff changeset
   120
6780
5de6b93d0190 util.*: Remove use of module() function, make all module functions local and return them in a table at the end
Kim Alvefur <zash@zash.se>
parents: 5787
diff changeset
   121
local function _traceback(thread, message, level)
4684
dc70c4ffb66d Merge timber->trunk - thanks everyone!
Matthew Wild <mwild1@gmail.com>
parents: 4525 4680
diff changeset
   122
4777
74ae0433f8dd util.debug: Re-fix parameter handling (I think it matches debug.traceback() more accurately now) and document level fudge
Matthew Wild <mwild1@gmail.com>
parents: 4699
diff changeset
   123
	-- Lua manual says: debug.traceback ([thread,] [message [, level]])
74ae0433f8dd util.debug: Re-fix parameter handling (I think it matches debug.traceback() more accurately now) and document level fudge
Matthew Wild <mwild1@gmail.com>
parents: 4699
diff changeset
   124
	-- I fathom this to mean one of:
74ae0433f8dd util.debug: Re-fix parameter handling (I think it matches debug.traceback() more accurately now) and document level fudge
Matthew Wild <mwild1@gmail.com>
parents: 4699
diff changeset
   125
	-- ()
74ae0433f8dd util.debug: Re-fix parameter handling (I think it matches debug.traceback() more accurately now) and document level fudge
Matthew Wild <mwild1@gmail.com>
parents: 4699
diff changeset
   126
	-- (thread)
74ae0433f8dd util.debug: Re-fix parameter handling (I think it matches debug.traceback() more accurately now) and document level fudge
Matthew Wild <mwild1@gmail.com>
parents: 4699
diff changeset
   127
	-- (message, level)
74ae0433f8dd util.debug: Re-fix parameter handling (I think it matches debug.traceback() more accurately now) and document level fudge
Matthew Wild <mwild1@gmail.com>
parents: 4699
diff changeset
   128
	-- (thread, message, level)
74ae0433f8dd util.debug: Re-fix parameter handling (I think it matches debug.traceback() more accurately now) and document level fudge
Matthew Wild <mwild1@gmail.com>
parents: 4699
diff changeset
   129
74ae0433f8dd util.debug: Re-fix parameter handling (I think it matches debug.traceback() more accurately now) and document level fudge
Matthew Wild <mwild1@gmail.com>
parents: 4699
diff changeset
   130
	if thread == nil then -- Defaults
74ae0433f8dd util.debug: Re-fix parameter handling (I think it matches debug.traceback() more accurately now) and document level fudge
Matthew Wild <mwild1@gmail.com>
parents: 4699
diff changeset
   131
		thread, message, level = coroutine.running(), message, level;
74ae0433f8dd util.debug: Re-fix parameter handling (I think it matches debug.traceback() more accurately now) and document level fudge
Matthew Wild <mwild1@gmail.com>
parents: 4699
diff changeset
   132
	elseif type(thread) == "string" then
4412
5d7d9a60bc7f util.debug: Experimental new library for producing more extensive debug tracebacks
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   133
		thread, message, level = coroutine.running(), thread, message;
4777
74ae0433f8dd util.debug: Re-fix parameter handling (I think it matches debug.traceback() more accurately now) and document level fudge
Matthew Wild <mwild1@gmail.com>
parents: 4699
diff changeset
   134
	elseif type(thread) ~= "thread" then
74ae0433f8dd util.debug: Re-fix parameter handling (I think it matches debug.traceback() more accurately now) and document level fudge
Matthew Wild <mwild1@gmail.com>
parents: 4699
diff changeset
   135
		return nil; -- debug.traceback() does this
4412
5d7d9a60bc7f util.debug: Experimental new library for producing more extensive debug tracebacks
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   136
	end
4777
74ae0433f8dd util.debug: Re-fix parameter handling (I think it matches debug.traceback() more accurately now) and document level fudge
Matthew Wild <mwild1@gmail.com>
parents: 4699
diff changeset
   137
5785
b2d6c5f94aa5 util.debug: Fixes to make coroutine tracebacks work properly
Matthew Wild <mwild1@gmail.com>
parents: 5776
diff changeset
   138
	level = level or 0;
4777
74ae0433f8dd util.debug: Re-fix parameter handling (I think it matches debug.traceback() more accurately now) and document level fudge
Matthew Wild <mwild1@gmail.com>
parents: 4699
diff changeset
   139
4412
5d7d9a60bc7f util.debug: Experimental new library for producing more extensive debug tracebacks
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   140
	message = message and (message.."\n") or "";
5776
bd0ff8ae98a8 Remove all trailing whitespace
Florian Zeitz <florob@babelmonkeys.de>
parents: 4778
diff changeset
   141
5785
b2d6c5f94aa5 util.debug: Fixes to make coroutine tracebacks work properly
Matthew Wild <mwild1@gmail.com>
parents: 5776
diff changeset
   142
	-- +3 counts for this function, and the pcall() and wrapper above us, the +1... I don't know.
b2d6c5f94aa5 util.debug: Fixes to make coroutine tracebacks work properly
Matthew Wild <mwild1@gmail.com>
parents: 5776
diff changeset
   143
	local levels = get_traceback_table(thread, level+(thread == nil and 4 or 0));
5776
bd0ff8ae98a8 Remove all trailing whitespace
Florian Zeitz <florob@babelmonkeys.de>
parents: 4778
diff changeset
   144
4521
4c7495f7f543 util.debug: Add markers in the output when crossing source file boundaries
Matthew Wild <mwild1@gmail.com>
parents: 4520
diff changeset
   145
	local last_source_desc;
5776
bd0ff8ae98a8 Remove all trailing whitespace
Florian Zeitz <florob@babelmonkeys.de>
parents: 4778
diff changeset
   146
4412
5d7d9a60bc7f util.debug: Experimental new library for producing more extensive debug tracebacks
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   147
	local lines = {};
8385
e5d00bf4a4d5 util: Various minor changes to please [luacheck]
Kim Alvefur <zash@zash.se>
parents: 8325
diff changeset
   148
	for nlevel, current_level in ipairs(levels) do
e5d00bf4a4d5 util: Various minor changes to please [luacheck]
Kim Alvefur <zash@zash.se>
parents: 8325
diff changeset
   149
		local info = current_level.info;
e5d00bf4a4d5 util: Various minor changes to please [luacheck]
Kim Alvefur <zash@zash.se>
parents: 8325
diff changeset
   150
		local line;
4412
5d7d9a60bc7f util.debug: Experimental new library for producing more extensive debug tracebacks
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   151
		local func_type = info.namewhat.." ";
4521
4c7495f7f543 util.debug: Add markers in the output when crossing source file boundaries
Matthew Wild <mwild1@gmail.com>
parents: 4520
diff changeset
   152
		local source_desc = (info.short_src == "[C]" and "C code") or info.short_src or "Unknown";
4412
5d7d9a60bc7f util.debug: Experimental new library for producing more extensive debug tracebacks
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   153
		if func_type == " " then func_type = ""; end;
5d7d9a60bc7f util.debug: Experimental new library for producing more extensive debug tracebacks
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   154
		if info.short_src == "[C]" then
4524
816c319a09d8 util.debug: Add a touch of colour to source locations
Matthew Wild <mwild1@gmail.com>
parents: 4523
diff changeset
   155
			line = "[ C ] "..func_type.."C function "..getstring(styles.location, (info.name and ("%q"):format(info.name) or "(unknown name)"));
4412
5d7d9a60bc7f util.debug: Experimental new library for producing more extensive debug tracebacks
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   156
		elseif info.what == "main" then
4524
816c319a09d8 util.debug: Add a touch of colour to source locations
Matthew Wild <mwild1@gmail.com>
parents: 4523
diff changeset
   157
			line = "[Lua] "..getstring(styles.location, info.short_src.." line "..info.currentline);
4412
5d7d9a60bc7f util.debug: Experimental new library for producing more extensive debug tracebacks
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   158
		else
5d7d9a60bc7f util.debug: Experimental new library for producing more extensive debug tracebacks
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   159
			local name = info.name or " ";
5d7d9a60bc7f util.debug: Experimental new library for producing more extensive debug tracebacks
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   160
			if name ~= " " then
5d7d9a60bc7f util.debug: Experimental new library for producing more extensive debug tracebacks
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   161
				name = ("%q"):format(name);
5d7d9a60bc7f util.debug: Experimental new library for producing more extensive debug tracebacks
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   162
			end
5d7d9a60bc7f util.debug: Experimental new library for producing more extensive debug tracebacks
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   163
			if func_type == "global " or func_type == "local " then
5d7d9a60bc7f util.debug: Experimental new library for producing more extensive debug tracebacks
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   164
				func_type = func_type.."function ";
5d7d9a60bc7f util.debug: Experimental new library for producing more extensive debug tracebacks
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   165
			end
8385
e5d00bf4a4d5 util: Various minor changes to please [luacheck]
Kim Alvefur <zash@zash.se>
parents: 8325
diff changeset
   166
			line = "[Lua] "..getstring(styles.location, info.short_src.." line "..
e5d00bf4a4d5 util: Various minor changes to please [luacheck]
Kim Alvefur <zash@zash.se>
parents: 8325
diff changeset
   167
				info.currentline).." in "..func_type..getstring(styles.funcname, name)..
e5d00bf4a4d5 util: Various minor changes to please [luacheck]
Kim Alvefur <zash@zash.se>
parents: 8325
diff changeset
   168
				" (defined on line "..info.linedefined..")";
4412
5d7d9a60bc7f util.debug: Experimental new library for producing more extensive debug tracebacks
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   169
		end
4521
4c7495f7f543 util.debug: Add markers in the output when crossing source file boundaries
Matthew Wild <mwild1@gmail.com>
parents: 4520
diff changeset
   170
		if source_desc ~= last_source_desc then -- Venturing into a new source, add marker for previous
4c7495f7f543 util.debug: Add markers in the output when crossing source file boundaries
Matthew Wild <mwild1@gmail.com>
parents: 4520
diff changeset
   171
			last_source_desc = source_desc;
4525
e00b4ec5fca4 util.debug: Move boundary markers to top of relevant sections of the stack trace (easier to follow)
Matthew Wild <mwild1@gmail.com>
parents: 4524
diff changeset
   172
			table.insert(lines, "\t "..build_source_boundary_marker(last_source_desc));
4412
5d7d9a60bc7f util.debug: Experimental new library for producing more extensive debug tracebacks
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   173
		end
5d7d9a60bc7f util.debug: Experimental new library for producing more extensive debug tracebacks
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   174
		nlevel = nlevel-1;
4523
d733bde93074 util.debug: Add a bit of colour
Matthew Wild <mwild1@gmail.com>
parents: 4522
diff changeset
   175
		table.insert(lines, "\t"..(nlevel==0 and ">" or " ")..getstring(styles.level_num, "("..nlevel..") ")..line);
4412
5d7d9a60bc7f util.debug: Experimental new library for producing more extensive debug tracebacks
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   176
		local npadding = (" "):rep(#tostring(nlevel));
8385
e5d00bf4a4d5 util: Various minor changes to please [luacheck]
Kim Alvefur <zash@zash.se>
parents: 8325
diff changeset
   177
		if current_level.locals then
e5d00bf4a4d5 util: Various minor changes to please [luacheck]
Kim Alvefur <zash@zash.se>
parents: 8325
diff changeset
   178
			local locals_str = string_from_var_table(current_level.locals, optimal_line_length, "\t            "..npadding);
5785
b2d6c5f94aa5 util.debug: Fixes to make coroutine tracebacks work properly
Matthew Wild <mwild1@gmail.com>
parents: 5776
diff changeset
   179
			if locals_str then
b2d6c5f94aa5 util.debug: Fixes to make coroutine tracebacks work properly
Matthew Wild <mwild1@gmail.com>
parents: 5776
diff changeset
   180
				table.insert(lines, "\t    "..npadding.."Locals: "..locals_str);
b2d6c5f94aa5 util.debug: Fixes to make coroutine tracebacks work properly
Matthew Wild <mwild1@gmail.com>
parents: 5776
diff changeset
   181
			end
4412
5d7d9a60bc7f util.debug: Experimental new library for producing more extensive debug tracebacks
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   182
		end
8385
e5d00bf4a4d5 util: Various minor changes to please [luacheck]
Kim Alvefur <zash@zash.se>
parents: 8325
diff changeset
   183
		local upvalues_str = string_from_var_table(current_level.upvalues, optimal_line_length, "\t            "..npadding);
4412
5d7d9a60bc7f util.debug: Experimental new library for producing more extensive debug tracebacks
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   184
		if upvalues_str then
5d7d9a60bc7f util.debug: Experimental new library for producing more extensive debug tracebacks
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   185
			table.insert(lines, "\t    "..npadding.."Upvals: "..upvalues_str);
5d7d9a60bc7f util.debug: Experimental new library for producing more extensive debug tracebacks
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   186
		end
5d7d9a60bc7f util.debug: Experimental new library for producing more extensive debug tracebacks
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   187
	end
4521
4c7495f7f543 util.debug: Add markers in the output when crossing source file boundaries
Matthew Wild <mwild1@gmail.com>
parents: 4520
diff changeset
   188
4525
e00b4ec5fca4 util.debug: Move boundary markers to top of relevant sections of the stack trace (easier to follow)
Matthew Wild <mwild1@gmail.com>
parents: 4524
diff changeset
   189
--	table.insert(lines, "\t "..build_source_boundary_marker(last_source_desc));
4521
4c7495f7f543 util.debug: Add markers in the output when crossing source file boundaries
Matthew Wild <mwild1@gmail.com>
parents: 4520
diff changeset
   190
4412
5d7d9a60bc7f util.debug: Experimental new library for producing more extensive debug tracebacks
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   191
	return message.."stack traceback:\n"..table.concat(lines, "\n");
5d7d9a60bc7f util.debug: Experimental new library for producing more extensive debug tracebacks
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   192
end
4680
8834f220ab91 util.debug: Turn into a real-ish module ('debugx'), and require you call use() to override debug.traceback()
Matthew Wild <mwild1@gmail.com>
parents: 4465
diff changeset
   193
6780
5de6b93d0190 util.*: Remove use of module() function, make all module functions local and return them in a table at the end
Kim Alvefur <zash@zash.se>
parents: 5787
diff changeset
   194
local function traceback(...)
5de6b93d0190 util.*: Remove use of module() function, make all module functions local and return them in a table at the end
Kim Alvefur <zash@zash.se>
parents: 5787
diff changeset
   195
	local ok, ret = pcall(_traceback, ...);
5de6b93d0190 util.*: Remove use of module() function, make all module functions local and return them in a table at the end
Kim Alvefur <zash@zash.se>
parents: 5787
diff changeset
   196
	if not ok then
5de6b93d0190 util.*: Remove use of module() function, make all module functions local and return them in a table at the end
Kim Alvefur <zash@zash.se>
parents: 5787
diff changeset
   197
		return "Error in error handling: "..ret;
5de6b93d0190 util.*: Remove use of module() function, make all module functions local and return them in a table at the end
Kim Alvefur <zash@zash.se>
parents: 5787
diff changeset
   198
	end
5de6b93d0190 util.*: Remove use of module() function, make all module functions local and return them in a table at the end
Kim Alvefur <zash@zash.se>
parents: 5787
diff changeset
   199
	return ret;
5de6b93d0190 util.*: Remove use of module() function, make all module functions local and return them in a table at the end
Kim Alvefur <zash@zash.se>
parents: 5787
diff changeset
   200
end
5de6b93d0190 util.*: Remove use of module() function, make all module functions local and return them in a table at the end
Kim Alvefur <zash@zash.se>
parents: 5787
diff changeset
   201
5de6b93d0190 util.*: Remove use of module() function, make all module functions local and return them in a table at the end
Kim Alvefur <zash@zash.se>
parents: 5787
diff changeset
   202
local function use()
4680
8834f220ab91 util.debug: Turn into a real-ish module ('debugx'), and require you call use() to override debug.traceback()
Matthew Wild <mwild1@gmail.com>
parents: 4465
diff changeset
   203
	debug.traceback = traceback;
8834f220ab91 util.debug: Turn into a real-ish module ('debugx'), and require you call use() to override debug.traceback()
Matthew Wild <mwild1@gmail.com>
parents: 4465
diff changeset
   204
end
8834f220ab91 util.debug: Turn into a real-ish module ('debugx'), and require you call use() to override debug.traceback()
Matthew Wild <mwild1@gmail.com>
parents: 4465
diff changeset
   205
6780
5de6b93d0190 util.*: Remove use of module() function, make all module functions local and return them in a table at the end
Kim Alvefur <zash@zash.se>
parents: 5787
diff changeset
   206
return {
5de6b93d0190 util.*: Remove use of module() function, make all module functions local and return them in a table at the end
Kim Alvefur <zash@zash.se>
parents: 5787
diff changeset
   207
	get_locals_table = get_locals_table;
5de6b93d0190 util.*: Remove use of module() function, make all module functions local and return them in a table at the end
Kim Alvefur <zash@zash.se>
parents: 5787
diff changeset
   208
	get_upvalues_table = get_upvalues_table;
5de6b93d0190 util.*: Remove use of module() function, make all module functions local and return them in a table at the end
Kim Alvefur <zash@zash.se>
parents: 5787
diff changeset
   209
	string_from_var_table = string_from_var_table;
5de6b93d0190 util.*: Remove use of module() function, make all module functions local and return them in a table at the end
Kim Alvefur <zash@zash.se>
parents: 5787
diff changeset
   210
	get_traceback_table = get_traceback_table;
5de6b93d0190 util.*: Remove use of module() function, make all module functions local and return them in a table at the end
Kim Alvefur <zash@zash.se>
parents: 5787
diff changeset
   211
	traceback = traceback;
5de6b93d0190 util.*: Remove use of module() function, make all module functions local and return them in a table at the end
Kim Alvefur <zash@zash.se>
parents: 5787
diff changeset
   212
	use = use;
5de6b93d0190 util.*: Remove use of module() function, make all module functions local and return them in a table at the end
Kim Alvefur <zash@zash.se>
parents: 5787
diff changeset
   213
};