diff options
Diffstat (limited to 'tools/guest-diag/bpwait.py')
| -rw-r--r-- | tools/guest-diag/bpwait.py | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/tools/guest-diag/bpwait.py b/tools/guest-diag/bpwait.py new file mode 100644 index 0000000..9b708c8 --- /dev/null +++ b/tools/guest-diag/bpwait.py @@ -0,0 +1,74 @@ +# gdb script: catch the tracker-gate exit with a NONZERO dispatcher status and +# dump the wait-entry array the gate polls. This names the wait that ends the +# client's context-init spin (the value that becomes the CUDA error). +# +# Site (libcuda+0x23f9e7): the gate loops +# call 0xd50e50 ; wait dispatcher +# 0x23f9ec: mov %eax,%edx +# 0x23f9ee: test %eax,%eax +# 0x23f9f0: je 0x23f9c0 ; still pending -> poll again +# 0x23f9f2: mov %edx,%eax ; <- nonzero status: gate exits with it +# Entry object: { *(void**)rsi; u32 count @+0x10; void *array @+0x18 } +# Array entries are 0x28 bytes: type @+0x0, then type-specific fields. +# Run: sudo gdb -p <cdt-pid> -batch -x /tmp/bpwait.py +import gdb + +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 + +gdb.execute("set pagination off") +gdb.execute("set confirm off") +gdb.execute("break *0x%x" % (base + 0x23f9f2)) +try: + gdb.execute("continue") +except gdb.error as e: + print("CONTINUE_ERR %s" % e) +print("STOPPED") + + +def rd64(a): + try: + return int(gdb.parse_and_eval("*(unsigned long *)0x%x" % a)) & 0xffffffffffffffff + except Exception: + return None + + +def rd32(a): + try: + return int(gdb.parse_and_eval("*(unsigned int *)0x%x" % a)) & 0xffffffff + except Exception: + return None + + +try: + rip = int(gdb.parse_and_eval("$rip")) & 0xffffffffffffffff + edx = int(gdb.parse_and_eval("$edx")) & 0xffffffff + rsi = int(gdb.parse_and_eval("$rsi")) & 0xffffffffffffffff + print("RIP=0x%x off=0x%x status(edx)=0x%x" % (rip, rip - base, edx)) + print(gdb.execute("bt 16", to_string=True)) + ent = rd64(rsi) + cnt = rd32(rsi + 0x10) + arr = rd64(rsi + 0x18) + print("entry_obj=0x%x count=0x%x array=0x%x" % (ent or 0, cnt or 0, arr or 0)) + if ent and arr: + print("entity hdr: " + " ".join("+0x%x=0x%x" % (o, rd32(ent + o) or 0) + for o in (0, 4, 8, 0xc, 0x10, 0x14, 0x18, 0x1c))) + if arr and cnt and cnt < 64: + for i in range(cnt): + e = arr + i * 0x28 + words = [rd32(e + o) or 0 for o in (0, 4, 8, 0xc, 0x10, 0x14, 0x18, 0x1c, 0x20, 0x24)] + print("entry[%d] " % i + " ".join("0x%08x" % w for w in words)) +except Exception as e: + print("dump_fail %s" % e) +try: + gdb.execute("detach") +except Exception: + pass
\ No newline at end of file |
