diff options
| author | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-09-30 03:34:33 -0400 |
|---|---|---|
| committer | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-09-30 03:34:33 -0400 |
| commit | f913d5dcb624a55ec40166052a632e07edee8d10 (patch) | |
| tree | 0d6b5c0941fcec7519ef7e402d2c6560df496e06 /tools | |
| parent | 5963df083aa668adec541ffbbe4432fab7281bdb (diff) | |
| download | open-iov-f913d5dcb624a55ec40166052a632e07edee8d10.tar.gz open-iov-f913d5dcb624a55ec40166052a632e07edee8d10.zip | |
guest-diag: bpz20 - watchpoint on ds+0xe94 to catch the zeroing write
Diffstat (limited to 'tools')
| -rw-r--r-- | tools/guest-diag/bpz20.py | 78 | ||||
| -rwxr-xr-x | tools/guest-diag/push_guest_tools.sh | 1 |
2 files changed, 79 insertions, 0 deletions
diff --git a/tools/guest-diag/bpz20.py b/tools/guest-diag/bpz20.py new file mode 100644 index 0000000..cf8ee8c --- /dev/null +++ b/tools/guest-diag/bpz20.py @@ -0,0 +1,78 @@ +# gdb script: catch the write that ZEROES ds+0xe94 after the CASE1 body set +# it to 0x18. Run via run_cycle.sh gdb-launch (device init happens during +# cuInit, before the CDT_PAUSE). +# +# bpz18 showed: CASE1 (0x32e8be) hit at t=0.24; at FUN_003e3e80 (t=72.9) +# ds+0xe94 == 0. Set a hardware watchpoint at the CASE1 hit and log every +# write with a backtrace. +import gdb +import time + +gdb.execute("set pagination off") +gdb.execute("set confirm off") +gdb.execute("set environment CDT_PAUSE=60") +gdb.execute("set environment CDT_HOLD=900") +gdb.execute("catch load libcuda.so") +gdb.execute("run") +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: + raise SystemExit + +CASE1 = base + 0x32e8be +TERM = base + 0x2e3e80 +CALLER_RET = base + 0xd0eae1 +gdb.execute("break *0x%x" % CASE1) +gdb.execute("break *0x%x" % TERM) + +def rd(addr, n=4, fmt="unsigned int"): + try: + return int(gdb.parse_and_eval("*(%s*)0x%x" % (fmt, addr))) & ((1 << (8 * n)) - 1) + except Exception: + return None + +t0 = time.time() +watched = False +for hit in range(200): + try: + gdb.execute("continue") + except gdb.error as e: + print("CONTINUE_END %s" % e) + break + rip = int(gdb.parse_and_eval("$rip")) & 0xffffffffffffffff + if rip == CASE1 and not watched: + rc = int(gdb.parse_and_eval("$rcx")) & 0xffffffffffffffff + gdb.execute("delete 1") + gdb.execute("set $wpaddr = 0x%x" % (rc + 0xe94)) + gdb.execute("watch *(int*)$wpaddr") + watched = True + print("WATCH set on ds=0x%x +0xe94 (t=%.3f)" % (rc, time.time() - t0)) + continue + if rip == TERM: + ret = rd(int(gdb.parse_and_eval("$rsp")), 8, "unsigned long") + if ret != CALLER_RET: + continue + rdi = int(gdb.parse_and_eval("$rdi")) & 0xffffffffffffffff + ds = rd(rdi + 0x40, 8, "unsigned long") + print("TERMINATOR t=%.3f ds=0x%x e94=0x%x c4c=0x%x" % + (time.time() - t0, ds or 0, rd(ds + 0xe94) or 0, rd(ds + 0xc4c) or 0)) + break + # watchpoint hit + addr = int(gdb.parse_and_eval("$wpaddr")) & 0xffffffffffffffff + val = rd(addr) or 0 + print("WP hit t=%.3f pc=+0x%x val=0x%x" % (time.time() - t0, rip - base, val)) + try: + print(gdb.execute("bt 6", to_string=True)) + except Exception: + pass + +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 9014144..ad1f310 100755 --- a/tools/guest-diag/push_guest_tools.sh +++ b/tools/guest-diag/push_guest_tools.sh @@ -44,6 +44,7 @@ push_b64 "$HERE/bpz13.py" /tmp/bpz13.py push_b64 "$HERE/bpz14.py" /tmp/bpz14.py push_b64 "$HERE/bpz16.py" /tmp/bpz16.py push_b64 "$HERE/bpz18.py" /tmp/bpz18.py +push_b64 "$HERE/bpz20.py" /tmp/bpz20.py push_b64 "$HERE/bpz19.py" /tmp/bpz19.py push_b64 "$HERE/invd.py" /tmp/invd.py push_b64 "$HERE/bpwait.py" /tmp/bpwait.py |
