From 32d876ded1aefc52f839d65570e3e3c43ec04415 Mon Sep 17 00:00:00 2001 From: Takoroka <137927095+Takoroka@users.noreply.github.com> Date: Wed, 28 Oct 2026 07:47:45 -0400 Subject: nx2: read debug switches once; key scripts from a file Several debug switches were read with std::getenv on every macro call, QMD, semaphore write or draw. The UCRT getenv locks and scans the environment, thousands of times a frame; a long EDEN_NX2_KEY_SCRIPT made title 4 crawl at 2 fps. Each is now read once. EDEN_NX2_KEY_SCRIPT=@ reads the script from a file. gdbrsp.py gains 'hits' (log registers, frame chain and object words at breakpoints, following the stopped thread). --- tools/nx2/gdbrsp.py | 43 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/nx2/gdbrsp.py b/tools/nx2/gdbrsp.py index 51968254fa..f7e70c8fbe 100644 --- a/tools/nx2/gdbrsp.py +++ b/tools/nx2/gdbrsp.py @@ -15,7 +15,7 @@ class Rsp: import time for _ in range(240): # wait up to ~2 min for the stub to listen try: - self.s = socket.create_connection(("127.0.0.1", port), timeout=600) + self.s = socket.create_connection(("127.0.0.1", port), timeout=3600) break except OSError: time.sleep(0.5) @@ -139,6 +139,47 @@ def main(): prev = pc if pc == stop_at: break + elif op == "hits": + # hits ...: break at the addresses and, on each hit, print the registers, + # the frame-pointer chain and the 0x40 bytes at x0, then step past and continue. + # Stops after hits or when the target stops anywhere else. + limit, addrs = int(parts[1]), [int(a, 16) for a in parts[2:]] + for a in addrs: + rsp.cmd(f"Z0,{a:x},4") + for hit in range(limit): + reason = rsp.cmd("c") + # Several threads can stop at once: read and step the one this reply names. + tid = re.search(r"thread:([0-9a-f]+);", reason) + if tid: + rsp.cmd(f"Hg{tid.group(1)}") + r = rsp.regs() + pc = r.get("pc", 0) + stamp = time.strftime("%H:%M:%S") + label = (f"hit {hit}" if pc in addrs else f"stopped elsewhere ({reason})") + (f" thread {tid.group(1)}" if tid else "") + print(f"[{stamp}] {label} pc={pc:#x} " + " ".join( + f"{k}={r.get(k, 0):#x}" for k in ("x0", "x1", "x2", "x19", "x20", "x21", "x30", "sp")), flush=True) + obj = rsp.mem(r.get("x0", 0), 0x40) + if len(obj) == 0x40: + print(" *x0: " + " ".join(f"{w:016x}" for w in struct.unpack("<8Q", obj)), flush=True) + fp = r.get("x29", 0) + chain = [] + for _ in range(16): + d = rsp.mem(fp, 16) + if len(d) < 16: + break + nfp, ret = struct.unpack("