@@ -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
@@ -57,8 +67,18 @@ def create_lldb_target(binary, memmap):
57
67
lldb_target .SetModuleLoadAddress (module , memmap [dynlib_path ])
58
68
return lldb_target
59
69
70
+ def add_lldb_target_modules (lldb_target , memmap ):
71
+ for dynlib_path in memmap :
72
+ module = lldb_target .AddModule (
73
+ dynlib_path , lldb .LLDB_ARCH_DEFAULT , None , None )
74
+ lldb_target .SetModuleLoadAddress (module , memmap [dynlib_path ])
75
+
76
+ lldb_target = None
77
+ known_memmap = {}
60
78
61
79
def process_stack (binary , dyn_libs , stack ):
80
+ global lldb_target
81
+ global known_memmap
62
82
if len (stack ) == 0 :
63
83
return
64
84
memmap = {}
@@ -77,21 +97,29 @@ def process_stack(binary, dyn_libs, stack):
77
97
framePC = int (stack_tokens [2 ], 16 )
78
98
symbol_offset = int (stack_tokens [- 1 ], 10 )
79
99
dynlib_baseaddr = framePC - symbol_offset
80
- if dynlib_path in memmap :
81
- if memmap [dynlib_path ] != dynlib_baseaddr :
100
+ if dynlib_path in memmap or dynlib_path in known_memmap :
101
+ if dynlib_path in memmap :
102
+ existing_baseaddr = memmap [dynlib_path ]
103
+ else :
104
+ existing_baseaddr = known_memmap [dynlib_path ]
105
+ if existing_baseaddr != dynlib_baseaddr :
82
106
error_msg = "Mismatched base address for: {0:s}, " \
83
107
"had: {1:x}, now got {2:x}"
84
108
error_msg = error_msg .format (
85
- dynlib_path , memmap [ dynlib_path ] , dynlib_baseaddr )
109
+ dynlib_path , existing_baseaddr , dynlib_baseaddr )
86
110
raise Exception (error_msg )
87
111
else :
112
+ known_memmap [dynlib_path ] = dynlib_baseaddr
88
113
memmap [dynlib_path ] = dynlib_baseaddr
89
114
else :
90
115
framePC = int (stack_tokens [2 ], 16 ) + int (stack_tokens [- 1 ], 10 )
91
116
full_stack .append (
92
117
{"line" : line , "framePC" : framePC , "dynlib_fname" : dynlib_fname })
93
118
94
- lldb_target = create_lldb_target (binary , memmap )
119
+ if lldb_target == None :
120
+ lldb_target = create_lldb_target (binary , memmap )
121
+ else :
122
+ add_lldb_target_modules (lldb_target , memmap )
95
123
frame_idx = 0
96
124
for frame in full_stack :
97
125
use_orig_line = True
@@ -130,8 +158,8 @@ def main():
130
158
parser .add_argument (
131
159
"binary" , help = "Executable which produced the log file" )
132
160
parser .add_argument (
133
- "log" , type = argparse .FileType ("rU" ),
134
- help = "Log file containing the stack trace to symbolicate" )
161
+ "log" , nargs = '?' , type = argparse .FileType ("rU" ), default = "-" ,
162
+ help = "Log file containing the stack trace to symbolicate. Defaults to stdin. " )
135
163
args = parser .parse_args ()
136
164
137
165
binary = args .binary
0 commit comments