summaryrefslogtreecommitdiffstats
path: root/tools/guest-diag/bpz4.py
diff options
context:
space:
mode:
authorArthur Hanson Rasmusson <arthur@vgpu.io>2026-09-30 01:25:44 -0400
committerArthur Hanson Rasmusson <arthur@vgpu.io>2026-09-30 01:25:44 -0400
commit581047cb66ae744d212bf1673799ddf16a4d7897 (patch)
tree6b12975b0f173fe215e6535489d41cea758793a9 /tools/guest-diag/bpz4.py
parentdec00519c198acf0d5f38955295b88f742b895ab (diff)
downloadopen-iov-581047cb66ae744d212bf1673799ddf16a4d7897.tar.gz
open-iov-581047cb66ae744d212bf1673799ddf16a4d7897.zip
guest-diag: bpz4 - identify the vtable slot+0x4580 that returns 999
Run #3 named the failing store: file 0x275cec, the indirect call at 0x275ce6 (slot +0x4580 of the table at [ctx+0x40], called with (ctx, obj+0xb8)) returned 0x3e7. bpz4 prints the runtime target pointer so it maps to the architecture vtable implementation that failed.
Diffstat (limited to 'tools/guest-diag/bpz4.py')
-rw-r--r--tools/guest-diag/bpz4.py64
1 files changed, 64 insertions, 0 deletions
diff --git a/tools/guest-diag/bpz4.py b/tools/guest-diag/bpz4.py
new file mode 100644
index 0000000..eca9618
--- /dev/null
+++ b/tools/guest-diag/bpz4.py
@@ -0,0 +1,64 @@
+# gdb script: identify the vtable slot that returns 999 in ctx bring-up.
+#
+# Run #3 found the failing store at file 0x275cec: the indirect call at
+# 0x275ce6, slot +0x4580 of the table at [ctx+0x40], called with
+# (ctx, r15+0xb8), returned 0x3e7. The table slot is installed by one of the
+# architecture vtable installers; this script prints the runtime target so it
+# can be mapped to its decompiled body, plus the call arguments.
+#
+# Run: sudo gdb -p <cdt-pid> -batch -x /tmp/bpz4.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 (0x275ce6, 0x275cec):
+ gdb.execute("break *0x%x" % (base + off))
+
+t0 = time.time()
+for hit in range(20):
+ 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
+ print("HIT %d t=%.3f off=0x%x" % (hit, time.time() - t0, off))
+ try:
+ r12 = int(gdb.parse_and_eval("$r12")) & 0xffffffffffffffff
+ r15 = int(gdb.parse_and_eval("$r15")) & 0xffffffffffffffff
+ vec = int(gdb.parse_and_eval("*(unsigned long *)0x%x" % (r12 + 0x40)))
+ tgt = int(gdb.parse_and_eval("*(unsigned long *)0x%x" % (vec + 0x4580)))
+ print(" r12=0x%x r15=0x%x vec=0x%x TARGET=0x%x target_off=0x%x" %
+ (r12, r15, vec, tgt, tgt - base))
+ print(" r15+0xb8 words: " + gdb.execute(
+ "x/8gx 0x%x" % (r15 + 0xb8), to_string=True).strip())
+ except Exception as e:
+ print(" deref_fail %s" % e)
+ if off == 0x275cec:
+ try:
+ print(" call returned eax=0x%x" % (int(gdb.parse_and_eval("$rax")) & 0xffffffff))
+ except Exception:
+ pass
+ try:
+ print(gdb.execute("bt 8", to_string=True))
+ except Exception as e:
+ print("bt_fail %s" % e)
+
+try:
+ gdb.execute("detach")
+except Exception:
+ pass