Debugging improvements
This commit is contained in:
parent
247e10e20c
commit
12bbefc034
@ -3,6 +3,7 @@
|
||||
extern char lua_boot[];
|
||||
extern char lua_component[];
|
||||
extern char lua_computer[];
|
||||
extern char lua_debug[];
|
||||
extern char lua_eeprom[];
|
||||
extern char lua_filesystem[];
|
||||
extern char lua_init[];
|
||||
|
@ -62,10 +62,20 @@ void logm(const char *message) {
|
||||
fclose(file);
|
||||
}
|
||||
}
|
||||
|
||||
static int l_log (lua_State *L) {
|
||||
const char* t = lua_tostring(L, 1);
|
||||
logn(t);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
#define logn(m)
|
||||
#define logi(m)
|
||||
#define logm(m)
|
||||
static int l_log (lua_State *L) {
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int l_sleep (lua_State *L) {
|
||||
@ -370,6 +380,7 @@ void luanative_start(lua_State *L) {
|
||||
lua_createtable (L, 0, 1);
|
||||
|
||||
pushctuple(L, "sleep", l_sleep);
|
||||
pushctuple(L, "log", l_log);
|
||||
|
||||
pushctuple(L, "fs_exists", l_fs_exists);
|
||||
pushctuple(L, "fs_mkdir", l_fs_mkdir);
|
||||
@ -397,5 +408,11 @@ void luanative_start(lua_State *L) {
|
||||
pushctuple(L, "freeMemory", l_freeMemory);
|
||||
pushctuple(L, "pull", l_pull);
|
||||
|
||||
#ifdef DEBUG
|
||||
lua_pushstring(L, "debug");
|
||||
lua_pushboolean(L, 1);
|
||||
lua_settable(L, -3);
|
||||
#endif
|
||||
|
||||
lua_setglobal(L, "native");
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ void setup_modules(lua_State *L) {
|
||||
pushstuple(L, "color", lua_util_color);
|
||||
pushstuple(L, "component", lua_component);
|
||||
pushstuple(L, "computer", lua_computer);
|
||||
pushstuple(L, "debug", lua_debug);
|
||||
pushstuple(L, "eeprom", lua_eeprom);
|
||||
pushstuple(L, "filesystem", lua_filesystem);
|
||||
pushstuple(L, "internet", lua_internet);
|
||||
|
@ -5,20 +5,29 @@ function boot.boot()
|
||||
local w, h = gpu.getResolution()
|
||||
|
||||
local function bsod(...)
|
||||
gpu.setBackground(0x0000FF)
|
||||
gpu.setForeground(0xFFFFFF)
|
||||
gpu.fill(1, 1, w, h, " ")
|
||||
gpu.set(2, 2, "CRITICAL ERROR OCCURED")
|
||||
gpu.set(2, 3, "Lua BIOS has failed:")
|
||||
for n, v in pairs({...}) do
|
||||
gpu.set(2, 4 + n, tostring(v))
|
||||
end
|
||||
gpu.set(2, h-1, "SYSTEM WILL STOP")
|
||||
gpu.setForeground(0xFFFFFF)
|
||||
gpu.setBackground(0x000000)
|
||||
local arg = {...}
|
||||
pcall(function()
|
||||
native.log("> LuPI BSOD")
|
||||
for n, v in pairs(arg) do
|
||||
native.log(tostring(v))
|
||||
end
|
||||
end)
|
||||
pcall(function()
|
||||
gpu.setBackground(0x0000FF)
|
||||
gpu.setForeground(0xFFFFFF)
|
||||
gpu.fill(1, 1, w, h, " ")
|
||||
gpu.set(2, 2, "CRITICAL ERROR OCCURED")
|
||||
gpu.set(2, 3, "Lua BIOS has failed:")
|
||||
for n, v in pairs(arg) do
|
||||
gpu.set(2, 4 + n, tostring(v))
|
||||
end
|
||||
gpu.set(2, h-1, "SYSTEM WILL STOP")
|
||||
gpu.setForeground(0xFFFFFF)
|
||||
gpu.setBackground(0x000000)
|
||||
|
||||
native.sleep(4000000)
|
||||
os.exit(1)
|
||||
native.sleep(4000000)
|
||||
os.exit(1)
|
||||
end)
|
||||
end
|
||||
|
||||
gpu.fill(1, 1, w, h, " ")
|
||||
@ -31,6 +40,7 @@ function boot.boot()
|
||||
if not f then
|
||||
bsod(reason)
|
||||
else
|
||||
local crash = false
|
||||
xpcall(f, function(e)
|
||||
local trace = {}
|
||||
|
||||
@ -38,9 +48,11 @@ function boot.boot()
|
||||
trace[#trace + 1] = s
|
||||
end
|
||||
bsod("System crashed", "Stack traceback:", table.unpack(trace))
|
||||
os.exit(4) --TODO: Run exit hooks
|
||||
crash = true
|
||||
end)
|
||||
bsod("System quit")
|
||||
if not crash then
|
||||
bsod("System quit")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -10,6 +10,29 @@ local componentCallback = {
|
||||
__tostring = function(self) return (components[self.address] ~= nil and components[self.address].doc[self.name] ~= nil) and components[self.address].doc[self.name] or "function" end
|
||||
}
|
||||
|
||||
if native.debug then
|
||||
local start = native.uptime()
|
||||
local last = native.uptime()
|
||||
componentCallback.__call = function(self, ...)
|
||||
local t = {}
|
||||
for k,v in pairs({...}) do
|
||||
if type(v) == "string" then
|
||||
v = "\"" .. v .. "\""
|
||||
end
|
||||
t[k] = tostring(v)
|
||||
end
|
||||
|
||||
local caller = debug.getinfo(2)
|
||||
local msg = tostring((native.uptime() - start) / 1000) .. " [+" .. native.uptime() - last .. "] " .. caller.short_src .. ":".. caller.currentline .. " > invoke(" .. self.address .. "): "
|
||||
.. components[self.address].type .. "." .. self.name
|
||||
.. "(" .. table.concat(t, ", ") .. ")"
|
||||
|
||||
native.log(msg)
|
||||
last = native.uptime()
|
||||
return components[self.address].rawproxy[self.name](...)
|
||||
end
|
||||
end
|
||||
|
||||
function component.prepare()
|
||||
print("Assembling initial component tree")
|
||||
end
|
||||
|
@ -118,12 +118,17 @@ function api.pushSignal(s, ...)
|
||||
end
|
||||
|
||||
function api.pullSignal(timeout)
|
||||
if signalQueue[1] then return table.unpack(table.remove(signalQueue, 1)) end
|
||||
--native.log("pullSignal for " .. (timeout or " infinite") .. " s")
|
||||
if signalQueue[1] then
|
||||
native.log("pullSignal direct: " .. signalQueue[1][1])
|
||||
return table.unpack(table.remove(signalQueue, 1))
|
||||
end
|
||||
local timeoutuptime = math.huge
|
||||
|
||||
if not timeout then
|
||||
timeout = -1
|
||||
else
|
||||
if timeout < 0 then timeout = 0 end
|
||||
timeout = timeout * 1000
|
||||
timeoutuptime = native.uptime() + timeout
|
||||
end
|
||||
@ -131,7 +136,11 @@ function api.pullSignal(timeout)
|
||||
repeat
|
||||
nevts = native.pull(timeout)
|
||||
until nevts > 0 or native.uptime() > timeoutuptime
|
||||
if signalQueue[1] then return table.unpack(table.remove(signalQueue, 1)) end
|
||||
if signalQueue[1] then
|
||||
native.log("pullSignal native: " .. signalQueue[1][1])
|
||||
return table.unpack(table.remove(signalQueue, 1))
|
||||
end
|
||||
--native.log("pullSignal timeout")
|
||||
end
|
||||
|
||||
function api.uptime()
|
||||
@ -158,6 +167,17 @@ function api.totalMemory()
|
||||
end
|
||||
|
||||
function api.shutdown()
|
||||
--TODO: Longjmp to init somehow?
|
||||
print("Running shutdown hooks")
|
||||
for k, hook in ipairs(deadhooks) do
|
||||
local state, cause = pcall(hook)
|
||||
if not state then
|
||||
print("Shutdown hook with following error:")
|
||||
print(cause)
|
||||
end
|
||||
end
|
||||
print("Hooks executed: " .. #deadhooks)
|
||||
|
||||
os.exit(0)
|
||||
end
|
||||
|
||||
|
26
src/lua/core/debug.lua
Normal file
26
src/lua/core/debug.lua
Normal file
@ -0,0 +1,26 @@
|
||||
local d = {}
|
||||
|
||||
local function getCallerInfo()
|
||||
local caller = debug.getinfo(3)
|
||||
return caller.short_src .. ":".. caller.currentline
|
||||
end
|
||||
|
||||
function d.hook()
|
||||
local sb = modules.sandbox
|
||||
|
||||
local otb = sb.debug.traceback
|
||||
function sb.debug.traceback(m, l, ...)
|
||||
local s = otb(m, l and (type(l) == "number" and (l + 1) or l) or 2, ...)
|
||||
native.log("Native traceback requested for:")
|
||||
native.log(s)
|
||||
return s --TODO: check if there actually is only one return value
|
||||
end
|
||||
|
||||
local oload = sb.load
|
||||
function sb.load(ld, source, mode, env)
|
||||
native.log("load from " .. getCallerInfo() .. ", loading \"" .. (source or type(ld)) .. "\"")
|
||||
return oload(ld, source, mode, env)
|
||||
end
|
||||
end
|
||||
|
||||
return d
|
@ -17,12 +17,17 @@ end
|
||||
-------------------------------------------------------------------------------
|
||||
math.randomseed(native.uptime())--TODO: Make it better?
|
||||
|
||||
print("LuPI L1 INIT")
|
||||
lprint = function (...)
|
||||
print(...)
|
||||
native.log(table.concat({...}, " "))
|
||||
end
|
||||
|
||||
lprint("LuPI L1 INIT")
|
||||
modules = {}
|
||||
deadhooks = {}
|
||||
|
||||
local function loadModule(name)
|
||||
print("LuPI L1 INIT > Load module > " .. name)
|
||||
lprint("LuPI L1 INIT > Load module > " .. name)
|
||||
io.flush()
|
||||
--TODO: PRERELEASE: Module sandboxing, preferably secure-ish
|
||||
--TODO: ASAP: Handle load errors
|
||||
@ -31,7 +36,7 @@ local function loadModule(name)
|
||||
end
|
||||
local code, reason = load(moduleCode[name], "=Module "..name)
|
||||
if not code then
|
||||
print("Failed loading module " .. name .. ": " .. reason)
|
||||
lprint("Failed loading module " .. name .. ": " .. reason)
|
||||
io.flush()
|
||||
else
|
||||
modules[name] = code()
|
||||
@ -41,6 +46,9 @@ end
|
||||
function main()
|
||||
--Load modules
|
||||
--Utils
|
||||
if native.debug then
|
||||
loadModule("debug")
|
||||
end
|
||||
loadModule("random")
|
||||
loadModule("color")
|
||||
loadModule("buffer")
|
||||
@ -73,20 +81,30 @@ function main()
|
||||
modules.computer.tmp = modules.filesystem.register("/tmp/lupi-" .. modules.random.uuid())
|
||||
modules.textgpu.start()
|
||||
|
||||
if native.debug then
|
||||
modules.debug.hook()
|
||||
end
|
||||
|
||||
modules.boot.boot()
|
||||
end
|
||||
|
||||
local state, cause = pcall(main)
|
||||
if not state then
|
||||
print("LuPI finished with following error:")
|
||||
print(cause)
|
||||
end
|
||||
local tb = ""
|
||||
|
||||
print("Running shutdown hooks")
|
||||
local state, cause = xpcall(main, function(e)
|
||||
tb = debug.traceback(e, 2)
|
||||
end)
|
||||
|
||||
lprint("Running shutdown hooks")
|
||||
for k, hook in ipairs(deadhooks) do
|
||||
local state, cause = pcall(hook)
|
||||
if not state then
|
||||
print("Shutdown hook with following error:")
|
||||
print(cause)
|
||||
lprint("Shutdown hook with following error:")
|
||||
lprint(cause)
|
||||
end
|
||||
end
|
||||
lprint("Hooks executed: " .. #deadhooks)
|
||||
|
||||
if not state then
|
||||
lprint("LuPI finished with following error:")
|
||||
lprint(tb)
|
||||
end
|
@ -241,7 +241,6 @@ sandbox = {
|
||||
end,
|
||||
},
|
||||
checkArg = checkArg,
|
||||
og = _G
|
||||
}
|
||||
|
||||
sandbox._G = sandbox
|
||||
|
Loading…
Reference in New Issue
Block a user