summaryrefslogtreecommitdiffstats
path: root/tools/guest-diag/bp999v2.py
diff options
context:
space:
mode:
Diffstat (limited to 'tools/guest-diag/bp999v2.py')
-rw-r--r--tools/guest-diag/bp999v2.py89
1 files changed, 89 insertions, 0 deletions
diff --git a/tools/guest-diag/bp999v2.py b/tools/guest-diag/bp999v2.py
new file mode 100644
index 0000000..766bc3b
--- /dev/null
+++ b/tools/guest-diag/bp999v2.py
@@ -0,0 +1,89 @@
+# gdb script: break at the 999/719 RETURN sites of the libcuda scanner
+# FUN_0054fa00 and dump the record values the scanner actually read (they are
+# still in its stack locals, so the host clearing the notification afterwards
+# cannot race this capture).
+#
+# Scanner layout (disassembly of libcuda+0x44fa00):
+# rec = *(*(*(ctx+0x9488)+0x10)+0x10)
+# locals: rbp-0x40 rec[+0x00], rbp-0x3c rec[+0x04], rbp-0x38 rec[+0x08],
+# rbp-0x34 rec[+0x0c] (s16), rbp-0x32 rec[+0x0e] (s16)
+# 0x44fb80 -> return 999 when force != 0 and (rec[+8]|rec[+0xc]|rec[+0xe])
+# 0x44fb6c -> return 0x2cf
+# Run: sudo gdb -p <cdt-pid> -batch -x /tmp/bp999v2.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 + 0x44fb80))
+gdb.execute("break *0x%x" % (base + 0x44fb6c))
+try:
+ gdb.execute("continue")
+except gdb.error as e:
+ print("CONTINUE_ERR %s" % e)
+print("STOPPED")
+
+try:
+ rip = int(gdb.parse_and_eval("$rip")) & 0xffffffffffffffff
+ print("RIP=0x%x off=0x%x" % (rip, rip - base))
+ rdi = int(gdb.parse_and_eval("$rdi")) & 0xffffffffffffffff
+ rsi = int(gdb.parse_and_eval("$rsi")) & 0xffffffff
+ rbp = int(gdb.parse_and_eval("$rbp")) & 0xffffffffffffffff
+ print("rdi=0x%x rsi(force)=%d rbp=0x%x" % (rdi, rsi, rbp))
+ print(gdb.execute("x/5wx 0x%x" % (rbp - 0x40), to_string=True))
+ print(gdb.execute("x/2hx 0x%x" % (rbp - 0x34), to_string=True))
+except Exception as e:
+ print("locals_fail %s" % e)
+
+try:
+ print(gdb.execute("bt 14", to_string=True))
+except Exception as e:
+ print("bt_fail %s" % e)
+
+
+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:
+ pl = rd64(rdi)
+ n = 0
+ while pl and n < 64:
+ mgr = rd64(pl + 0x9488)
+ print("ctx[%d]=0x%x mgr=0x%x" % (n, pl, mgr or 0))
+ if mgr:
+ reg = rd64(mgr + 0x10)
+ if reg:
+ rec = rd64(reg + 0x10)
+ print(" reg=0x%x rec=0x%x" % (reg, rec or 0))
+ if rec:
+ for i in range(0, 0x28, 4):
+ print(" rec[+0x%02x]=0x%08x" % (i, rd32(rec + i) or 0))
+ pl = rd64(pl + 0x9470)
+ n += 1
+except Exception as e:
+ print("record_dump_fail %s" % e)
+try:
+ gdb.execute("detach")
+except Exception:
+ pass \ No newline at end of file