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
|
# SPDX-License-Identifier: BSD-3-Clause
# Copyright (c) 2026 Open-IOV contributors
# 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
|