diff options
Diffstat (limited to 'tools/guest-diag/bpz2.py')
| -rw-r--r-- | tools/guest-diag/bpz2.py | 80 |
1 files changed, 80 insertions, 0 deletions
diff --git a/tools/guest-diag/bpz2.py b/tools/guest-diag/bpz2.py new file mode 100644 index 0000000..2d399ff --- /dev/null +++ b/tools/guest-diag/bpz2.py @@ -0,0 +1,80 @@ +# gdb script: capture the post-pump failure call in FUN_00374240 (ctx init). +# +# From the previous run: the engine event pump FUN_0031a3b0 returned 0 +# (0x2231ab) and the four known 999 stores did NOT fire, so the rc=999 comes +# from a call AFTER the pump on the setup path. Every one of those calls in +# FUN_00374240 stores its status into r14d and jumps to 0x274680 on failure, +# and the function returns r14d at 0x27428a. Break at each store site and at +# the final return; print the status and a backtrace when it is non-zero. +# +# Run: sudo gdb -p <cdt-pid> -batch -x /tmp/bpz2.py +import gdb +import time + +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: + print("NO_LIBCUDA") + raise SystemExit + +gdb.execute("set pagination off") +gdb.execute("set confirm off") + +SITES = [ + (0x2231ab, "AFTER_PUMP"), + (0x2233f7, "TAIL_SCAN"), + (0x27537d, "RET_CTXENG"), + (0x27539d, "RET_A4090"), + (0x2753da, "RET_35fb00"), + (0x275444, "RET_a5c50"), + (0x275474, "RET_ENG60"), + (0x27549d, "RET_ENG68"), + (0x2754c6, "RET_ENG70"), + (0x2754f6, "RET_ENG78"), + (0x275541, "RET_ENGLOOP"), + (0x27558c, "RET_ENG2f8"), + (0x2755bf, "RET_ENG300"), + (0x27428a, "CTX_RET"), + (0x277840, "CTXREF999"), + (0x44fb80, "SCAN999"), + (0x44fb6c, "SCAN2cf"), +] +for off, name in SITES: + gdb.execute("break *0x%x" % (base + off)) + +t0 = time.time() +for hit in range(200): + try: + gdb.execute("continue") + except gdb.error as e: + print("CONTINUE_END %s" % e) + break + try: + rip = int(gdb.parse_and_eval("$rip")) & 0xffffffffffffffff + rax = int(gdb.parse_and_eval("$rax")) & 0xffffffffffffffff + r14 = int(gdb.parse_and_eval("$r14")) & 0xffffffffffffffff + except Exception as e: + print("REGS_GONE %s" % e) + break + off = rip - base + name = dict(SITES).get(off, "?") + st = rax & 0xffffffff + print("HIT %d t=%.3f off=0x%x %s rax=0x%x r14d=0x%x" % + (hit, time.time() - t0, off, name, rax, r14 & 0xffffffff)) + if st != 0 or off in (0x27428a, 0x277840, 0x44fb80, 0x44fb6c): + print(" >>> NONZERO/TERMINAL %s status=0x%x" % (name, st)) + try: + print(gdb.execute("bt 12", to_string=True)) + except Exception as e: + print("bt_fail %s" % e) + +try: + gdb.execute("detach") +except Exception: + pass |
