2 This LLDB module contains miscellaneous utilities.
3 Some of the test suite takes advantage of the utility functions defined here.
4 They can also be useful for general purpose lldb scripting.
7 from __future__
import print_function
8 from __future__
import absolute_import
17 from six
import StringIO
as SixStringIO
22 from . import lldbtest_config
25 # ===================================================
26 # Utilities for locating/checking executable programs
27 # ===================================================
30 """Returns True if fpath is an executable."""
31 return os
.path
.isfile(fpath
) and os
.access(fpath
, os
.X_OK
)
35 """Returns the full path to a program; None otherwise."""
36 fpath
, fname
= os
.path
.split(program
)
41 for path
in os
.environ
["PATH"].split(os
.pathsep
):
42 exe_file
= os
.path
.join(path
, program
)
51 if e
.errno
!= errno
.EEXIST
:
53 if not os
.path
.isdir(path
):
54 raise OSError(errno
.ENOTDIR
, "%s is not a directory"%path
)
55 # ===================================================
56 # Disassembly for an SBFunction or an SBSymbol object
57 # ===================================================
60 def disassemble(target
, function_or_symbol
):
61 """Disassemble the function or symbol given a target.
63 It returns the disassembly content in a string object.
66 insts
= function_or_symbol
.GetInstructions(target
)
71 # ==========================================================
72 # Integer (byte size 1, 2, 4, and 8) to bytearray conversion
73 # ==========================================================
76 def int_to_bytearray(val
, bytesize
):
77 """Utility function to convert an integer into a bytearray.
79 It returns the bytearray in the little endian format. It is easy to get the
80 big endian format, just do ba.reverse() on the returned object.
85 return bytearray([val
])
87 # Little endian followed by a format character.
98 packed
= struct
.pack(fmt
, val
)
99 return bytearray(packed
)
102 def bytearray_to_int(bytes
, bytesize
):
103 """Utility function to convert a bytearray into an integer.
105 It interprets the bytearray in the little endian format. For a big endian
106 bytearray, just do ba.reverse() on the object before passing it in.
113 # Little endian followed by a format character.
124 unpacked
= struct
.unpack_from(fmt
, bytes
)
128 # ==============================================================
129 # Get the description of an lldb object or None if not available
130 # ==============================================================
131 def get_description(obj
, option
=None):
132 """Calls lldb_obj.GetDescription() and returns a string, or None.
134 For SBTarget, SBBreakpointLocation, and SBWatchpoint lldb objects, an extra
135 option can be passed in to describe the detailed level of description
137 o lldb.eDescriptionLevelBrief
138 o lldb.eDescriptionLevelFull
139 o lldb.eDescriptionLevelVerbose
141 method
= getattr(obj
, 'GetDescription')
144 tuple = (lldb
.SBTarget
, lldb
.SBBreakpointLocation
, lldb
.SBWatchpoint
)
145 if isinstance(obj
, tuple):
147 option
= lldb
.eDescriptionLevelBrief
149 stream
= lldb
.SBStream()
151 success
= method(stream
)
153 success
= method(stream
, option
)
156 return stream
.GetData()
159 # =================================================
160 # Convert some enum value to its string counterpart
161 # =================================================
163 def state_type_to_str(enum
):
164 """Returns the stateType string given an enum."""
165 if enum
== lldb
.eStateInvalid
:
167 elif enum
== lldb
.eStateUnloaded
:
169 elif enum
== lldb
.eStateConnected
:
171 elif enum
== lldb
.eStateAttaching
:
173 elif enum
== lldb
.eStateLaunching
:
175 elif enum
== lldb
.eStateStopped
:
177 elif enum
== lldb
.eStateRunning
:
179 elif enum
== lldb
.eStateStepping
:
181 elif enum
== lldb
.eStateCrashed
:
183 elif enum
== lldb
.eStateDetached
:
185 elif enum
== lldb
.eStateExited
:
187 elif enum
== lldb
.eStateSuspended
:
190 raise Exception("Unknown StateType enum")
193 def stop_reason_to_str(enum
):
194 """Returns the stopReason string given an enum."""
195 if enum
== lldb
.eStopReasonInvalid
:
197 elif enum
== lldb
.eStopReasonNone
:
199 elif enum
== lldb
.eStopReasonTrace
:
201 elif enum
== lldb
.eStopReasonBreakpoint
:
203 elif enum
== lldb
.eStopReasonWatchpoint
:
205 elif enum
== lldb
.eStopReasonExec
:
207 elif enum
== lldb
.eStopReasonSignal
:
209 elif enum
== lldb
.eStopReasonException
:
211 elif enum
== lldb
.eStopReasonPlanComplete
:
212 return "plancomplete"
213 elif enum
== lldb
.eStopReasonThreadExiting
:
214 return "threadexiting"
216 raise Exception("Unknown StopReason enum")
219 def symbol_type_to_str(enum
):
220 """Returns the symbolType string given an enum."""
221 if enum
== lldb
.eSymbolTypeInvalid
:
223 elif enum
== lldb
.eSymbolTypeAbsolute
:
225 elif enum
== lldb
.eSymbolTypeCode
:
227 elif enum
== lldb
.eSymbolTypeData
:
229 elif enum
== lldb
.eSymbolTypeTrampoline
:
231 elif enum
== lldb
.eSymbolTypeRuntime
:
233 elif enum
== lldb
.eSymbolTypeException
:
235 elif enum
== lldb
.eSymbolTypeSourceFile
:
237 elif enum
== lldb
.eSymbolTypeHeaderFile
:
239 elif enum
== lldb
.eSymbolTypeObjectFile
:
241 elif enum
== lldb
.eSymbolTypeCommonBlock
:
243 elif enum
== lldb
.eSymbolTypeBlock
:
245 elif enum
== lldb
.eSymbolTypeLocal
:
247 elif enum
== lldb
.eSymbolTypeParam
:
249 elif enum
== lldb
.eSymbolTypeVariable
:
251 elif enum
== lldb
.eSymbolTypeVariableType
:
252 return "variabletype"
253 elif enum
== lldb
.eSymbolTypeLineEntry
:
255 elif enum
== lldb
.eSymbolTypeLineHeader
:
257 elif enum
== lldb
.eSymbolTypeScopeBegin
:
259 elif enum
== lldb
.eSymbolTypeScopeEnd
:
261 elif enum
== lldb
.eSymbolTypeAdditional
:
263 elif enum
== lldb
.eSymbolTypeCompiler
:
265 elif enum
== lldb
.eSymbolTypeInstrumentation
:
266 return "instrumentation"
267 elif enum
== lldb
.eSymbolTypeUndefined
:
271 def value_type_to_str(enum
):
272 """Returns the valueType string given an enum."""
273 if enum
== lldb
.eValueTypeInvalid
:
275 elif enum
== lldb
.eValueTypeVariableGlobal
:
276 return "global_variable"
277 elif enum
== lldb
.eValueTypeVariableStatic
:
278 return "static_variable"
279 elif enum
== lldb
.eValueTypeVariableArgument
:
280 return "argument_variable"
281 elif enum
== lldb
.eValueTypeVariableLocal
:
282 return "local_variable"
283 elif enum
== lldb
.eValueTypeRegister
:
285 elif enum
== lldb
.eValueTypeRegisterSet
:
286 return "register_set"
287 elif enum
== lldb
.eValueTypeConstResult
:
288 return "constant_result"
290 raise Exception("Unknown ValueType enum")
293 # ==================================================
294 # Get stopped threads due to each stop reason.
295 # ==================================================
297 def sort_stopped_threads(process
,
298 breakpoint_threads
=None,
299 crashed_threads
=None,
300 watchpoint_threads
=None,
302 exiting_threads
=None,
304 """ Fills array *_threads with threads stopped for the corresponding stop
307 for lst
in [breakpoint_threads
,
315 for thread
in process
:
317 for (reason
, list) in [(lldb
.eStopReasonBreakpoint
, breakpoint_threads
),
318 (lldb
.eStopReasonException
, crashed_threads
),
319 (lldb
.eStopReasonWatchpoint
, watchpoint_threads
),
320 (lldb
.eStopReasonSignal
, signal_threads
),
321 (lldb
.eStopReasonThreadExiting
, exiting_threads
),
322 (None, other_threads
)]:
323 if not dispatched
and list is not None:
324 if thread
.GetStopReason() == reason
or reason
is None:
328 # ==================================================
329 # Utility functions for setting breakpoints
330 # ==================================================
332 def run_break_set_by_script(
336 num_expected_locations
=1):
337 """Set a scripted breakpoint. Check that it got the right number of locations."""
338 test
.assertTrue(class_name
is not None, "Must pass in a class name.")
339 command
= "breakpoint set -P " + class_name
340 if extra_options
is not None:
341 command
+= " " + extra_options
343 break_results
= run_break_set_command(test
, command
)
344 check_breakpoint_result(test
, break_results
, num_locations
=num_expected_locations
)
345 return get_bpno_from_match(break_results
)
347 def run_break_set_by_file_and_line(
352 num_expected_locations
=1,
355 """Set a breakpoint by file and line, returning the breakpoint number.
357 If extra_options is not None, then we append it to the breakpoint set command.
359 If num_expected_locations is -1, we check that we got AT LEAST one location. If num_expected_locations is -2, we don't
360 check the actual number at all. Otherwise, we check that num_expected_locations equals the number of locations.
362 If loc_exact is true, we check that there is one location, and that location must be at the input file and line number."""
364 if file_name
is None:
365 command
= 'breakpoint set -l %d' % (line_number
)
367 command
= 'breakpoint set -f "%s" -l %d' % (file_name
, line_number
)
370 command
+= " --shlib '%s'" % (module_name
)
373 command
+= " " + extra_options
375 break_results
= run_break_set_command(test
, command
)
377 if num_expected_locations
== 1 and loc_exact
:
378 check_breakpoint_result(
381 num_locations
=num_expected_locations
,
383 line_number
=line_number
,
384 module_name
=module_name
)
386 check_breakpoint_result(
389 num_locations
=num_expected_locations
)
391 return get_bpno_from_match(break_results
)
394 def run_break_set_by_symbol(
398 num_expected_locations
=-1,
401 """Set a breakpoint by symbol name. Common options are the same as run_break_set_by_file_and_line.
403 If sym_exact is true, then the output symbol must match the input exactly, otherwise we do a substring match."""
404 command
= 'breakpoint set -n "%s"' % (symbol
)
407 command
+= " --shlib '%s'" % (module_name
)
410 command
+= " " + extra_options
412 break_results
= run_break_set_command(test
, command
)
414 if num_expected_locations
== 1 and sym_exact
:
415 check_breakpoint_result(
418 num_locations
=num_expected_locations
,
420 module_name
=module_name
)
422 check_breakpoint_result(
425 num_locations
=num_expected_locations
)
427 return get_bpno_from_match(break_results
)
430 def run_break_set_by_selector(
434 num_expected_locations
=-1,
436 """Set a breakpoint by selector. Common options are the same as run_break_set_by_file_and_line."""
438 command
= 'breakpoint set -S "%s"' % (selector
)
441 command
+= ' --shlib "%s"' % (module_name
)
444 command
+= " " + extra_options
446 break_results
= run_break_set_command(test
, command
)
448 if num_expected_locations
== 1:
449 check_breakpoint_result(
452 num_locations
=num_expected_locations
,
453 symbol_name
=selector
,
454 symbol_match_exact
=False,
455 module_name
=module_name
)
457 check_breakpoint_result(
460 num_locations
=num_expected_locations
)
462 return get_bpno_from_match(break_results
)
465 def run_break_set_by_regexp(
469 num_expected_locations
=-1):
470 """Set a breakpoint by regular expression match on symbol name. Common options are the same as run_break_set_by_file_and_line."""
472 command
= 'breakpoint set -r "%s"' % (regexp
)
474 command
+= " " + extra_options
476 break_results
= run_break_set_command(test
, command
)
478 check_breakpoint_result(
481 num_locations
=num_expected_locations
)
483 return get_bpno_from_match(break_results
)
486 def run_break_set_by_source_regexp(
490 num_expected_locations
=-1):
491 """Set a breakpoint by source regular expression. Common options are the same as run_break_set_by_file_and_line."""
492 command
= 'breakpoint set -p "%s"' % (regexp
)
494 command
+= " " + extra_options
496 break_results
= run_break_set_command(test
, command
)
498 check_breakpoint_result(
501 num_locations
=num_expected_locations
)
503 return get_bpno_from_match(break_results
)
506 def run_break_set_command(test
, command
):
507 """Run the command passed in - it must be some break set variant - and analyze the result.
508 Returns a dictionary of information gleaned from the command-line results.
509 Will assert if the breakpoint setting fails altogether.
511 Dictionary will contain:
512 bpno - breakpoint of the newly created breakpoint, -1 on error.
513 num_locations - number of locations set for the breakpoint.
515 If there is only one location, the dictionary MAY contain:
516 file - source file name
517 line_no - source line number
519 inline_symbol - inlined symbol name
520 offset - offset from the original symbol
522 address - address at which the breakpoint was set."""
525 r
"^Breakpoint (?P<bpno>[0-9]+): (?P<num_locations>[0-9]+) locations\.$",
526 r
"^Breakpoint (?P<bpno>[0-9]+): (?P<num_locations>no) locations \(pending\)\.",
527 r
"^Breakpoint (?P<bpno>[0-9]+): where = (?P<module>.*)`(?P<symbol>[+\-]{0,1}[^+]+)( \+ (?P<offset>[0-9]+)){0,1}( \[inlined\] (?P<inline_symbol>.*)){0,1} at (?P<file>[^:]+):(?P<line_no>[0-9]+)(?P<column>(:[0-9]+)?), address = (?P<address>0x[0-9a-fA-F]+)$",
528 r
"^Breakpoint (?P<bpno>[0-9]+): where = (?P<module>.*)`(?P<symbol>.*)( \+ (?P<offset>[0-9]+)){0,1}, address = (?P<address>0x[0-9a-fA-F]+)$"]
529 match_object
= test
.match(command
, patterns
)
530 break_results
= match_object
.groupdict()
532 # We always insert the breakpoint number, setting it to -1 if we couldn't find it
533 # Also, make sure it gets stored as an integer.
534 if not 'bpno' in break_results
:
535 break_results
['bpno'] = -1
537 break_results
['bpno'] = int(break_results
['bpno'])
539 # We always insert the number of locations
540 # If ONE location is set for the breakpoint, then the output doesn't mention locations, but it has to be 1...
541 # We also make sure it is an integer.
543 if not 'num_locations' in break_results
:
546 num_locations
= break_results
['num_locations']
547 if num_locations
== 'no':
550 num_locations
= int(break_results
['num_locations'])
552 break_results
['num_locations'] = num_locations
554 if 'line_no' in break_results
:
555 break_results
['line_no'] = int(break_results
['line_no'])
560 def get_bpno_from_match(break_results
):
561 return int(break_results
['bpno'])
564 def check_breakpoint_result(
570 symbol_match_exact
=True,
575 out_num_locations
= break_results
['num_locations']
577 if num_locations
== -1:
578 test
.assertTrue(out_num_locations
> 0,
579 "Expecting one or more locations, got none.")
580 elif num_locations
!= -2:
582 num_locations
== out_num_locations
,
583 "Expecting %d locations, got %d." %
589 if 'file' in break_results
:
590 out_file_name
= break_results
['file']
592 file_name
.endswith(out_file_name
),
593 "Breakpoint file name '%s' doesn't match resultant name '%s'." %
597 if line_number
!= -1:
599 if 'line_no' in break_results
:
600 out_line_number
= break_results
['line_no']
603 line_number
== out_line_number
,
604 "Breakpoint line number %s doesn't match resultant line %s." %
610 # Look first for the inlined symbol name, otherwise use the symbol
612 if 'inline_symbol' in break_results
and break_results
['inline_symbol']:
613 out_symbol_name
= break_results
['inline_symbol']
614 elif 'symbol' in break_results
:
615 out_symbol_name
= break_results
['symbol']
617 if symbol_match_exact
:
619 symbol_name
== out_symbol_name
,
620 "Symbol name '%s' doesn't match resultant symbol '%s'." %
625 out_symbol_name
.find(symbol_name
) != -
627 "Symbol name '%s' isn't in resultant symbol '%s'." %
632 out_module_name
= None
633 if 'module' in break_results
:
634 out_module_name
= break_results
['module']
637 module_name
.find(out_module_name
) != -
639 "Symbol module name '%s' isn't in expected module name '%s'." %
643 # ==================================================
644 # Utility functions related to Threads and Processes
645 # ==================================================
648 def get_stopped_threads(process
, reason
):
649 """Returns the thread(s) with the specified stop reason in a list.
651 The list can be empty if no such thread exists.
655 if t
.GetStopReason() == reason
:
660 def get_stopped_thread(process
, reason
):
661 """A convenience function which returns the first thread with the given stop
666 1. Get the stopped thread due to a breakpoint condition
669 from lldbutil import get_stopped_thread
670 thread = get_stopped_thread(process, lldb.eStopReasonPlanComplete)
671 self.assertTrue(thread.IsValid(), "There should be a thread stopped due to breakpoint condition")
674 2. Get the thread stopped due to a breakpoint
677 from lldbutil import get_stopped_thread
678 thread = get_stopped_thread(process, lldb.eStopReasonBreakpoint)
679 self.assertTrue(thread.IsValid(), "There should be a thread stopped due to breakpoint")
683 threads
= get_stopped_threads(process
, reason
)
684 if len(threads
) == 0:
689 def get_threads_stopped_at_breakpoint_id(process
, bpid
):
690 """ For a stopped process returns the thread stopped at the breakpoint passed in bkpt"""
694 stopped_threads
= get_stopped_threads(process
, lldb
.eStopReasonBreakpoint
)
696 if len(stopped_threads
) == 0:
699 for thread
in stopped_threads
:
700 # Make sure we've hit our breakpoint...
701 break_id
= thread
.GetStopReasonDataAtIndex(0)
703 threads
.append(thread
)
708 def get_threads_stopped_at_breakpoint(process
, bkpt
):
709 return get_threads_stopped_at_breakpoint_id(process
, bkpt
.GetID())
712 def get_one_thread_stopped_at_breakpoint_id(
713 process
, bpid
, require_exactly_one
=True):
714 threads
= get_threads_stopped_at_breakpoint_id(process
, bpid
)
715 if len(threads
) == 0:
717 if require_exactly_one
and len(threads
) != 1:
723 def get_one_thread_stopped_at_breakpoint(
724 process
, bkpt
, require_exactly_one
=True):
725 return get_one_thread_stopped_at_breakpoint_id(
726 process
, bkpt
.GetID(), require_exactly_one
)
729 def is_thread_crashed(test
, thread
):
730 """In the test suite we dereference a null pointer to simulate a crash. The way this is
731 reported depends on the platform."""
732 if test
.platformIsDarwin():
733 return thread
.GetStopReason(
734 ) == lldb
.eStopReasonException
and "EXC_BAD_ACCESS" in thread
.GetStopDescription(100)
735 elif test
.getPlatform() == "linux":
736 return thread
.GetStopReason() == lldb
.eStopReasonSignal
and thread
.GetStopReasonDataAtIndex(
737 0) == thread
.GetProcess().GetUnixSignals().GetSignalNumberFromName("SIGSEGV")
738 elif test
.getPlatform() == "windows":
739 return "Exception 0xc0000005" in thread
.GetStopDescription(200)
741 return "invalid address" in thread
.GetStopDescription(100)
744 def get_crashed_threads(test
, process
):
746 if process
.GetState() != lldb
.eStateStopped
:
748 for thread
in process
:
749 if is_thread_crashed(test
, thread
):
750 threads
.append(thread
)
753 # Helper functions for run_to_{source,name}_breakpoint:
755 def run_to_breakpoint_make_target(test
, exe_name
= "a.out", in_cwd
= True):
757 exe
= test
.getBuildArtifact(exe_name
)
760 target
= test
.dbg
.CreateTarget(exe
)
761 test
.assertTrue(target
, "Target: %s is not valid."%(exe_name))
763 # Set environment variables for the inferior.
764 if lldbtest_config
.inferior_env
:
765 test
.runCmd('settings set target.env-vars {}'.format(
766 lldbtest_config
.inferior_env
))
770 def run_to_breakpoint_do_run(test
, target
, bkpt
, launch_info
= None,
771 only_one_thread
= True, extra_images
= None):
773 # Launch the process, and do not stop at the entry point.
775 launch_info
= target
.GetLaunchInfo()
776 launch_info
.SetWorkingDirectory(test
.get_process_working_directory())
778 if extra_images
and lldb
.remote_platform
:
779 environ
= test
.registerSharedLibrariesWithTarget(target
, extra_images
)
780 launch_info
.SetEnvironmentEntries(environ
, True)
782 error
= lldb
.SBError()
783 process
= target
.Launch(launch_info
, error
)
785 test
.assertTrue(process
,
786 "Could not create a valid process for %s: %s"%(target
.GetExecutable().GetFilename(),
788 test
.assertFalse(error
.Fail(),
789 "Process launch failed: %s" % (error
.GetCString()))
791 # Frame #0 should be at our breakpoint.
792 threads
= get_threads_stopped_at_breakpoint(
795 num_threads
= len(threads
)
797 test
.assertEqual(num_threads
, 1, "Expected 1 thread to stop at breakpoint, %d did."%(num_threads))
799 test
.assertGreater(num_threads
, 0, "No threads stopped at breakpoint")
802 return (target
, process
, thread
, bkpt
)
804 def run_to_name_breakpoint (test
, bkpt_name
, launch_info
= None,
808 only_one_thread
= True,
809 extra_images
= None):
810 """Start up a target, using exe_name as the executable, and run it to
811 a breakpoint set by name on bkpt_name restricted to bkpt_module.
813 If you want to pass in launch arguments or environment
814 variables, you can optionally pass in an SBLaunchInfo. If you
815 do that, remember to set the working directory as well.
817 If your executable isn't called a.out, you can pass that in.
818 And if your executable isn't in the CWD, pass in the absolute
819 path to the executable in exe_name, and set in_cwd to False.
821 If you need to restrict the breakpoint to a particular module,
822 pass the module name (a string not a FileSpec) in bkpt_module. If
823 nothing is passed in setting will be unrestricted.
825 If the target isn't valid, the breakpoint isn't found, or hit, the
826 function will cause a testsuite failure.
828 If successful it returns a tuple with the target process and
829 thread that hit the breakpoint, and the breakpoint that we set
832 If only_one_thread is true, we require that there be only one
833 thread stopped at the breakpoint. Otherwise we only require one
834 or more threads stop there. If there are more than one, we return
835 the first thread that stopped.
838 target
= run_to_breakpoint_make_target(test
, exe_name
, in_cwd
)
840 breakpoint
= target
.BreakpointCreateByName(bkpt_name
, bkpt_module
)
843 test
.assertTrue(breakpoint
.GetNumLocations() > 0,
844 "No locations found for name breakpoint: '%s'."%(bkpt_name))
845 return run_to_breakpoint_do_run(test
, target
, breakpoint
, launch_info
,
846 only_one_thread
, extra_images
)
848 def run_to_source_breakpoint(test
, bkpt_pattern
, source_spec
,
849 launch_info
= None, exe_name
= "a.out",
852 only_one_thread
= True,
853 extra_images
= None):
854 """Start up a target, using exe_name as the executable, and run it to
855 a breakpoint set by source regex bkpt_pattern.
857 The rest of the behavior is the same as run_to_name_breakpoint.
860 target
= run_to_breakpoint_make_target(test
, exe_name
, in_cwd
)
861 # Set the breakpoints
862 breakpoint
= target
.BreakpointCreateBySourceRegex(
863 bkpt_pattern
, source_spec
, bkpt_module
)
864 test
.assertTrue(breakpoint
.GetNumLocations() > 0,
865 'No locations found for source breakpoint: "%s", file: "%s", dir: "%s"'
866 %(bkpt_pattern
, source_spec
.GetFilename(), source_spec
.GetDirectory()))
867 return run_to_breakpoint_do_run(test
, target
, breakpoint
, launch_info
,
868 only_one_thread
, extra_images
)
870 def run_to_line_breakpoint(test
, source_spec
, line_number
, column
= 0,
871 launch_info
= None, exe_name
= "a.out",
874 only_one_thread
= True,
875 extra_images
= None):
876 """Start up a target, using exe_name as the executable, and run it to
877 a breakpoint set by (source_spec, line_number(, column)).
879 The rest of the behavior is the same as run_to_name_breakpoint.
882 target
= run_to_breakpoint_make_target(test
, exe_name
, in_cwd
)
883 # Set the breakpoints
884 breakpoint
= target
.BreakpointCreateByLocation(
885 source_spec
, line_number
, column
, 0, lldb
.SBFileSpecList())
886 test
.assertTrue(breakpoint
.GetNumLocations() > 0,
887 'No locations found for line breakpoint: "%s:%d(:%d)", dir: "%s"'
888 %(source_spec
.GetFilename(), line_number
, column
,
889 source_spec
.GetDirectory()))
890 return run_to_breakpoint_do_run(test
, target
, breakpoint
, launch_info
,
891 only_one_thread
, extra_images
)
894 def continue_to_breakpoint(process
, bkpt
):
895 """ Continues the process, if it stops, returns the threads stopped at bkpt; otherwise, returns None"""
897 if process
.GetState() != lldb
.eStateStopped
:
900 return get_threads_stopped_at_breakpoint(process
, bkpt
)
903 def get_caller_symbol(thread
):
905 Returns the symbol name for the call site of the leaf function.
907 depth
= thread
.GetNumFrames()
910 caller
= thread
.GetFrameAtIndex(1).GetSymbol()
912 return caller
.GetName()
917 def get_function_names(thread
):
919 Returns a sequence of function names from the stack frames of this thread.
922 return thread
.GetFrameAtIndex(i
).GetFunctionName()
924 return list(map(GetFuncName
, list(range(thread
.GetNumFrames()))))
927 def get_symbol_names(thread
):
929 Returns a sequence of symbols for this thread.
932 return thread
.GetFrameAtIndex(i
).GetSymbol().GetName()
934 return list(map(GetSymbol
, list(range(thread
.GetNumFrames()))))
937 def get_pc_addresses(thread
):
939 Returns a sequence of pc addresses for this thread.
942 return thread
.GetFrameAtIndex(i
).GetPCAddress()
944 return list(map(GetPCAddress
, list(range(thread
.GetNumFrames()))))
947 def get_filenames(thread
):
949 Returns a sequence of file names from the stack frames of this thread.
952 return thread
.GetFrameAtIndex(
953 i
).GetLineEntry().GetFileSpec().GetFilename()
955 return list(map(GetFilename
, list(range(thread
.GetNumFrames()))))
958 def get_line_numbers(thread
):
960 Returns a sequence of line numbers from the stack frames of this thread.
962 def GetLineNumber(i
):
963 return thread
.GetFrameAtIndex(i
).GetLineEntry().GetLine()
965 return list(map(GetLineNumber
, list(range(thread
.GetNumFrames()))))
968 def get_module_names(thread
):
970 Returns a sequence of module names from the stack frames of this thread.
972 def GetModuleName(i
):
973 return thread
.GetFrameAtIndex(
974 i
).GetModule().GetFileSpec().GetFilename()
976 return list(map(GetModuleName
, list(range(thread
.GetNumFrames()))))
979 def get_stack_frames(thread
):
981 Returns a sequence of stack frames for this thread.
983 def GetStackFrame(i
):
984 return thread
.GetFrameAtIndex(i
)
986 return list(map(GetStackFrame
, list(range(thread
.GetNumFrames()))))
989 def print_stacktrace(thread
, string_buffer
=False):
990 """Prints a simple stack trace of this thread."""
992 output
= SixStringIO() if string_buffer
else sys
.stdout
993 target
= thread
.GetProcess().GetTarget()
995 depth
= thread
.GetNumFrames()
997 mods
= get_module_names(thread
)
998 funcs
= get_function_names(thread
)
999 symbols
= get_symbol_names(thread
)
1000 files
= get_filenames(thread
)
1001 lines
= get_line_numbers(thread
)
1002 addrs
= get_pc_addresses(thread
)
1004 if thread
.GetStopReason() != lldb
.eStopReasonInvalid
:
1005 desc
= "stop reason=" + stop_reason_to_str(thread
.GetStopReason())
1009 "Stack trace for thread id={0:#x} name={1} queue={2} ".format(
1010 thread
.GetThreadID(),
1012 thread
.GetQueueName()) + desc
,
1015 for i
in range(depth
):
1016 frame
= thread
.GetFrameAtIndex(i
)
1017 function
= frame
.GetFunction()
1019 load_addr
= addrs
[i
].GetLoadAddress(target
)
1021 file_addr
= addrs
[i
].GetFileAddress()
1022 start_addr
= frame
.GetSymbol().GetStartAddress().GetFileAddress()
1023 symbol_offset
= file_addr
- start_addr
1025 " frame #{num}: {addr:#016x} {mod}`{symbol} + {offset}".format(
1030 offset
=symbol_offset
),
1034 " frame #{num}: {addr:#016x} {mod}`{func} at {file}:{line} {args}".format(
1038 func
='%s [inlined]' %
1039 funcs
[i
] if frame
.IsInlined() else funcs
[i
],
1042 args
=get_args_as_string(
1044 showFuncName
=False) if not frame
.IsInlined() else '()'),
1048 return output
.getvalue()
1051 def print_stacktraces(process
, string_buffer
=False):
1052 """Prints the stack traces of all the threads."""
1054 output
= SixStringIO() if string_buffer
else sys
.stdout
1056 print("Stack traces for " + str(process
), file=output
)
1058 for thread
in process
:
1059 print(print_stacktrace(thread
, string_buffer
=True), file=output
)
1062 return output
.getvalue()
1065 def expect_state_changes(test
, listener
, process
, states
, timeout
=5):
1066 """Listens for state changed events on the listener and makes sure they match what we
1067 expect. Stop-and-restart events (where GetRestartedFromEvent() returns true) are ignored."""
1069 for expected_state
in states
:
1070 def get_next_event():
1071 event
= lldb
.SBEvent()
1072 if not listener
.WaitForEventForBroadcasterWithType(
1074 process
.GetBroadcaster(),
1075 lldb
.SBProcess
.eBroadcastBitStateChanged
,
1078 "Timed out while waiting for a transition to state %s" %
1079 lldb
.SBDebugger
.StateAsCString(expected_state
))
1082 event
= get_next_event()
1083 while (lldb
.SBProcess
.GetStateFromEvent(event
) == lldb
.eStateStopped
and
1084 lldb
.SBProcess
.GetRestartedFromEvent(event
)):
1085 # Ignore restarted event and the subsequent running event.
1086 event
= get_next_event()
1088 lldb
.SBProcess
.GetStateFromEvent(event
),
1090 "Restarted event followed by a running event")
1091 event
= get_next_event()
1094 lldb
.SBProcess
.GetStateFromEvent(event
),
1097 # ===================================
1098 # Utility functions related to Frames
1099 # ===================================
1102 def get_parent_frame(frame
):
1104 Returns the parent frame of the input frame object; None if not available.
1106 thread
= frame
.GetThread()
1107 parent_found
= False
1111 if f
.GetFrameID() == frame
.GetFrameID():
1114 # If we reach here, no parent has been found, return None.
1118 def get_args_as_string(frame
, showFuncName
=True):
1120 Returns the args of the input frame object as a string.
1125 # in_scope_only => True
1126 vars = frame
.GetVariables(True, False, False, True) # type of SBValueList
1127 args
= [] # list of strings
1129 args
.append("(%s)%s=%s" % (var
.GetTypeName(),
1132 if frame
.GetFunction():
1133 name
= frame
.GetFunction().GetName()
1134 elif frame
.GetSymbol():
1135 name
= frame
.GetSymbol().GetName()
1139 return "%s(%s)" % (name
, ", ".join(args
))
1141 return "(%s)" % (", ".join(args
))
1144 def print_registers(frame
, string_buffer
=False):
1145 """Prints all the register sets of the frame."""
1147 output
= SixStringIO() if string_buffer
else sys
.stdout
1149 print("Register sets for " + str(frame
), file=output
)
1151 registerSet
= frame
.GetRegisters() # Return type of SBValueList.
1152 print("Frame registers (size of register set = %d):" %
1153 registerSet
.GetSize(), file=output
)
1154 for value
in registerSet
:
1155 #print(value, file=output)
1156 print("%s (number of children = %d):" %
1157 (value
.GetName(), value
.GetNumChildren()), file=output
)
1160 "Name: %s, Value: %s" %
1166 return output
.getvalue()
1169 def get_registers(frame
, kind
):
1170 """Returns the registers given the frame and the kind of registers desired.
1172 Returns None if there's no such kind.
1174 registerSet
= frame
.GetRegisters() # Return type of SBValueList.
1175 for value
in registerSet
:
1176 if kind
.lower() in value
.GetName().lower():
1182 def get_GPRs(frame
):
1183 """Returns the general purpose registers of the frame as an SBValue.
1185 The returned SBValue object is iterable. An example:
1187 from lldbutil import get_GPRs
1188 regs = get_GPRs(frame)
1190 print("%s => %s" % (reg.GetName(), reg.GetValue()))
1193 return get_registers(frame
, "general purpose")
1196 def get_FPRs(frame
):
1197 """Returns the floating point registers of the frame as an SBValue.
1199 The returned SBValue object is iterable. An example:
1201 from lldbutil import get_FPRs
1202 regs = get_FPRs(frame)
1204 print("%s => %s" % (reg.GetName(), reg.GetValue()))
1207 return get_registers(frame
, "floating point")
1210 def get_ESRs(frame
):
1211 """Returns the exception state registers of the frame as an SBValue.
1213 The returned SBValue object is iterable. An example:
1215 from lldbutil import get_ESRs
1216 regs = get_ESRs(frame)
1218 print("%s => %s" % (reg.GetName(), reg.GetValue()))
1221 return get_registers(frame
, "exception state")
1223 # ======================================
1224 # Utility classes/functions for SBValues
1225 # ======================================
1228 class BasicFormatter(object):
1229 """The basic formatter inspects the value object and prints the value."""
1231 def format(self
, value
, buffer=None, indent
=0):
1233 output
= SixStringIO()
1236 # If there is a summary, it suffices.
1237 val
= value
.GetSummary()
1238 # Otherwise, get the value.
1240 val
= value
.GetValue()
1241 if val
is None and value
.GetNumChildren() > 0:
1242 val
= "%s (location)" % value
.GetLocation()
1243 print("{indentation}({type}) {name} = {value}".format(
1244 indentation
=' ' * indent
,
1245 type=value
.GetTypeName(),
1246 name
=value
.GetName(),
1247 value
=val
), file=output
)
1248 return output
.getvalue()
1251 class ChildVisitingFormatter(BasicFormatter
):
1252 """The child visiting formatter prints the value and its immediate children.
1254 The constructor takes a keyword arg: indent_child, which defaults to 2.
1257 def __init__(self
, indent_child
=2):
1258 """Default indentation of 2 SPC's for the children."""
1259 self
.cindent
= indent_child
1261 def format(self
, value
, buffer=None):
1263 output
= SixStringIO()
1267 BasicFormatter
.format(self
, value
, buffer=output
)
1269 BasicFormatter
.format(
1270 self
, child
, buffer=output
, indent
=self
.cindent
)
1272 return output
.getvalue()
1275 class RecursiveDecentFormatter(BasicFormatter
):
1276 """The recursive decent formatter prints the value and the decendents.
1278 The constructor takes two keyword args: indent_level, which defaults to 0,
1279 and indent_child, which defaults to 2. The current indentation level is
1280 determined by indent_level, while the immediate children has an additional
1281 indentation by inden_child.
1284 def __init__(self
, indent_level
=0, indent_child
=2):
1285 self
.lindent
= indent_level
1286 self
.cindent
= indent_child
1288 def format(self
, value
, buffer=None):
1290 output
= SixStringIO()
1294 BasicFormatter
.format(self
, value
, buffer=output
, indent
=self
.lindent
)
1295 new_indent
= self
.lindent
+ self
.cindent
1297 if child
.GetSummary() is not None:
1298 BasicFormatter
.format(
1299 self
, child
, buffer=output
, indent
=new_indent
)
1301 if child
.GetNumChildren() > 0:
1302 rdf
= RecursiveDecentFormatter(indent_level
=new_indent
)
1303 rdf
.format(child
, buffer=output
)
1305 BasicFormatter
.format(
1306 self
, child
, buffer=output
, indent
=new_indent
)
1308 return output
.getvalue()
1310 # ===========================================================
1311 # Utility functions for path manipulation on remote platforms
1312 # ===========================================================
1315 def join_remote_paths(*paths
):
1316 # TODO: update with actual platform name for remote windows once it exists
1317 if lldb
.remote_platform
.GetName() == 'remote-windows':
1318 return os
.path
.join(*paths
).replace(os
.path
.sep
, '\\')
1319 return os
.path
.join(*paths
).replace(os
.path
.sep
, '/')
1322 def append_to_process_working_directory(test
, *paths
):
1323 remote
= lldb
.remote_platform
1325 return join_remote_paths(remote
.GetWorkingDirectory(), *paths
)
1326 return os
.path
.join(test
.getBuildDir(), *paths
)
1328 # ==================================================
1329 # Utility functions to get the correct signal number
1330 # ==================================================
1335 def get_signal_number(signal_name
):
1336 platform
= lldb
.remote_platform
1337 if platform
and platform
.IsValid():
1338 signals
= platform
.GetUnixSignals()
1339 if signals
.IsValid():
1340 signal_number
= signals
.GetSignalNumberFromName(signal_name
)
1341 if signal_number
> 0:
1342 return signal_number
1343 # No remote platform; fall back to using local python signals.
1344 return getattr(signal
, signal_name
)
1347 class PrintableRegex(object):
1349 def __init__(self
, text
):
1350 self
.regex
= re
.compile(text
)
1353 def match(self
, str):
1354 return self
.regex
.match(str)
1357 return "%s" % (self
.text
)
1360 return "re.compile(%s) -> %s" % (self
.text
, self
.regex
)
1363 def skip_if_callable(test
, mycallable
, reason
):
1364 if six
.callable(mycallable
):
1365 if mycallable(test
):
1366 test
.skipTest(reason
)
1371 def skip_if_library_missing(test
, target
, library
):
1372 def find_library(target
, library
):
1373 for module
in target
.modules
:
1374 filename
= module
.file.GetFilename()
1375 if isinstance(library
, str):
1376 if library
== filename
:
1378 elif hasattr(library
, 'match'):
1379 if library
.match(filename
):
1383 def find_library_callable(test
):
1384 return find_library(target
, library
)
1385 return skip_if_callable(
1387 find_library_callable
,
1388 "could not find library matching '%s' in target %s" %
1393 def read_file_on_target(test
, remote
):
1394 if lldb
.remote_platform
:
1395 local
= test
.getBuildArtifact("file_from_target")
1396 error
= lldb
.remote_platform
.Get(lldb
.SBFileSpec(remote
, False),
1397 lldb
.SBFileSpec(local
, True))
1398 test
.assertTrue(error
.Success(), "Reading file {0} failed: {1}".format(remote
, error
))
1401 with
open(local
, 'r') as f
:
1404 def read_file_from_process_wd(test
, name
):
1405 path
= append_to_process_working_directory(test
, name
)
1406 return read_file_on_target(test
, path
)
1408 def wait_for_file_on_target(testcase
, file_path
, max_attempts
=6):
1409 for i
in range(max_attempts
):
1410 err
, retcode
, msg
= testcase
.run_platform_command("ls %s" % file_path
)
1411 if err
.Success() and retcode
== 0:
1413 if i
< max_attempts
:
1414 # Exponential backoff!
1416 time
.sleep(pow(2, i
) * 0.25)
1419 "File %s not found even after %d attempts." %
1420 (file_path
, max_attempts
))
1422 return read_file_on_target(testcase
, file_path
)