summaryrefslogtreecommitdiffstats
path: root/tools/guest-diag/bpz11.py
blob: 601a73db8e8a063245b2d457f3ac0f356e08dc70 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
# gdb script: split FUN_00391ee0 (ucode-image registration, file 0x291ee0).
#
# PART 76 + bpz10 run: FUN_003e90c0's failing call is FUN_00391ee0, which
# returns 1. FUN_00391ee0 (6519 bytes) has a single epilogue at 0x292258
# (mov r15d,eax) with status in r15d; every checked call does
# "test; jne 0x292248" (error exit). This script traces every call return,
# printing nonzero values, then at the epilogue prints the final status and
# the recent history tail.
#
# Run: sudo gdb -p <cdt-pid> -batch -x /tmp/bpz11.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")

SITES = [
    (0x291f0c, "c_179350_lock"),
    (0x2920b6, "c_179560_snprintf"),
    (0x292108, "c_4fbb50"),
    (0x29211b, "c_1799e0_calloc"),
    (0x29217a, "c_279110_a"),
    (0x2921a6, "c_2f9fa0"),
    (0x2921c6, "c_279110_b"),
    (0x2921fd, "c_279210"),
    (0x29223d, "c_2f9e20"),
    (0x29227f, "c_512230_a"),
    (0x292295, "c_512230_b"),
    (0x2922b9, "c_5277f0_a"),
    (0x2922d5, "c_24a4d0_bool"),
    (0x29232f, "c_5277f0_b"),
    (0x292392, "c_285410"),
    (0x2923bd, "c_2f9f00"),
    (0x2923f6, "c_4fd080"),
    (0x29240e, "c_4fd1a0"),
    (0x292418, "c_4fbf20"),
    (0x292457, "c_279900"),
    (0x292497, "c_286020"),
    (0x2924e3, "c_2df340_bool"),
    (0x292518, "c_263790"),
    (0x292572, "c_512910"),
    (0x292580, "c_5277f0_c"),
    (0x29258f, "c_5277f0_d"),
    (0x2925f8, "c_2df340_bool2"),
    (0x29262e, "c_263980"),
    (0x29269b, "c_3aa550_a"),
    (0x2926c1, "c_d663e0_a"),
    (0x2927cc, "c_277c70_a"),
    (0x292835, "c_3aa740"),
    (0x29291c, "c_277c70_b"),
    (0x292999, "c_d4b570_a"),
    (0x292a35, "c_d4b570_b"),
    (0x292aaf, "c_d4b570_c"),
    (0x292b29, "c_d4b570_d"),
    (0x292b62, "c_277900"),
    (0x292b96, "c_d4b570_e"),
    (0x292bb7, "c_278c70"),
    (0x292c1e, "c_d4b570_f"),
    (0x292c3f, "c_2874a0"),
    (0x292c6e, "c_27c3a0"),
    (0x292c81, "c_27c8f0"),
    (0x292ca9, "c_ind_0x4770"),
    (0x292d34, "c_d4b980"),
    (0x292d6e, "c_27c870"),
    (0x292dc7, "c_27c6a0_a"),
    (0x292e04, "c_27c6a0_b"),
    (0x292e43, "c_27c6a0_c"),
    (0x292e82, "c_27c6a0_d"),
    (0x292ef3, "c_27c6a0_e"),
    (0x292f38, "c_2df340_bool3"),
    (0x292f65, "c_25c0a0"),
    (0x29304d, "c_3aa550_b"),
    (0x29307a, "c_d663e0_b"),
    (0x2931e4, "c_3ab420"),
    (0x29328d, "c_27a9e0_a"),
    (0x293305, "c_27be70"),
    (0x29333e, "c_27a9e0_b"),
    (0x29336d, "c_3aa820_alloc"),
    (0x2933f8, "c_28fb00"),
    (0x29340b, "c_277960"),
    (0x29343f, "c_d6c560"),
    (0x29354d, "c_28f6b0"),
    (0x29361b, "c_179980_strcmp_a"),
    (0x293640, "c_179980_strcmp_b"),
    (0x2936ca, "c_d664f0_a"),
    (0x2936f2, "c_d664f0_b"),
    (0x29371a, "c_d664f0_c"),
    (0x293742, "c_d664f0_d"),
    (0x29376a, "c_d664f0_e"),
    (0x293830, "c_179350_lock2"),
    (0x292258, "FRET"),
]
NAMES = dict(SITES)
for off, name in SITES:
    gdb.execute("break *0x%x" % (base + off))

t0 = time.time()
hits = 0
hist = []
inv = 0
while hits < 800:
    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
    if name == "FRET":
        inv += 1
        print("INV %d FRET r15d=0x%x (eax=0x%x)" % (inv, r15, eax))
        print("  tail:", " | ".join("%s=0x%x" % (n, v) for n, v in hist[-10:]))
        if r15 != 0:
            nz = [x for x in hist if x[1] != 0]
            print("  nonzero call returns (last 12):")
            for n, v in nz[-12:]:
                print("    %s = 0x%x" % (n, v))
            try:
                print(gdb.execute("bt 6", to_string=True))
            except Exception as e:
                print("bt_fail %s" % e)
            break
        hist = []
    else:
        hist.append((name, eax))
        if eax != 0:
            print("HIT %d t=%.3f %-18s eax=0x%x" % (hits, time.time() - t0, name, eax))
        elif hits % 100 == 0:
            print("HIT %d t=%.3f %s eax=0" % (hits, time.time() - t0, name))

try:
    gdb.execute("detach")
except Exception:
    pass