mirror of
https://github.com/bryanthaboi/gen1recomp.git
synced 2026-08-12 08:21:02 +02:00
feat(debug): log Lua errors and document NX crash triage
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -237,3 +237,24 @@ Implementation: `src/core/GamepadMap.lua` (`NX_RAW_*`, `ignoreRawForJoystick`).
|
||||
|
||||
**Suspend/resume audio:** after resume, chip music is stopped to avoid duplicate streams; confirm on hardware during P0-09/10 (T19).
|
||||
|
||||
## Lua error log (save directory)
|
||||
|
||||
On any uncaught Lua error, Gen1Recomp appends a redacted trace to `lua-error.log` in the LÖVE save directory (`love.filesystem.getSaveDirectory()`). The on-screen error overlay includes a hint pointing at that file. Logs rotate to `lua-error.log.1` when the active file exceeds 32 KiB. ROM/save bytes and non-printable data are stripped — never commit or share logs that might contain private paths without reviewing them first.
|
||||
|
||||
## Native crash triage (love-nx / Atmosphère)
|
||||
|
||||
love-nx native faults land under the console’s `crash_reports/` folder on SD (reachable via the same MTP workflow as game deploys).
|
||||
|
||||
1. **Collect** — DBI → `Run MTP responder`; copy `sdmc:/crash_reports/*.bin` (or the dated subfolder) to the Mac. Do **not** remove the microSD card.
|
||||
2. **Redact** — delete any attached screenshots or notes that mention ROM filenames, save paths, or private hashes before sharing logs publicly.
|
||||
3. **Symbolize** — use the **pinned** `love.elf` from `.bazinga/love-nx/11.5-nx1/` that matches `build-info.json` / `scripts/switch/love-nx-11.5-nx1.sha256`. Never use a “latest” download.
|
||||
|
||||
```bash
|
||||
# Example: aarch64-none-elf-addr2line from devkitPro
|
||||
aarch64-none-elf-addr2line -e .bazinga/love-nx/11.5-nx1/love.elf -f -C 0xADDRESS_FROM_CRASH_REPORT
|
||||
```
|
||||
|
||||
4. **Correlate** — compare `gitCommit` / `loveNxTag` from embedded `build-info.json` with the operator’s hardware notes.
|
||||
|
||||
If `addr2line` cannot resolve an address, archive the crash `.bin` with the exact `love.elf` SHA-256 used for the build — addresses are only meaningful against that ELF.
|
||||
|
||||
|
||||
@@ -12,6 +12,20 @@ local editorMode = os.getenv("POKEPORT_EDITOR") == "1" or POKEPORT_EDITOR_MODE =
|
||||
|
||||
local SwitchDiagnostics = require("src.debug.SwitchDiagnostics")
|
||||
|
||||
-- Lua errors: persist a redacted trace in the save dir and surface a hint.
|
||||
do
|
||||
local defaultErrorHandler = love.errorhandler
|
||||
function love.errorhandler(msg)
|
||||
local hint = SwitchDiagnostics.logLuaError(msg)
|
||||
if hint and type(msg) == "string" then
|
||||
msg = msg .. "\n\n" .. hint
|
||||
end
|
||||
if defaultErrorHandler then
|
||||
return defaultErrorHandler(msg)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local Game, EditorApp, Importer, TouchEditor
|
||||
|
||||
local autopilot -- optional scripted-input dev tool (tests/autopilot.lua)
|
||||
|
||||
@@ -70,7 +70,7 @@ verify_love() {
|
||||
run_self_test() {
|
||||
local work clean bad staging
|
||||
work="$(mktemp -d "${TMPDIR:-/tmp}/verify-payload.XXXXXX")"
|
||||
trap 'rm -rf "$work"' EXIT
|
||||
trap "rm -rf '$work'" EXIT
|
||||
|
||||
clean="$work/clean.love"
|
||||
"$ROOT/scripts/pack_love.sh" --output "$clean" --listing "$work/clean-listing.txt" >/dev/null
|
||||
|
||||
@@ -5,6 +5,9 @@ local SwitchDiagnostics = {}
|
||||
|
||||
local MARKER = "switch-debug.txt"
|
||||
local LOG_FILE = "switch.log"
|
||||
local ERROR_LOG = "lua-error.log"
|
||||
local ERROR_LOG_ROTATED = "lua-error.log.1"
|
||||
local ERROR_LOG_MAX = 32 * 1024
|
||||
local FLUSH_INTERVAL = 1.0
|
||||
local RING_SIZE = 64
|
||||
|
||||
@@ -65,6 +68,11 @@ function SwitchDiagnostics._resetForTests()
|
||||
bufCount = 0
|
||||
lastFlushAt = -math.huge
|
||||
identityLine = nil
|
||||
local filesystem = fs()
|
||||
if filesystem then
|
||||
filesystem.remove(ERROR_LOG)
|
||||
filesystem.remove(ERROR_LOG_ROTATED)
|
||||
end
|
||||
end
|
||||
|
||||
function SwitchDiagnostics.isEnabled()
|
||||
@@ -122,6 +130,24 @@ function SwitchDiagnostics.onJoystickEvent(kind, joystick, button, extra)
|
||||
SwitchDiagnostics.onEvent(kind, payload)
|
||||
end
|
||||
|
||||
function SwitchDiagnostics.logLuaError(msg)
|
||||
local filesystem = fs()
|
||||
if not filesystem then return nil end
|
||||
|
||||
local text = redactString(tostring(msg or "unknown error"))
|
||||
local existing = filesystem.read(ERROR_LOG) or ""
|
||||
if #existing > ERROR_LOG_MAX then
|
||||
filesystem.write(ERROR_LOG_ROTATED, existing)
|
||||
existing = ""
|
||||
end
|
||||
|
||||
local stamp = os.date("!%Y-%m-%dT%H:%M:%SZ")
|
||||
local line = ("[%s] %s\n"):format(stamp, text)
|
||||
filesystem.write(ERROR_LOG, existing .. line .. SwitchDiagnostics.identityOverlay() .. "\n")
|
||||
|
||||
return "Details saved to lua-error.log in the save directory."
|
||||
end
|
||||
|
||||
function SwitchDiagnostics.maybeFlush(force, now)
|
||||
if not SwitchDiagnostics.isEnabled() then return end
|
||||
now = now or (love and love.timer and love.timer.getTime() or 0)
|
||||
|
||||
@@ -50,4 +50,15 @@ local logLate = love.filesystem.read("switch.log") or ""
|
||||
check(not logMid:find("n=2", 1, true), "flush waits until 1s elapsed")
|
||||
check(logLate:find("n=2", 1, true) ~= nil, "flush includes events after 1s")
|
||||
|
||||
-- Lua error log: redacted, no ROM bytes.
|
||||
local romErr = string.char(0xEA, 0x9B, 0xCA, 0xE6)
|
||||
local hint = SwitchDiagnostics.logLuaError("probe failure")
|
||||
check(type(hint) == "string" and hint:find("lua-error.log", 1, true) ~= nil,
|
||||
"error handler hint mentions lua-error.log")
|
||||
SwitchDiagnostics.logLuaError(romErr)
|
||||
local errLog = love.filesystem.read("lua-error.log") or ""
|
||||
check(errLog:find("probe failure", 1, true) ~= nil, "lua-error.log records message")
|
||||
check(errLog:find("<redacted>", 1, true) ~= nil, "lua-error.log strips ROM bytes")
|
||||
check(not errLog:find(romErr, 1, true), "lua-error.log omits raw ROM bytes")
|
||||
|
||||
T.finish()
|
||||
|
||||
Reference in New Issue
Block a user