@@ -28,7 +28,17 @@ import argparse
28
28
import os
29
29
import subprocess
30
30
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
32
42
33
43
34
44
def process_ldd (lddoutput ):
@@ -38,7 +48,7 @@ def process_ldd(lddoutput):
38
48
if len (ldd_tokens ) >= 2 :
39
49
lib = ldd_tokens [- 2 ]
40
50
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 ))
42
52
dyn_libs [real_name ] = lib
43
53
return dyn_libs
44
54
@@ -58,7 +68,19 @@ def create_lldb_target(binary, memmap):
58
68
return lldb_target
59
69
60
70
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
+
61
81
def process_stack (binary , dyn_libs , stack ):
82
+ global lldb_target
83
+ global known_memmap
62
84
if len (stack ) == 0 :
63
85
return
64
86
memmap = {}
@@ -77,21 +99,29 @@ def process_stack(binary, dyn_libs, stack):
77
99
framePC = int (stack_tokens [2 ], 16 )
78
100
symbol_offset = int (stack_tokens [- 1 ], 10 )
79
101
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 :
82
108
error_msg = "Mismatched base address for: {0:s}, " \
83
109
"had: {1:x}, now got {2:x}"
84
110
error_msg = error_msg .format (
85
- dynlib_path , memmap [ dynlib_path ] , dynlib_baseaddr )
111
+ dynlib_path , existing_baseaddr , dynlib_baseaddr )
86
112
raise Exception (error_msg )
87
113
else :
114
+ known_memmap [dynlib_path ] = dynlib_baseaddr
88
115
memmap [dynlib_path ] = dynlib_baseaddr
89
116
else :
90
117
framePC = int (stack_tokens [2 ], 16 ) + int (stack_tokens [- 1 ], 10 )
91
118
full_stack .append (
92
119
{"line" : line , "framePC" : framePC , "dynlib_fname" : dynlib_fname })
93
120
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 )
95
125
frame_idx = 0
96
126
for frame in full_stack :
97
127
use_orig_line = True
@@ -130,8 +160,8 @@ def main():
130
160
parser .add_argument (
131
161
"binary" , help = "Executable which produced the log file" )
132
162
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. " )
135
165
args = parser .parse_args ()
136
166
137
167
binary = args .binary
0 commit comments