# SPDX-License-Identifier: BSD-3-Clause # Copyright (c) 2026 Open-IOV contributors # gdb script: at the libcuda error-scanner entry (FUN_0054fa00), walk the # context list and dump every non-zero RM error record (magic words, # errorClass at +0x8, shorts at +0xc/+0xe). The scanner is called often with # a zeroed record; keep going until a hit has a non-zero record (that is the # one a forced 999 comes from) and print it with a backtrace. # Run: sudo gdb -p -batch -x /tmp/scanerr.py import gdb out = gdb.execute("info proc mappings", to_string=True) base = None for line in out.splitlines(): if "libcuda" in line and "r-xp" in line: f = line.split() base = int(f[0], 16) - int(f[3], 16) break print("BASE=0x%x" % (base or 0)) if base is None: raise SystemExit gdb.execute("set pagination off") gdb.execute("set confirm off") gdb.execute("break *0x%x" % (base + 0x44fa00)) def rd64(a): try: return int(gdb.parse_and_eval("*(unsigned long *)0x%x" % a)) & 0xffffffffffffffff except Exception: return None def rd32(a): try: return int(gdb.parse_and_eval("*(unsigned int *)0x%x" % a)) & 0xffffffff except Exception: return None for hit in range(400): try: gdb.execute("continue") except gdb.error as e: print("CONTINUE_END %s" % e) break try: p1 = int(gdb.parse_and_eval("$rdi")) & 0xffffffffffffffff p2 = int(gdb.parse_and_eval("$rsi")) & 0xffffffff except Exception: print("REGS_GONE") break pl = rd64(p1) n = 0 found = 0 while pl and n < 64: mgr = rd64(pl + 0x1291 * 8) if mgr: reg = rd64(mgr + 0x10) if reg: rec = rd64(reg + 0x10) if rec: vals = [rd32(rec + i) or 0 for i in range(0, 0x28, 4)] if any(vals): print("HIT %d param_2=%d ENTRY %d ctx=0x%x mgr=0x%x rec=0x%x rec=%s" % (hit, p2, n, pl, mgr, rec, ' '.join('0x%08x' % v for v in vals))) found = 1 pl = rd64(pl + 0x128e * 8) n += 1 if found: print("FOUND") try: print(gdb.execute("bt 12", to_string=True)) except Exception: pass break print("DONE") try: gdb.execute("detach") except Exception: pass