Debugging improvements
This commit is contained in:
parent
247e10e20c
commit
12bbefc034
@ -3,6 +3,7 @@
|
|||||||
extern char lua_boot[];
|
extern char lua_boot[];
|
||||||
extern char lua_component[];
|
extern char lua_component[];
|
||||||
extern char lua_computer[];
|
extern char lua_computer[];
|
||||||
|
extern char lua_debug[];
|
||||||
extern char lua_eeprom[];
|
extern char lua_eeprom[];
|
||||||
extern char lua_filesystem[];
|
extern char lua_filesystem[];
|
||||||
extern char lua_init[];
|
extern char lua_init[];
|
||||||
|
@ -62,10 +62,20 @@ void logm(const char *message) {
|
|||||||
fclose(file);
|
fclose(file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int l_log (lua_State *L) {
|
||||||
|
const char* t = lua_tostring(L, 1);
|
||||||
|
logn(t);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#define logn(m)
|
#define logn(m)
|
||||||
#define logi(m)
|
#define logi(m)
|
||||||
#define logm(m)
|
#define logm(m)
|
||||||
|
static int l_log (lua_State *L) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int l_sleep (lua_State *L) {
|
static int l_sleep (lua_State *L) {
|
||||||
@ -370,6 +380,7 @@ void luanative_start(lua_State *L) {
|
|||||||
lua_createtable (L, 0, 1);
|
lua_createtable (L, 0, 1);
|
||||||
|
|
||||||
pushctuple(L, "sleep", l_sleep);
|
pushctuple(L, "sleep", l_sleep);
|
||||||
|
pushctuple(L, "log", l_log);
|
||||||
|
|
||||||
pushctuple(L, "fs_exists", l_fs_exists);
|
pushctuple(L, "fs_exists", l_fs_exists);
|
||||||
pushctuple(L, "fs_mkdir", l_fs_mkdir);
|
pushctuple(L, "fs_mkdir", l_fs_mkdir);
|
||||||
@ -397,5 +408,11 @@ void luanative_start(lua_State *L) {
|
|||||||
pushctuple(L, "freeMemory", l_freeMemory);
|
pushctuple(L, "freeMemory", l_freeMemory);
|
||||||
pushctuple(L, "pull", l_pull);
|
pushctuple(L, "pull", l_pull);
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
lua_pushstring(L, "debug");
|
||||||
|
lua_pushboolean(L, 1);
|
||||||
|
lua_settable(L, -3);
|
||||||
|
#endif
|
||||||
|
|
||||||
lua_setglobal(L, "native");
|
lua_setglobal(L, "native");
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,7 @@ void setup_modules(lua_State *L) {
|
|||||||
pushstuple(L, "color", lua_util_color);
|
pushstuple(L, "color", lua_util_color);
|
||||||
pushstuple(L, "component", lua_component);
|
pushstuple(L, "component", lua_component);
|
||||||
pushstuple(L, "computer", lua_computer);
|
pushstuple(L, "computer", lua_computer);
|
||||||
|
pushstuple(L, "debug", lua_debug);
|
||||||
pushstuple(L, "eeprom", lua_eeprom);
|
pushstuple(L, "eeprom", lua_eeprom);
|
||||||
pushstuple(L, "filesystem", lua_filesystem);
|
pushstuple(L, "filesystem", lua_filesystem);
|
||||||
pushstuple(L, "internet", lua_internet);
|
pushstuple(L, "internet", lua_internet);
|
||||||
|
@ -5,12 +5,20 @@ function boot.boot()
|
|||||||
local w, h = gpu.getResolution()
|
local w, h = gpu.getResolution()
|
||||||
|
|
||||||
local function bsod(...)
|
local function bsod(...)
|
||||||
|
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.setBackground(0x0000FF)
|
||||||
gpu.setForeground(0xFFFFFF)
|
gpu.setForeground(0xFFFFFF)
|
||||||
gpu.fill(1, 1, w, h, " ")
|
gpu.fill(1, 1, w, h, " ")
|
||||||
gpu.set(2, 2, "CRITICAL ERROR OCCURED")
|
gpu.set(2, 2, "CRITICAL ERROR OCCURED")
|
||||||
gpu.set(2, 3, "Lua BIOS has failed:")
|
gpu.set(2, 3, "Lua BIOS has failed:")
|
||||||
for n, v in pairs({...}) do
|
for n, v in pairs(arg) do
|
||||||
gpu.set(2, 4 + n, tostring(v))
|
gpu.set(2, 4 + n, tostring(v))
|
||||||
end
|
end
|
||||||
gpu.set(2, h-1, "SYSTEM WILL STOP")
|
gpu.set(2, h-1, "SYSTEM WILL STOP")
|
||||||
@ -19,6 +27,7 @@ function boot.boot()
|
|||||||
|
|
||||||
native.sleep(4000000)
|
native.sleep(4000000)
|
||||||
os.exit(1)
|
os.exit(1)
|
||||||
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
gpu.fill(1, 1, w, h, " ")
|
gpu.fill(1, 1, w, h, " ")
|
||||||
@ -31,6 +40,7 @@ function boot.boot()
|
|||||||
if not f then
|
if not f then
|
||||||
bsod(reason)
|
bsod(reason)
|
||||||
else
|
else
|
||||||
|
local crash = false
|
||||||
xpcall(f, function(e)
|
xpcall(f, function(e)
|
||||||
local trace = {}
|
local trace = {}
|
||||||
|
|
||||||
@ -38,10 +48,12 @@ function boot.boot()
|
|||||||
trace[#trace + 1] = s
|
trace[#trace + 1] = s
|
||||||
end
|
end
|
||||||
bsod("System crashed", "Stack traceback:", table.unpack(trace))
|
bsod("System crashed", "Stack traceback:", table.unpack(trace))
|
||||||
os.exit(4) --TODO: Run exit hooks
|
crash = true
|
||||||
end)
|
end)
|
||||||
|
if not crash then
|
||||||
bsod("System quit")
|
bsod("System quit")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
return boot
|
return boot
|
||||||
|
@ -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
|
__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()
|
function component.prepare()
|
||||||
print("Assembling initial component tree")
|
print("Assembling initial component tree")
|
||||||
end
|
end
|
||||||
|
@ -118,12 +118,17 @@ function api.pushSignal(s, ...)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function api.pullSignal(timeout)
|
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
|
local timeoutuptime = math.huge
|
||||||
|
|
||||||
if not timeout then
|
if not timeout then
|
||||||
timeout = -1
|
timeout = -1
|
||||||
else
|
else
|
||||||
|
if timeout < 0 then timeout = 0 end
|
||||||
timeout = timeout * 1000
|
timeout = timeout * 1000
|
||||||
timeoutuptime = native.uptime() + timeout
|
timeoutuptime = native.uptime() + timeout
|
||||||
end
|
end
|
||||||
@ -131,7 +136,11 @@ function api.pullSignal(timeout)
|
|||||||
repeat
|
repeat
|
||||||
nevts = native.pull(timeout)
|
nevts = native.pull(timeout)
|
||||||
until nevts > 0 or native.uptime() > timeoutuptime
|
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
|
end
|
||||||
|
|
||||||
function api.uptime()
|
function api.uptime()
|
||||||
@ -158,6 +167,17 @@ function api.totalMemory()
|
|||||||
end
|
end
|
||||||
|
|
||||||
function api.shutdown()
|
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)
|
os.exit(0)
|
||||||
end
|
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?
|
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 = {}
|
modules = {}
|
||||||
deadhooks = {}
|
deadhooks = {}
|
||||||
|
|
||||||
local function loadModule(name)
|
local function loadModule(name)
|
||||||
print("LuPI L1 INIT > Load module > " .. name)
|
lprint("LuPI L1 INIT > Load module > " .. name)
|
||||||
io.flush()
|
io.flush()
|
||||||
--TODO: PRERELEASE: Module sandboxing, preferably secure-ish
|
--TODO: PRERELEASE: Module sandboxing, preferably secure-ish
|
||||||
--TODO: ASAP: Handle load errors
|
--TODO: ASAP: Handle load errors
|
||||||
@ -31,7 +36,7 @@ local function loadModule(name)
|
|||||||
end
|
end
|
||||||
local code, reason = load(moduleCode[name], "=Module "..name)
|
local code, reason = load(moduleCode[name], "=Module "..name)
|
||||||
if not code then
|
if not code then
|
||||||
print("Failed loading module " .. name .. ": " .. reason)
|
lprint("Failed loading module " .. name .. ": " .. reason)
|
||||||
io.flush()
|
io.flush()
|
||||||
else
|
else
|
||||||
modules[name] = code()
|
modules[name] = code()
|
||||||
@ -41,6 +46,9 @@ end
|
|||||||
function main()
|
function main()
|
||||||
--Load modules
|
--Load modules
|
||||||
--Utils
|
--Utils
|
||||||
|
if native.debug then
|
||||||
|
loadModule("debug")
|
||||||
|
end
|
||||||
loadModule("random")
|
loadModule("random")
|
||||||
loadModule("color")
|
loadModule("color")
|
||||||
loadModule("buffer")
|
loadModule("buffer")
|
||||||
@ -73,20 +81,30 @@ function main()
|
|||||||
modules.computer.tmp = modules.filesystem.register("/tmp/lupi-" .. modules.random.uuid())
|
modules.computer.tmp = modules.filesystem.register("/tmp/lupi-" .. modules.random.uuid())
|
||||||
modules.textgpu.start()
|
modules.textgpu.start()
|
||||||
|
|
||||||
|
if native.debug then
|
||||||
|
modules.debug.hook()
|
||||||
|
end
|
||||||
|
|
||||||
modules.boot.boot()
|
modules.boot.boot()
|
||||||
end
|
end
|
||||||
|
|
||||||
local state, cause = pcall(main)
|
local tb = ""
|
||||||
if not state then
|
|
||||||
print("LuPI finished with following error:")
|
|
||||||
print(cause)
|
|
||||||
end
|
|
||||||
|
|
||||||
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
|
for k, hook in ipairs(deadhooks) do
|
||||||
local state, cause = pcall(hook)
|
local state, cause = pcall(hook)
|
||||||
if not state then
|
if not state then
|
||||||
print("Shutdown hook with following error:")
|
lprint("Shutdown hook with following error:")
|
||||||
print(cause)
|
lprint(cause)
|
||||||
end
|
end
|
||||||
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,
|
end,
|
||||||
},
|
},
|
||||||
checkArg = checkArg,
|
checkArg = checkArg,
|
||||||
og = _G
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sandbox._G = sandbox
|
sandbox._G = sandbox
|
||||||
|
Loading…
Reference in New Issue
Block a user