class EnumSynthProvider(RustSynthProvider): variant = lldb.SBValue() summary = '' skip_first = 0 def initialize(self): self.initialize_enum() def initialize_enum(self): pass def num_children(self): return self.variant.GetNumChildren() - self.skip_first def has_children(self): return self.variant.MightHaveChildren() def get_child_at_index(self, index): return self.variant.GetChildAtIndex(index + self.skip_first) def get_child_index(self, name): return self.variant.GetIndexOfChildWithName(name) - self.skip_first def get_summary(self): return self.summary
def invoke(val, method, args=''): """Try to invoke a method on val, args are passed in as an expression string""" # first try to get a valid frame frame = None for f in [ val.frame, lldb.frame, val.process.selected_thread.GetFrameAtIndex(0) ]: if f.IsValid(): frame = f break if frame is None: return lldb.SBValue() # second try to get a pointer to val if val.GetType().IsPointerType(): ptype = val.GetType() addr = val.GetValueAsUnsigned(0) else: ptype = val.GetType().GetPointerType() addr = val.AddressOf().GetValueAsUnsigned(0) # third, build expression expr = 'reinterpret_cast<const {}>({})->{}({})'.format( ptype.GetName(), addr, method, args) res = frame.EvaluateExpression(expr) # if not res.IsValid(): # print 'Expr {} on value {} failed'.format(expr, val.GetName()) return res
def initialize_enum(self): if self.valobj.GetTypeName().endswith('::Some'): self.variant = 'Some' self.deref = gcm(self.valobj, '0') else: self.variant = 'None' self.deref = lldb.SBValue()
def fuzz_obj(obj): obj.Append(lldb.SBValue()) obj.GetSize() obj.GetValueAtIndex(100) obj.FindValueObjectByUID(200) for val in obj: s = str(val)
def initialize(self): obj_type = self.valobj.GetType() first_field_name = obj_type.GetFieldAtIndex(0).GetName() # The first two branches are for the sake of windows-*-msvc targets and non-rust-enabled liblldb. # Normally, we should be calling the initialize_enum(). if first_field_name.startswith( ENCODED_ENUM_PREFIX): # Niche-optimized enum tokens = first_field_name[len(ENCODED_ENUM_PREFIX):].split("$") discr_indices = [int(index) for index in tokens[:-1]] null_variant = tokens[-1] discriminant = self.valobj.GetChildAtIndex(0) for discr_index in discr_indices: discriminant = discriminant.GetChildAtIndex(discr_index) # Recurse down the first field of the discriminant till we reach a non-struct type, for i in range(20): # ... but limit the depth, just in case. if discriminant.GetType().GetTypeClass( ) != lldb.eTypeClassStruct: break discriminant = discriminant.GetChildAtIndex(0) if discriminant.GetValueAsUnsigned() == 0: self.variant = null_variant self.deref = lldb.SBValue() else: self.deref = self.valobj.GetChildAtIndex(0) elif first_field_name == ENUM_DISCRIMINANT: # Regular enum self.variant = self.valobj.GetChildAtIndex(0).GetValue() self.deref = self.valobj.GetChildAtIndex(1) else: self.initialize_enum() self.deref.SetPreferSyntheticValue(True)
def test_SBValue(self): obj = lldb.SBValue() if self.TraceOn(): print obj self.assertFalse(obj) # Do fuzz testing on the invalid obj, it should not crash lldb. import sb_value sb_value.fuzz_obj(obj)
def __init__(self, dataobj, pnode_type): self.pnode_type = pnode_type self.root = dataobj.GetChildMemberWithName('header') self.current = lldb.SBValue() # We store the path here to avoid keeping re-fetching # values from the inferior (also, skip the pointer # arithmetic involved in using the parent pointer self.path = []
def initialize(self): inner = get_first_tuple_field(gcm(self.valobj, 'ptr', 'pointer')) self.strong = gcm(inner, 'strong', 'value', 'value').GetValueAsUnsigned() self.weak = gcm(inner, 'weak', 'value', 'value').GetValueAsUnsigned() if self.strong > 0: self.deref = gcm(inner, 'value') self.weak -= 1 # There's an implicit weak reference communally owned by all the strong pointers else: self.deref = lldb.SBValue()
def initialize(self): inner = read_unique_ptr(gcm(self.valobj, 'ptr')) self.strong = gcm(inner, 'strong', 'v', 'value').GetValueAsUnsigned() self.weak = gcm(inner, 'weak', 'v', 'value').GetValueAsUnsigned() if self.strong > 0: self.deref = gcm(inner, 'data') self.weak -= 1 # There's an implicit weak reference communally owned by all the strong pointers else: self.deref = lldb.SBValue()
def __init__(self, process): '''Initialization needs a valid.SBProcess object. This plug-in will get created after a live process is valid and has stopped for the first time.''' print("Plugin initialized.") self.process = None self.start_stop_id = 0 self.g_value = lldb.SBValue() if isinstance(process, lldb.SBProcess) and process.IsValid(): self.process = process self.g_value = process.GetTarget().FindFirstGlobalVariable( "g_value") if not self.g_value.IsValid(): print("Could not find g_value")
class DerefSynthProvider(RustSynthProvider): deref = lldb.SBValue() def num_children(self): return self.deref.GetNumChildren() def has_children(self): return self.deref.MightHaveChildren() def get_child_at_index(self, index): return self.deref.GetChildAtIndex(index) def get_child_index(self, name): return self.deref.GetIndexOfChildWithName(name) def get_summary(self): return get_obj_summary(self.deref)
def test_return_past_artificial_frame(self): self.build() thread = self.prepare_thread() value = lldb.SBValue() # Frame #0's ancestor is artificial. Returning from frame #0 should move # to frame #2. thread.ReturnFromFrame(thread.GetSelectedFrame(), value) frame2 = thread.GetSelectedFrame() self.assertEqual(frame2.GetDisplayFunctionName(), "func2()") self.assertFalse(frame2.IsArtificial()) # Ditto: stepping out of frame #2 should move to frame #4. thread.ReturnFromFrame(thread.GetSelectedFrame(), value) frame4 = thread.GetSelectedFrame() self.assertEqual(frame4.GetDisplayFunctionName(), "main") self.assertFalse(frame2.IsArtificial())
def wait_until_program_setup_complete(self, process, listener): inferior_set_up = lldb.SBValue() retry = 5 while retry > 0: arch = self.getArchitecture() # when running the testsuite against a remote arm device, it may take # a little longer for the process to start up. Use a "can't possibly take # longer than this" value. if arch == 'arm64' or arch == 'armv7': time.sleep(10) else: time.sleep(1) process.SendAsyncInterrupt() self.assertTrue(self.wait_for_stop(process, listener), "Check that process is paused") inferior_set_up = process.GetTarget().CreateValueFromExpression("threads_up_and_running", "threads_up_and_running") if inferior_set_up.IsValid() and inferior_set_up.GetValueAsSigned() == 1: retry = 0 else: process.Continue() retry = retry - 1 return inferior_set_up
def get_child_at_index(self, index): if index < self.valobj.num_children: return self.valobj.GetChildAtIndex(index) return GetOptionalValue(self.valobj) or lldb.SBValue()
if stop_reason != lldb.eStopReasonInvalid: print '--- Stopped ---' frame = thread.GetSelectedFrame() frame.GetDescription(stream) valueList = frame.GetVariables( True, True, False, True) # print stream.GetData() for i in range(valueList.GetSize()): value = valueList.GetValueAtIndex(i) if str(value.GetType()).find( 'A *') > 0: child_vs = lldb.SBValue( value).GetChildMemberWithName( 'name') print(child_vs.GetSummary()) if stop_reason == lldb.eStopReasonBreakpoint: print '--- Stopped At Breakpoint ---' process.Continue() else: continue elif event_type == lldb.SBProcess.eBroadcastBitSTDOUT: print '------------' while True: bytes = process.GetSTDOUT(1024)
def test_with_python_api(self): """Test that we get thread names when interrupting a process.""" self.build() exe = os.path.join(os.getcwd(), "a.out") target = self.dbg.CreateTarget(exe) self.assertTrue(target, VALID_TARGET) launch_info = lldb.SBLaunchInfo(None) error = lldb.SBError() lldb.debugger.SetAsync(True) process = target.Launch(launch_info, error) self.assertTrue(process, PROCESS_IS_VALID) listener = lldb.debugger.GetListener() broadcaster = process.GetBroadcaster() rc = broadcaster.AddListener(listener, lldb.SBProcess.eBroadcastBitStateChanged) self.assertTrue(rc != 0, "Unable to add listener to process") self.assertTrue(self.wait_for_running(process, listener), "Check that process is up and running") inferior_set_up = lldb.SBValue() retry = 5 while retry > 0: time.sleep(1) process.SendAsyncInterrupt() self.assertTrue(self.wait_for_stop(process, listener), "Check that process is paused") inferior_set_up = target.CreateValueFromExpression( "threads_up_and_running", "threads_up_and_running") if inferior_set_up.IsValid() and inferior_set_up.GetValueAsSigned( ) == 1: retry = 0 else: process.Continue() retry = retry - 1 self.assertTrue( inferior_set_up.IsValid() and inferior_set_up.GetValueAsSigned() == 1, "Check that the program was able to create its threads within the allotted time" ) self.check_number_of_threads(process) main_thread = lldb.SBThread() second_thread = lldb.SBThread() third_thread = lldb.SBThread() for idx in range(0, process.GetNumThreads()): t = process.GetThreadAtIndex(idx) if t.GetName() == "main thread": main_thread = t if t.GetName() == "second thread": second_thread = t if t.GetName() == "third thread": third_thread = t self.assertTrue( main_thread.IsValid() and second_thread.IsValid() and third_thread.IsValid(), "Got all three expected threads") process.Kill()
target.BreakpointCreateByName("[CKContainer containerWithIdentifier:]") process = target.LaunchSimple(None, None, os.getcwd()) if not process: raise ValueError("Failed to launch process: " + exe) try: if process.GetState() == lldb.eStateStopped: thread = process.GetThreadAtIndex(0) if thread.GetStopReason() == lldb.eStopReasonBreakpoint: frame = thread.GetSelectedFrame().name if frame == "+[CKContainer containerWithIdentifier:]": # Skip the code in CKContainer, avoiding a crash due to missing entitlements: thread.ReturnFromFrame( thread.GetSelectedFrame(), lldb.SBValue().CreateValueFromExpression("0", ""), ) process.Continue() if process.GetState() == lldb.eStateStopped: if thread and (frame := thread.GetFrameAtIndex(0)): registry = frame.EvaluateExpression( "[TSPRegistry sharedRegistry]").description if registry is None: raise (ValueError("Failed to extract registry")) split = [ x.strip().split(" -> ") for x in registry.split("{")[1].split("}")[0].split("\n") if x.strip() ] json_str = json.dumps( dict(
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. import lldb from typing import Any, List, Tuple import inspect import HMLLDBClassInfo gIsFirstCall = True gClassPrefixes: List[str] = [] # Class Prefixes that may be user-written gClassPrefixesValue: lldb.SBValue = lldb.SBValue() def processContinue() -> None: asyncState = lldb.debugger.GetAsync() lldb.debugger.SetAsync(True) lldb.debugger.HandleCommand('process continue') lldb.debugger.SetAsync(asyncState) def DPrint(obj: Any) -> None: print('[HMLLDB] ', end='') print(obj) def evaluateExpressionValue(expression: str,