Skip to content

Commit 72af643

Browse files
authored
Merge pull request #10103 from gmilos/linux-symbolication-improvements
Improve symbolication of stacktraces on Linux.
2 parents 88baa17 + 4844a13 commit 72af643

File tree

1 file changed

+38
-8
lines changed

1 file changed

+38
-8
lines changed

utils/symbolicate-linux-fatal

Lines changed: 38 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,17 @@ import argparse
2828
import os
2929
import subprocess
3030

31-
import lldb
31+
try:
32+
import lldb
33+
except ImportError:
34+
from distutils import spawn
35+
swift_exec = spawn.find_executable('swift')
36+
if swift_exec is not None:
37+
site_packages = os.path.join(os.path.dirname(swift_exec),
38+
'../lib/python2.7/site-packages/')
39+
import sys
40+
sys.path.append(site_packages)
41+
import lldb
3242

3343

3444
def process_ldd(lddoutput):
@@ -38,7 +48,7 @@ def process_ldd(lddoutput):
3848
if len(ldd_tokens) >= 2:
3949
lib = ldd_tokens[-2]
4050
dyn_libs[ldd_tokens[0]] = lib
41-
real_name = os.path.basename(os.path.realpath(lib))
51+
real_name = os.path.basename(os.path.realpath(lib))
4252
dyn_libs[real_name] = lib
4353
return dyn_libs
4454

@@ -58,7 +68,19 @@ def create_lldb_target(binary, memmap):
5868
return lldb_target
5969

6070

71+
def add_lldb_target_modules(lldb_target, memmap):
72+
for dynlib_path in memmap:
73+
module = lldb_target.AddModule(
74+
dynlib_path, lldb.LLDB_ARCH_DEFAULT, None, None)
75+
lldb_target.SetModuleLoadAddress(module, memmap[dynlib_path])
76+
77+
lldb_target = None
78+
known_memmap = {}
79+
80+
6181
def process_stack(binary, dyn_libs, stack):
82+
global lldb_target
83+
global known_memmap
6284
if len(stack) == 0:
6385
return
6486
memmap = {}
@@ -77,21 +99,29 @@ def process_stack(binary, dyn_libs, stack):
7799
framePC = int(stack_tokens[2], 16)
78100
symbol_offset = int(stack_tokens[-1], 10)
79101
dynlib_baseaddr = framePC - symbol_offset
80-
if dynlib_path in memmap:
81-
if memmap[dynlib_path] != dynlib_baseaddr:
102+
if dynlib_path in memmap or dynlib_path in known_memmap:
103+
if dynlib_path in memmap:
104+
existing_baseaddr = memmap[dynlib_path]
105+
else:
106+
existing_baseaddr = known_memmap[dynlib_path]
107+
if existing_baseaddr != dynlib_baseaddr:
82108
error_msg = "Mismatched base address for: {0:s}, " \
83109
"had: {1:x}, now got {2:x}"
84110
error_msg = error_msg.format(
85-
dynlib_path, memmap[dynlib_path], dynlib_baseaddr)
111+
dynlib_path, existing_baseaddr, dynlib_baseaddr)
86112
raise Exception(error_msg)
87113
else:
114+
known_memmap[dynlib_path] = dynlib_baseaddr
88115
memmap[dynlib_path] = dynlib_baseaddr
89116
else:
90117
framePC = int(stack_tokens[2], 16) + int(stack_tokens[-1], 10)
91118
full_stack.append(
92119
{"line": line, "framePC": framePC, "dynlib_fname": dynlib_fname})
93120

94-
lldb_target = create_lldb_target(binary, memmap)
121+
if lldb_target is None:
122+
lldb_target = create_lldb_target(binary, memmap)
123+
else:
124+
add_lldb_target_modules(lldb_target, memmap)
95125
frame_idx = 0
96126
for frame in full_stack:
97127
use_orig_line = True
@@ -130,8 +160,8 @@ def main():
130160
parser.add_argument(
131161
"binary", help="Executable which produced the log file")
132162
parser.add_argument(
133-
"log", type=argparse.FileType("rU"),
134-
help="Log file containing the stack trace to symbolicate")
163+
"log", nargs='?', type=argparse.FileType("rU"), default="-",
164+
help="Log file for symbolication. Defaults to stdin.")
135165
args = parser.parse_args()
136166

137167
binary = args.binary

0 commit comments

Comments
 (0)