diff options
Diffstat (limited to 'tools')
| -rw-r--r-- | tools/guest-diag/bpz5.py | 67 | ||||
| -rwxr-xr-x | tools/guest-diag/push_guest_tools.sh | 1 |
2 files changed, 68 insertions, 0 deletions
diff --git a/tools/guest-diag/bpz5.py b/tools/guest-diag/bpz5.py new file mode 100644 index 0000000..568b2f2 --- /dev/null +++ b/tools/guest-diag/bpz5.py @@ -0,0 +1,67 @@ +# gdb script: identify WHICH engine-setup hook returns 999. +# +# Run #4 named the target: file 0x4d1fa0 (the +0x4580 table slot) — an engine +# setup function that callocs a 4-pointer array and calls each enabled hook in +# order: descriptors 0x440f780 (fn 0x4d9350), 0x440f7c0 (0x4c8a70), +# 0x440f800 (0x4ad980), 0x440f840 (0x4d7e70); the first non-zero return is +# propagated (it returned 0x3e7). This script breaks on the indirect call site +# (0x4d20fe) and its return (0x4d2101), printing the descriptor index, the +# call target and the status; the first non-zero status names the failing +# engine setup step and its callee. +# +# Run: sudo gdb -p <cdt-pid> -batch -x /tmp/bpz5.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") +for off in (0x4d20fe, 0x4d2101): + gdb.execute("break *0x%x" % (base + off)) + +t0 = time.time() +for hit in range(40): + try: + gdb.execute("continue") + except gdb.error as e: + print("CONTINUE_END %s" % e) + break + rip = int(gdb.parse_and_eval("$rip")) & 0xffffffffffffffff + off = rip - base + try: + r13 = int(gdb.parse_and_eval("$r13")) & 0xffffffffffffffff + r12 = int(gdb.parse_and_eval("$r12")) & 0xffffffffffffffff + idx = (r12 - r13) // 8 + except Exception: + idx = -1 + if off == 0x4d20fe: + rax = int(gdb.parse_and_eval("$rax")) & 0xffffffffffffffff + tgt = int(gdb.parse_and_eval("*(unsigned long *)0x%x" % (rax + 8))) + print("HIT %d t=%.3f CALL idx=%d desc=0x%x target=0x%x target_off=0x%x" % + (hit, time.time() - t0, idx, rax, tgt, tgt - base)) + else: + rax = int(gdb.parse_and_eval("$rax")) & 0xffffffffffffffff + print("HIT %d t=%.3f RET idx=%d eax=0x%x" % + (hit, time.time() - t0, idx, rax & 0xffffffff)) + if (rax & 0xffffffff) != 0: + print(" >>> HOOK FAILED idx=%d status=0x%x" % (idx, rax & 0xffffffff)) + try: + print(gdb.execute("bt 10", to_string=True)) + except Exception as e: + print("bt_fail %s" % e) + +try: + gdb.execute("detach") +except Exception: + pass diff --git a/tools/guest-diag/push_guest_tools.sh b/tools/guest-diag/push_guest_tools.sh index 38aa6e5..e4c1222 100755 --- a/tools/guest-diag/push_guest_tools.sh +++ b/tools/guest-diag/push_guest_tools.sh @@ -32,6 +32,7 @@ push_b64 "$HERE/bpz.py" /tmp/bpz.py push_b64 "$HERE/bpz2.py" /tmp/bpz2.py push_b64 "$HERE/bpz3.py" /tmp/bpz3.py push_b64 "$HERE/bpz4.py" /tmp/bpz4.py +push_b64 "$HERE/bpz5.py" /tmp/bpz5.py push_b64 "$HERE/bpwait.py" /tmp/bpwait.py push_b64 "$HERE/ctx999.py" /tmp/ctx999.py push_b64 "$HERE/scanerr.py" /tmp/scanerr.py |
