diff options
Diffstat (limited to 'tools/guest-diag/bpz10.py')
| -rw-r--r-- | tools/guest-diag/bpz10.py | 125 |
1 files changed, 125 insertions, 0 deletions
diff --git a/tools/guest-diag/bpz10.py b/tools/guest-diag/bpz10.py new file mode 100644 index 0000000..30aa1da --- /dev/null +++ b/tools/guest-diag/bpz10.py @@ -0,0 +1,125 @@ +# gdb script: name the first failing call inside FUN_003e90c0 (ucode-image +# create, second half) after FUN_003d1e70 (blob parse) succeeded. +# +# PART 76 chain: FUN_00e21850 -> FUN_003e99d0 -> FUN_003d1e70 OK -> +# FUN_003e90c0 returns 1. This script breaks after EVERY call in +# FUN_003e90c0 (file 0x2e90c0..0x2e99b5), prints the return value, and +# finally prints the function's return + the caller's test site +# (CREATE2_RET at 0x2e9a3f). +# +# Run: sudo gdb -p <cdt-pid> -batch -x /tmp/bpz10.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: + raise SystemExit + +gdb.execute("set pagination off") +gdb.execute("set confirm off") + +# (file offset of the instruction AFTER the call, short name) +SITES = [ + (0x2e9110, "calloc"), + (0x2e912a, "FUN_004aa820_alloc"), + (0x2e918e, "FUN_00390290_status"), + (0x2e91b3, "FUN_003df0d0_status"), + (0x2e91f1, "destr_2e84d0"), + (0x2e921d, "FUN_00391ee0_status"), + (0x2e923c, "FUN_00371fa0_status"), + (0x2e9282, "mutex_lock84"), + (0x2e92b7, "mutex_unlock84"), + (0x2e92bf, "FUN_00e4f3e0_status"), + (0x2e9304, "mutex_lock68"), + (0x2e931a, "mutex_unlock68"), + (0x2e932a, "FUN_00363430_bool"), + (0x2e9336, "FUN_003df340_bool"), + (0x2e9363, "FUN_00406ff0_status"), + (0x2e93ba, "FUN_00394190_status"), + (0x2e93c9, "FUN_003bf520_status"), + (0x2e9449, "free_a"), + (0x2e9478, "FUN_00400550"), + (0x2e948e, "FUN_004ab390"), + (0x2e9497, "free_b"), + (0x2e94a8, "free_c"), + (0x2e94b6, "free_d_fail"), + (0x2e9505, "FUN_003011e0_status"), + (0x2e9525, "ind_0xa0_status"), + (0x2e9564, "unlock_fail"), + (0x2e9598, "unlock_b"), + (0x2e95fc, "FUN_00e4b8c0"), + (0x2e9615, "ind_0x4a48_ptr"), + (0x2e9628, "FUN_005a5530"), + (0x2e9643, "FUN_003df340_bool2"), + (0x2e967a, "FUN_00e4f200_status"), + (0x2e9687, "FUN_0034a4d0_bool"), + (0x2e96e4, "FUN_00251730_done"), + (0x2e9717, "unlock_ret0"), + (0x2e9788, "FUN_003bf520_status2"), + (0x2e97fa, "fprintf_fail"), + (0x2e9808, "FUN_003be020_bool"), + (0x2e9824, "FUN_0036b900_bool"), + (0x2e9857, "FUN_003df340_bool3"), + (0x2e9936, "FUN_00e4f2d0"), + (0x2e9203, "FUN_3e90c0_RET"), + (0x2e9a23, "PARSE_RET"), + (0x2e9a3f, "CREATE2_RET"), +] +NAMES = dict(SITES) +for off, name in SITES: + gdb.execute("break *0x%x" % (base + off)) + +t0 = time.time() +hits = 0 +last_nonzero = None +inv = 0 +while hits < 500: + try: + gdb.execute("continue") + except gdb.error as e: + print("CONTINUE_END %s" % e) + break + hits += 1 + rip = int(gdb.parse_and_eval("$rip")) & 0xffffffffffffffff + off = rip - base + name = NAMES.get(off, "?") + eax = int(gdb.parse_and_eval("$eax")) & 0xffffffff + r15 = int(gdb.parse_and_eval("$r15d")) & 0xffffffff + print("HIT %d t=%.3f off=0x%x %-24s eax=0x%x r15=0x%x" % + (hits, time.time() - t0, off, name, eax, r15)) + if name in ("FUN_00390290_status", "FUN_003df0d0_status", + "FUN_00391ee0_status", "FUN_00371fa0_status", + "FUN_00e4f3e0_status", "FUN_00406ff0_status", + "FUN_00394190_status", "FUN_003bf520_status", + "FUN_003bf520_status2", "FUN_003011e0_status", + "FUN_00e4f200_status") and eax != 0: + last_nonzero = (name, eax) + print(" >>> LAST NONZERO %s = 0x%x" % (name, eax)) + if name == "FUN_3e90c0_RET": + inv += 1 + print("INV %d FUN_3e90c0 return r15/eax=0x%x" % (inv, r15)) + if last_nonzero: + print(" last nonzero status call: %s = 0x%x" % last_nonzero) + if r15 != 0: + try: + print(gdb.execute("bt 6", to_string=True)) + except Exception as e: + print("bt_fail %s" % e) + break + last_nonzero = None + if name == "CREATE2_RET": + print("CREATE2_RET eax=0x%x" % eax) + if eax != 0: + break + +try: + gdb.execute("detach") +except Exception: + pass |
