summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tools/guest-diag/bpz5.py67
-rwxr-xr-xtools/guest-diag/push_guest_tools.sh1
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