summaryrefslogtreecommitdiffstats
path: root/tools/guest-diag/bpwait.py
diff options
context:
space:
mode:
Diffstat (limited to 'tools/guest-diag/bpwait.py')
-rw-r--r--tools/guest-diag/bpwait.py74
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