Skip to content

Commit 1803c04

Browse files
authored
Merge pull request #10705 from gmilos/symbolication-improvements
Improve symbolicate-linux-fatal to handle unparsable addresses.
2 parents 400c326 + 1e078fb commit 1803c04

File tree

1 file changed

+53
-39
lines changed

1 file changed

+53
-39
lines changed

utils/symbolicate-linux-fatal

Lines changed: 53 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,45 @@ lldb_target = None
7979
known_memmap = {}
8080

8181

82+
def check_base_address(dynlib_path, dynlib_baseaddr, memmap):
83+
global known_memmap
84+
if dynlib_path in memmap or dynlib_path in known_memmap:
85+
if dynlib_path in memmap:
86+
existing_baseaddr = memmap[dynlib_path]
87+
else:
88+
existing_baseaddr = known_memmap[dynlib_path]
89+
if existing_baseaddr != dynlib_baseaddr:
90+
error_msg = "Mismatched base address for: {0:s}, " \
91+
"had: {1:x}, now got {2:x}"
92+
error_msg = error_msg.format(
93+
dynlib_path, existing_baseaddr, dynlib_baseaddr)
94+
raise Exception(error_msg)
95+
96+
97+
def symbolicate_one(frame_addr, frame_idx, dynlib_fname):
98+
global lldb_target
99+
so_addr = lldb_target.ResolveLoadAddress(frame_addr - 1)
100+
sym_ctx = so_addr.GetSymbolContext(lldb.eSymbolContextEverything)
101+
frame_fragment = "{0: <4d} {1:20s} 0x{2:016x}".format(
102+
frame_idx, dynlib_fname, frame_addr)
103+
symbol = sym_ctx.GetSymbol()
104+
if not symbol.IsValid():
105+
raise Exception("symbol isn't valid")
106+
107+
symbol_base = symbol.GetStartAddress().GetLoadAddress(lldb_target)
108+
symbol_fragment = "{0:s} + {1:d}".format(
109+
symbol.GetName(), frame_addr - symbol_base)
110+
line_entry = sym_ctx.GetLineEntry()
111+
if line_entry.IsValid():
112+
line_fragment = "at {0:s}:{1:d}".format(
113+
line_entry.GetFileSpec().GetFilename(), line_entry.GetLine())
114+
else:
115+
line_fragment = ""
116+
117+
return "{0:s} {1:s} {2:s}".format(
118+
frame_fragment, symbol_fragment, line_fragment)
119+
120+
82121
def process_stack(binary, dyn_libs, stack):
83122
global lldb_target
84123
global known_memmap
@@ -96,26 +135,20 @@ def process_stack(binary, dyn_libs, stack):
96135
else:
97136
dynlib_path = None
98137

99-
if "<unavailable>" in stack_tokens[3]:
138+
try:
100139
framePC = int(stack_tokens[2], 16)
101140
symbol_offset = int(stack_tokens[-1], 10)
141+
except:
142+
full_stack.append({"line": line, "framePC": 0, "dynlib_fname": ""})
143+
continue
144+
145+
if "<unavailable>" in stack_tokens[3]:
102146
dynlib_baseaddr = framePC - symbol_offset
103-
if dynlib_path in memmap or dynlib_path in known_memmap:
104-
if dynlib_path in memmap:
105-
existing_baseaddr = memmap[dynlib_path]
106-
else:
107-
existing_baseaddr = known_memmap[dynlib_path]
108-
if existing_baseaddr != dynlib_baseaddr:
109-
error_msg = "Mismatched base address for: {0:s}, " \
110-
"had: {1:x}, now got {2:x}"
111-
error_msg = error_msg.format(
112-
dynlib_path, existing_baseaddr, dynlib_baseaddr)
113-
raise Exception(error_msg)
114-
else:
115-
known_memmap[dynlib_path] = dynlib_baseaddr
116-
memmap[dynlib_path] = dynlib_baseaddr
147+
check_base_address(dynlib_path, dynlib_baseaddr, memmap)
148+
known_memmap[dynlib_path] = dynlib_baseaddr
149+
memmap[dynlib_path] = dynlib_baseaddr
117150
else:
118-
framePC = int(stack_tokens[2], 16) + int(stack_tokens[-1], 10)
151+
framePC = framePC + symbol_offset
119152
full_stack.append(
120153
{"line": line, "framePC": framePC, "dynlib_fname": dynlib_fname})
121154

@@ -125,32 +158,13 @@ def process_stack(binary, dyn_libs, stack):
125158
add_lldb_target_modules(lldb_target, memmap)
126159
frame_idx = 0
127160
for frame in full_stack:
128-
use_orig_line = True
129161
frame_addr = frame["framePC"]
130162
dynlib_fname = frame["dynlib_fname"]
131-
so_addr = lldb_target.ResolveLoadAddress(frame_addr - 1)
132-
sym_ctx = so_addr.GetSymbolContext(lldb.eSymbolContextEverything)
133-
frame_fragment = "{0: <4d} {1:20s} 0x{2:016x}".format(
134-
frame_idx, dynlib_fname, frame_addr)
135-
symbol = sym_ctx.GetSymbol()
136-
if symbol.IsValid():
137-
symbol_base = symbol.GetStartAddress().GetLoadAddress(lldb_target)
138-
symbol_fragment = "{0:s} + {1:d}".format(
139-
symbol.GetName(), frame_addr - symbol_base)
140-
use_orig_line = False
141-
else:
142-
symbol_fragment = "<unavailable>"
143-
line_entry = sym_ctx.GetLineEntry()
144-
if line_entry.IsValid():
145-
line_fragment = "at {0:s}:{1:d}".format(
146-
line_entry.GetFileSpec().GetFilename(), line_entry.GetLine())
147-
else:
148-
line_fragment = ""
149-
if use_orig_line:
163+
try:
164+
sym_line = symbolicate_one(frame_addr, frame_idx, dynlib_fname)
165+
print(sym_line)
166+
except:
150167
print(frame["line"].rstrip())
151-
else:
152-
print("{0:s} {1:s} {2:s}".format(
153-
frame_fragment, symbol_fragment, line_fragment))
154168
frame_idx = frame_idx + 1
155169

156170

0 commit comments

Comments
 (0)