# 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). This names the source of a # forced 999: the scanner returns 999 when param_2 != 0 and any record's # class fields are non-zero. # 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)) try: gdb.execute("continue") except gdb.error as e: print("CONTINUE %s" % e) print("HIT") 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 try: p1 = int(gdb.parse_and_eval("$rdi")) & 0xffffffffffffffff p2 = int(gdb.parse_and_eval("$rsi")) & 0xffffffff print("param_1=0x%x param_2=%d" % (p1, p2)) pl = rd64(p1) n = 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("ENTRY %d ctx=0x%x mgr=0x%x rec=0x%x rec=%s" % (n, pl, mgr, rec, ' '.join('0x%08x' % v for v in vals))) pl = rd64(pl + 0x128e * 8) n += 1 print("WALKED %d" % n) except Exception as e: print("dump_fail %s" % e) try: gdb.execute("bt 8", to_string=True) except Exception: pass try: gdb.execute("detach") except Exception: pass