blob: 88ca6a77eb66a8c76d10d2a2e2cd4a8df37af8e2 [file] [log] [blame]
Greg Clayton2f9ca7b2011-09-26 18:39:23 +00001#!/usr/bin/python
2
3#----------------------------------------------------------------------
4# Be sure to add the python path that points to the LLDB shared library.
5# On MacOSX csh, tcsh:
6# setenv PYTHONPATH /Developer/Library/PrivateFrameworks/LLDB.framework/Resources/Python
7# On MacOSX sh, bash:
8# export PYTHONPATH=/Developer/Library/PrivateFrameworks/LLDB.framework/Resources/Python
9#----------------------------------------------------------------------
10
11import lldb
12import optparse
13import os
14import re
15import sys
16import time
17
18PARSE_MODE_NORMAL = 0
19PARSE_MODE_THREAD = 1
20PARSE_MODE_IMAGES = 2
21PARSE_MODE_THREGS = 3
22PARSE_MODE_SYSTEM = 4
23
24class CrashLog:
25 """Class that does parses darwin crash logs"""
26 thread_state_regex = re.compile('^Thread ([0-9]+) crashed with')
27 thread_regex = re.compile('^Thread ([0-9]+)([^:]*):(.*)')
Greg Claytona6e42922011-09-26 19:17:49 +000028 frame_regex = re.compile('^([0-9]+).*\t(0x[0-9a-fA-F]+) +(.*)')
29 image_regex_uuid = re.compile('(0x[0-9a-fA-F]+)[- ]+(0x[0-9a-fA-F]+) +([^ ]+) +([^<]+)<([-0-9a-fA-F]+)> (.*)');
30 image_regex_no_uuid = re.compile('(0x[0-9a-fA-F]+)[- ]+(0x[0-9a-fA-F]+) +([^ ]+) +([^/]+)/(.*)');
Greg Clayton2f9ca7b2011-09-26 18:39:23 +000031 empty_line_regex = re.compile('^$')
32
33 class Thread:
34 """Class that represents a thread in a darwin crash log"""
35 def __init__(self, index):
36 self.index = index
37 self.frames = list()
38 self.registers = dict()
39 self.reason = None
40 self.queue = None
41
42 def dump(self, prefix):
43 print "%sThread[%u] %s" % (prefix, self.index, self.reason)
44 if self.frames:
45 print "%s Frames:" % (prefix)
46 for frame in self.frames:
47 frame.dump(prefix + ' ')
48 if self.registers:
49 print "%s Registers:" % (prefix)
50 for reg in self.registers.keys():
51 print "%s %-5s = %#16.16x" % (prefix, reg, self.registers[reg])
52
53 def did_crash(self):
54 return self.reason != None
55
56 def __str__(self):
57 s = "Thread[%u]" % self.index
58 if self.reason:
59 s += ' %s' % self.reason
60 return s
61
62 class Frame:
63 """Class that represents a stack frame in a thread in a darwin crash log"""
64 def __init__(self, index, pc, details):
65 self.index = index
66 self.pc = pc
67 self.sym_ctx = None
68 self.details = details
69
70 def __str__(self):
71 return "[%2u] %#16.16x %s" % (self.index, self.pc, self.details)
72
73 def dump(self, prefix):
74 print "%s%s" % (prefix, self)
75
76 class Image:
77 """Class that represents a binary images in a darwin crash log"""
Greg Claytona6e42922011-09-26 19:17:49 +000078 def __init__(self, text_addr_lo, text_addr_hi, ident, version, uuid, path):
Greg Clayton2f9ca7b2011-09-26 18:39:23 +000079 self.text_addr_lo = text_addr_lo
80 self.text_addr_hi = text_addr_hi
81 self.ident = ident
82 self.version = version
Greg Clayton2f9ca7b2011-09-26 18:39:23 +000083 self.uuid = uuid
84 self.path = path
85
86 def dump(self, prefix):
87 print "%s%s" % (prefix, self)
88
89 def __str__(self):
90 return "%#16.16x %s %s" % (self.text_addr_lo, self.uuid, self.path)
91
92
93 def __init__(self, path):
94 """CrashLog constructor that take a path to a darwin crash log file"""
95 self.path = path;
96 self.info_lines = list()
97 self.system_profile = list()
98 self.threads = list()
99 self.images = list()
100 self.crashed_thread_idx = -1
101 self.version = -1
Johnny Chen1c6c43f2011-10-06 23:36:00 +0000102 # With possible initial component of ~ or ~user replaced by that user's home directory.
103 f = open(os.path.expanduser(self.path))
Greg Clayton2f9ca7b2011-09-26 18:39:23 +0000104 self.file_lines = f.read().splitlines()
105 parse_mode = PARSE_MODE_NORMAL
106 thread = None
107 for line in self.file_lines:
108 # print line
109 line_len = len(line)
110 if line_len == 0:
111 if thread:
112 if parse_mode == PARSE_MODE_THREAD:
113 if thread.index == self.crashed_thread_idx:
114 thread.reason = ''
115 if self.thread_exception:
116 thread.reason += self.thread_exception
117 if self.thread_exception_data:
118 thread.reason += " (%s)" % self.thread_exception_data
119 self.threads.append(thread)
120 thread = None
121 else:
122 # only append an extra empty line if the previous line
123 # in the info_lines wasn't empty
124 if len(self.info_lines) > 0 and len(self.info_lines[-1]):
125 self.info_lines.append(line)
126 parse_mode = PARSE_MODE_NORMAL
127 # print 'PARSE_MODE_NORMAL'
128 elif parse_mode == PARSE_MODE_NORMAL:
129 if line.startswith ('Process:'):
130 (self.process_name, pid_with_brackets) = line[8:].strip().split()
131 self.process_id = pid_with_brackets.strip('[]')
132 elif line.startswith ('Path:'):
133 self.process_path = line[5:].strip()
134 elif line.startswith ('Identifier:'):
135 self.process_identifier = line[11:].strip()
136 elif line.startswith ('Version:'):
137 (self.process_version, compatability_version) = line[8:].strip().split()
138 self.process_compatability_version = compatability_version.strip('()')
139 elif line.startswith ('Parent Process:'):
140 (self.parent_process_name, pid_with_brackets) = line[15:].strip().split()
141 self.parent_process_id = pid_with_brackets.strip('[]')
142 elif line.startswith ('Exception Type:'):
143 self.thread_exception = line[15:].strip()
144 continue
145 elif line.startswith ('Exception Codes:'):
146 self.thread_exception_data = line[16:].strip()
147 continue
148 elif line.startswith ('Crashed Thread:'):
149 self.crashed_thread_idx = int(line[15:].strip().split()[0])
150 continue
151 elif line.startswith ('Report Version:'):
152 self.version = int(line[15:].strip())
153 continue
154 elif line.startswith ('System Profile:'):
155 parse_mode = PARSE_MODE_SYSTEM
156 continue
157 elif (line.startswith ('Interval Since Last Report:') or
158 line.startswith ('Crashes Since Last Report:') or
159 line.startswith ('Per-App Interval Since Last Report:') or
160 line.startswith ('Per-App Crashes Since Last Report:') or
161 line.startswith ('Sleep/Wake UUID:') or
162 line.startswith ('Anonymous UUID:')):
163 # ignore these
164 continue
165 elif line.startswith ('Thread'):
166 thread_state_match = self.thread_state_regex.search (line)
167 if thread_state_match:
168 thread_state_match = self.thread_regex.search (line)
169 thread_idx = int(thread_state_match.group(1))
170 parse_mode = PARSE_MODE_THREGS
171 thread = self.threads[thread_idx]
172 else:
173 thread_match = self.thread_regex.search (line)
174 if thread_match:
175 # print 'PARSE_MODE_THREAD'
176 parse_mode = PARSE_MODE_THREAD
177 thread_idx = int(thread_match.group(1))
178 thread = CrashLog.Thread(thread_idx)
179 continue
180 elif line.startswith ('Binary Images:'):
181 parse_mode = PARSE_MODE_IMAGES
182 continue
183 self.info_lines.append(line.strip())
184 elif parse_mode == PARSE_MODE_THREAD:
185 frame_match = self.frame_regex.search(line)
186 if frame_match:
187 thread.frames.append (CrashLog.Frame(int(frame_match.group(1)), int(frame_match.group(2), 0), frame_match.group(3)))
188 else:
189 print "error: frame regex failed"
190 elif parse_mode == PARSE_MODE_IMAGES:
Greg Claytona6e42922011-09-26 19:17:49 +0000191 image_match = self.image_regex_uuid.search (line)
Greg Clayton2f9ca7b2011-09-26 18:39:23 +0000192 if image_match:
193 image = CrashLog.Image (int(image_match.group(1),0),
194 int(image_match.group(2),0),
Greg Claytona6e42922011-09-26 19:17:49 +0000195 image_match.group(3).strip(),
196 image_match.group(4).strip(),
Greg Clayton2f9ca7b2011-09-26 18:39:23 +0000197 image_match.group(5),
Greg Claytona6e42922011-09-26 19:17:49 +0000198 image_match.group(6))
Greg Clayton2f9ca7b2011-09-26 18:39:23 +0000199 self.images.append (image)
200 else:
Greg Claytona6e42922011-09-26 19:17:49 +0000201 image_match = self.image_regex_no_uuid.search (line)
202 if image_match:
203 image = CrashLog.Image (int(image_match.group(1),0),
204 int(image_match.group(2),0),
205 image_match.group(3).strip(),
206 image_match.group(4).strip(),
207 None,
208 image_match.group(5))
209 self.images.append (image)
210 else:
211 print "error: image regex failed for: %s" % line
212
Greg Clayton2f9ca7b2011-09-26 18:39:23 +0000213 elif parse_mode == PARSE_MODE_THREGS:
214 stripped_line = line.strip()
215 reg_values = stripped_line.split(' ')
216 for reg_value in reg_values:
217 (reg, value) = reg_value.split(': ')
218 thread.registers[reg.strip()] = int(value, 0)
219 elif parse_mode == PARSE_MODE_SYSTEM:
220 self.system_profile.append(line)
221 f.close()
222
223 def dump(self):
224 print "Crash Log File: %s" % (self.path)
225 print "\nThreads:"
226 for thread in self.threads:
227 thread.dump(' ')
228 print "\nImages:"
229 for image in self.images:
230 image.dump(' ')
231
232def disassemble_instructions (target, instructions, pc, insts_before_pc, insts_after_pc):
233 lines = list()
234 pc_index = -1
235 comment_column = 50
236 for inst_idx, inst in enumerate(instructions):
237 inst_pc = inst.GetAddress().GetLoadAddress(target);
238 if pc == inst_pc:
239 pc_index = inst_idx
Greg Claytonfb0655e2011-09-27 00:58:45 +0000240 mnemonic = inst.GetMnemonic (target)
241 operands = inst.GetOperands (target)
242 comment = inst.GetComment (target)
243 #data = inst.GetData (target)
244 lines.append ("%#16.16x: %8s %s" % (inst_pc, mnemonic, operands))
Greg Clayton2f9ca7b2011-09-26 18:39:23 +0000245 if comment:
246 line_len = len(lines[-1])
247 if line_len < comment_column:
248 lines[-1] += ' ' * (comment_column - line_len)
249 lines[-1] += "; %s" % comment
250
251 if pc_index >= 0:
252 if pc_index >= insts_before_pc:
253 start_idx = pc_index - insts_before_pc
254 else:
255 start_idx = 0
256 end_idx = pc_index + insts_after_pc
257 if end_idx > inst_idx:
258 end_idx = inst_idx
259 for i in range(start_idx, end_idx+1):
260 if i == pc_index:
261 print ' -> ', lines[i]
262 else:
263 print ' ', lines[i]
264
265def print_module_section_data (section):
266 print section
267 section_data = section.GetSectionData()
268 if section_data:
269 ostream = lldb.SBStream()
270 section_data.GetDescription (ostream, section.GetFileAddress())
271 print ostream.GetData()
272
273def print_module_section (section, depth):
274 print section
275
276 if depth > 0:
277 num_sub_sections = section.GetNumSubSections()
278 for sect_idx in range(num_sub_sections):
279 print_module_section (section.GetSubSectionAtIndex(sect_idx), depth - 1)
280
281def print_module_sections (module, depth):
Johnny Chene7e4ac42011-10-06 22:48:56 +0000282 for sect in module.section_iter():
283 print_module_section (sect, depth)
Greg Clayton2f9ca7b2011-09-26 18:39:23 +0000284
285def print_module_symbols (module):
Johnny Chene7e4ac42011-10-06 22:48:56 +0000286 for sym in module:
287 print sym
Greg Clayton2f9ca7b2011-09-26 18:39:23 +0000288
289def usage():
290 print "Usage: lldb-symbolicate.py [-n name] executable-image"
291 sys.exit(0)
292
293
294if __name__ == '__main__':
295 parser = optparse.OptionParser(description='A script that parses skinny and universal mach-o files.')
296 parser.add_option('--arch', type='string', metavar='arch', dest='triple', help='specify one architecture or target triple')
297 parser.add_option('--platform', type='string', metavar='platform', dest='platform', help='specify one platform by name')
298 parser.add_option('--verbose', action='store_true', dest='verbose', help='display verbose debug info', default=False)
299 parser.add_option('--interactive', action='store_true', dest='interactive', help='enable interactive mode', default=False)
300 parser.add_option('--no-images', action='store_false', dest='show_images', help='don\'t show images in stack frames', default=True)
301 parser.add_option('--no-dependents', action='store_false', dest='dependents', help='skip loading dependent modules', default=True)
302 parser.add_option('--sections', action='store_true', dest='dump_sections', help='show module sections', default=False)
303 parser.add_option('--symbols', action='store_true', dest='dump_symbols', help='show module symbols', default=False)
304 parser.add_option('--image-list', action='store_true', dest='dump_image_list', help='show image list', default=False)
305 parser.add_option('--debug-delay', type='int', dest='debug_delay', metavar='NSEC', help='pause for NSEC seconds for debugger', default=0)
306 parser.add_option('--section-depth', type='int', dest='section_depth', help='set the section depth to use when showing sections', default=0)
307 parser.add_option('--section-data', type='string', action='append', dest='sect_data_names', help='specify sections by name to display data for')
308 parser.add_option('--address', type='int', action='append', dest='addresses', help='specify addresses to lookup')
309 parser.add_option('--crash-log', type='string', action='append', dest='crash_log_files', help='specify crash log files to symbolicate')
310 parser.add_option('--crashed-only', action='store_true', dest='crashed_only', help='only show the crashed thread', default=False)
311 loaded_addresses = False
312 (options, args) = parser.parse_args()
313 if options.verbose:
314 print 'options', options
315
316 if options.debug_delay > 0:
317 print "Waiting %u seconds for debugger to attach..." % options.debug_delay
318 time.sleep(options.debug_delay)
319
320 # Create a new debugger instance
321 debugger = lldb.SBDebugger.Create()
322
323 # When we step or continue, don't return from the function until the process
324 # stops. We do this by setting the async mode to false.
325 debugger.SetAsync (False)
326 error = lldb.SBError()
327
328 if options.crash_log_files:
329 options.dependents = False
330 for crash_log_file in options.crash_log_files:
331 triple = "x86_64"
332 crash_log = CrashLog(crash_log_file)
333 #crash_log.dump()
334 target = debugger.CreateTarget (crash_log.process_path, options.triple, options.platform, options.dependents, error);
335 exe_module = target.GetModuleAtIndex(0)
Greg Claytona6e42922011-09-26 19:17:49 +0000336 image_paths = list()
Greg Clayton2f9ca7b2011-09-26 18:39:23 +0000337 for image in crash_log.images:
338 if image.path == crash_log.process_path:
339 module = exe_module
340 else:
341 module = target.AddModule (image.path, options.triple, image.uuid)
Greg Claytona6e42922011-09-26 19:17:49 +0000342 if image.path in image_paths:
Greg Clayton2f9ca7b2011-09-26 18:39:23 +0000343 print "warning: skipping %s loaded at %#16.16x duplicate entry (probably commpage)" % (image.path, image.text_addr_lo)
344 else:
Greg Claytona6e42922011-09-26 19:17:49 +0000345 image_paths.append(image.path)
346
347 if not module and image.uuid != module.GetUUIDString():
348 if image.uuid:
349 print "warning: couldn't locate %s %s" % (image.uuid, image.path)
350 else:
351 print "warning: couldn't locate %s" % (image.path)
352 else:
353 target.SetSectionLoadAddress (module.FindSection ("__TEXT"), image.text_addr_lo)
Greg Clayton2f9ca7b2011-09-26 18:39:23 +0000354 for line in crash_log.info_lines:
355 print line
Greg Clayton2f9ca7b2011-09-26 18:39:23 +0000356 # Reconstruct inlined frames for all threads for anything that has debug info
357 for thread in crash_log.threads:
358 if options.crashed_only and thread.did_crash() == False:
359 continue
360 # start a new frame list that we will fixup for each thread
361 new_thread_frames = list()
362 # Iterate through all concrete frames for a thread and resolve
363 # any parent frames of inlined functions
364 for frame_idx, frame in enumerate(thread.frames):
365 # Resolve the frame's pc into a section + offset address 'pc_addr'
366 pc_addr = target.ResolveLoadAddress (frame.pc)
367 # Check to see if we were able to resolve the address
368 if pc_addr:
369 # We were able to resolve the frame's PC into a section offset
370 # address.
371
372 # Resolve the frame's PC value into a symbol context. A symbol
373 # context can resolve a module, compile unit, function, block,
374 # line table entry and/or symbol. If the frame has a block, then
375 # we can look for inlined frames, which are represented by blocks
376 # that have inlined information in them
377 frame.sym_ctx = target.ResolveSymbolContextForAddress (pc_addr, lldb.eSymbolContextEverything);
378
379 # dump if the verbose option was specified
380 if options.verbose:
381 print "frame.pc = %#16.16x (file_addr = %#16.16x)" % (frame.pc, pc_addr.GetFileAddress())
382 print "frame.pc_addr = ", pc_addr
383 print "frame.sym_ctx = "
384 print frame.sym_ctx
385 print
386
387 # Append the frame we already had from the crash log to the new
388 # frames list
389 new_thread_frames.append(frame)
390
391 new_frame = CrashLog.Frame (frame.index, -1, None)
392
393 # Try and use the current frame's symbol context to calculate a
394 # parent frame for an inlined function. If the curent frame is
395 # inlined, it will return a valid symbol context for the parent
396 # frame of the current inlined function
397 parent_pc_addr = lldb.SBAddress()
Greg Clayton1ed54f52011-10-01 00:45:15 +0000398 new_frame.sym_ctx = frame.sym_ctx.GetParentOfInlinedScope (pc_addr, parent_pc_addr)
Greg Clayton2f9ca7b2011-09-26 18:39:23 +0000399
400 # See if we were able to reconstruct anything?
401 while new_frame.sym_ctx:
402 # We have a parent frame of an inlined frame, create a new frame
403 # Convert the section + offset 'parent_pc_addr' to a load address
404 new_frame.pc = parent_pc_addr.GetLoadAddress(target)
405 # push the new frame onto the new frame stack
406 new_thread_frames.append (new_frame)
407 # dump if the verbose option was specified
408 if options.verbose:
409 print "new_frame.pc = %#16.16x (%s)" % (new_frame.pc, parent_pc_addr)
410 print "new_frame.sym_ctx = "
411 print new_frame.sym_ctx
412 print
413 # Create another new frame in case we have multiple inlined frames
414 prev_new_frame = new_frame
415 new_frame = CrashLog.Frame (frame.index, -1, None)
416 # Swap the addresses so we can try another inlined lookup
417 pc_addr = parent_pc_addr;
Greg Clayton1ed54f52011-10-01 00:45:15 +0000418 new_frame.sym_ctx = prev_new_frame.sym_ctx.GetParentOfInlinedScope (pc_addr, parent_pc_addr)
Greg Clayton2f9ca7b2011-09-26 18:39:23 +0000419 # Replace our thread frames with our new list that includes parent
420 # frames for inlined functions
421 thread.frames = new_thread_frames
422 # Now iterate through all threads and display our richer stack backtraces
423 for thread in crash_log.threads:
424 this_thread_crashed = thread.did_crash()
425 if options.crashed_only and this_thread_crashed == False:
426 continue
427 print "%s" % thread
428 prev_frame_index = -1
429 for frame_idx, frame in enumerate(thread.frames):
Greg Claytona6e42922011-09-26 19:17:49 +0000430 details = ' %s' % frame.details
Greg Clayton2f9ca7b2011-09-26 18:39:23 +0000431 module = frame.sym_ctx.GetModule()
432 instructions = None
433 if module:
434 module_basename = module.GetFileSpec().GetFilename();
435 function_start_load_addr = -1
436 function_name = None
437 function = frame.sym_ctx.GetFunction()
438 block = frame.sym_ctx.GetBlock()
439 line_entry = frame.sym_ctx.GetLineEntry()
440 symbol = frame.sym_ctx.GetSymbol()
441 inlined_block = block.GetContainingInlinedBlock();
442 if inlined_block:
443 function_name = inlined_block.GetInlinedName();
444 block_range_idx = inlined_block.GetRangeIndexForBlockAddress (target.ResolveLoadAddress (frame.pc))
445 if block_range_idx < lldb.UINT32_MAX:
446 block_range_start_addr = inlined_block.GetRangeStartAddress (block_range_idx)
447 function_start_load_addr = block_range_start_addr.GetLoadAddress (target)
448 else:
449 function_start_load_addr = frame.pc
450 if this_thread_crashed and frame_idx == 0:
451 instructions = function.GetInstructions(target)
452 elif function:
453 function_name = function.GetName()
454 function_start_load_addr = function.GetStartAddress().GetLoadAddress (target)
455 if this_thread_crashed and frame_idx == 0:
456 instructions = function.GetInstructions(target)
457 elif symbol:
458 function_name = symbol.GetName()
459 function_start_load_addr = symbol.GetStartAddress().GetLoadAddress (target)
460 if this_thread_crashed and frame_idx == 0:
461 instructions = symbol.GetInstructions(target)
462
463 if function_name:
464 # Print the function or symbol name and annotate if it was inlined
465 inline_suffix = ''
466 if inlined_block:
467 inline_suffix = '[inlined] '
468 else:
469 inline_suffix = ' '
470 if options.show_images:
471 details = "%s%s`%s" % (inline_suffix, module_basename, function_name)
472 else:
473 details = "%s" % (function_name)
474 # Dump the offset from the current function or symbol if it is non zero
475 function_offset = frame.pc - function_start_load_addr
476 if function_offset > 0:
477 details += " + %u" % (function_offset)
478 elif function_offset < 0:
479 defaults += " %i (invalid negative offset, file a bug) " % function_offset
480 # Print out any line information if any is available
481 if line_entry.GetFileSpec():
482 details += ' at %s' % line_entry.GetFileSpec().GetFilename()
483 details += ':%u' % line_entry.GetLine ()
484 column = line_entry.GetColumn()
485 if column > 0:
486 details += ':%u' % column
Greg Clayton2f9ca7b2011-09-26 18:39:23 +0000487
488
489 # Only print out the concrete frame index if it changes.
490 # if prev_frame_index != frame.index:
491 # print "[%2u] %#16.16x %s" % (frame.index, frame.pc, details)
492 # else:
493 # print " %#16.16x %s" % (frame.pc, details)
494 print "[%2u] %#16.16x %s" % (frame.index, frame.pc, details)
495 prev_frame_index = frame.index
496 if instructions:
497 print
498 disassemble_instructions (target, instructions, frame.pc, 4, 4)
499 print
500
501 print
502
503 if options.dump_image_list:
504 print "Binary Images:"
505 for image in crash_log.images:
506 print image
507 else:
508 for exe_file in args:
509
510 # Create a target from a file and arch
511 print "Creating a target for '%s'" % exe_file
512
513 target = debugger.CreateTarget (exe_file, options.triple, options.platform, options.dependents, error);
514
515 if target:
516 exe_module = None;
517 module_count = target.GetNumModules();
518 for module_idx in range(module_count):
519 module = target.GetModuleAtIndex (module_idx)
520 if module_idx == 0:
521 exe_module = module
522 print "module[%u] = %s" % (module_idx, module)
523
524 if options.dump_symbols:
525 print_module_symbols (module)
526 if options.dump_sections:
527 print_module_sections (module, options.section_depth)
528 if options.sect_data_names:
529 for sect_name in options.sect_data_names:
530 section = module.FindSection (sect_name)
531 if section:
532 print_module_section_data (section)
533 else:
534 print "No section was found in '%s' named '%s'" % (module, sect_name)
535 if options.addresses:
536 for address in options.addresses:
537 if loaded_addresses:
538 so_address = target.ResolveLoadAddress (address)
539 if so_address:
540 print so_address
541 so_address_sc = exe_module.ResolveSymbolContextForAddress (so_address, lldb.eSymbolContextEverything);
542 print so_address_sc
543 else:
544 print "error: 0x%8.8x failed to resolve as a load address" % (address)
545 else:
546 so_address = exe_module.ResolveFileAddress (address)
547
548 if so_address:
549 print so_address
550 so_address_sc = exe_module.ResolveSymbolContextForAddress (so_address, lldb.eSymbolContextEverything);
551 print so_address_sc
552 else:
553 print "error: 0x%8.8x failed to resolve as a file address in %s" % (address, exe_module)
554
555 # text_base_addr = 0x10000
556 # load_addr = 0x10bb0
557 # text_segment = exe_module.FindSection ("__TEXT")
558 # if text_segment:
559 # target.SetSectionLoadAddress (text_segment, text_base_addr)
560 #
561 # load_so_addr = target.ResolveLoadAddress (load_addr)
562 #
563 # if load_so_addr:
564 # sc = target.ResolveSymbolContextForAddress (so_addr, lldb.eSymbolContextEverything);
565 # print sc
566 # else:
567 # print "error: 0x%8.8x failed to resolve as a load address" % (load_addr)
568 else:
569 print "error: ", error
570
571
572 lldb.SBDebugger.Terminate()
573