diff options
| author | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-09-30 01:25:44 -0400 |
|---|---|---|
| committer | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-09-30 01:25:44 -0400 |
| commit | 581047cb66ae744d212bf1673799ddf16a4d7897 (patch) | |
| tree | 6b12975b0f173fe215e6535489d41cea758793a9 /tools/guest-diag/bpz4.py | |
| parent | dec00519c198acf0d5f38955295b88f742b895ab (diff) | |
| download | open-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.py | 64 |
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 |
