199451b44SJordan Rupprechtimport lldb 299451b44SJordan Rupprecht 32238dcc3SJonas Devlieghere 499451b44SJordan Rupprechtclass StepWithChild: 599451b44SJordan Rupprecht def __init__(self, thread_plan): 699451b44SJordan Rupprecht self.thread_plan = thread_plan 799451b44SJordan Rupprecht self.child_thread_plan = self.queue_child_thread_plan() 899451b44SJordan Rupprecht 999451b44SJordan Rupprecht def explains_stop(self, event): 1099451b44SJordan Rupprecht return False 1199451b44SJordan Rupprecht 1299451b44SJordan Rupprecht def should_stop(self, event): 1399451b44SJordan Rupprecht if not self.child_thread_plan.IsPlanComplete(): 1499451b44SJordan Rupprecht return False 1599451b44SJordan Rupprecht 1699451b44SJordan Rupprecht self.thread_plan.SetPlanComplete(True) 1799451b44SJordan Rupprecht 1899451b44SJordan Rupprecht return True 1999451b44SJordan Rupprecht 2099451b44SJordan Rupprecht def should_step(self): 2199451b44SJordan Rupprecht return False 2299451b44SJordan Rupprecht 23c2be7021SJim Ingham def stop_description(self, stream): 24c2be7021SJim Ingham if self.child_thread_plan.IsPlanComplete(): 25c2be7021SJim Ingham return self.child_thread_plan.GetDescription(stream) 26c2be7021SJim Ingham return True 27c2be7021SJim Ingham 2899451b44SJordan Rupprecht def queue_child_thread_plan(self): 2999451b44SJordan Rupprecht return None 3099451b44SJordan Rupprecht 312238dcc3SJonas Devlieghere 3299451b44SJordan Rupprechtclass StepOut(StepWithChild): 3399451b44SJordan Rupprecht def __init__(self, thread_plan, dict): 3499451b44SJordan Rupprecht StepWithChild.__init__(self, thread_plan) 3599451b44SJordan Rupprecht 3699451b44SJordan Rupprecht def queue_child_thread_plan(self): 3799451b44SJordan Rupprecht return self.thread_plan.QueueThreadPlanForStepOut(0) 3899451b44SJordan Rupprecht 392238dcc3SJonas Devlieghere 4099451b44SJordan Rupprechtclass StepScripted(StepWithChild): 4199451b44SJordan Rupprecht def __init__(self, thread_plan, dict): 4299451b44SJordan Rupprecht StepWithChild.__init__(self, thread_plan) 4399451b44SJordan Rupprecht 4499451b44SJordan Rupprecht def queue_child_thread_plan(self): 4599451b44SJordan Rupprecht return self.thread_plan.QueueThreadPlanForStepScripted("Steps.StepOut") 4699451b44SJordan Rupprecht 472238dcc3SJonas Devlieghere 4899451b44SJordan Rupprecht# This plan does a step-over until a variable changes value. 4999451b44SJordan Rupprechtclass StepUntil(StepWithChild): 50*9a9ec228SMed Ismail Bennani def __init__(self, thread_plan, args_data): 51c2be7021SJim Ingham self.thread_plan = thread_plan 5299451b44SJordan Rupprecht self.frame = thread_plan.GetThread().frames[0] 5399451b44SJordan Rupprecht self.target = thread_plan.GetThread().GetProcess().GetTarget() 54c2be7021SJim Ingham var_entry = args_data.GetValueForKey("variable_name") 5599451b44SJordan Rupprecht 56c2be7021SJim Ingham if not var_entry.IsValid(): 5799451b44SJordan Rupprecht print("Did not get a valid entry for variable_name") 58c2be7021SJim Ingham self.var_name = var_entry.GetStringValue(100) 5999451b44SJordan Rupprecht 60c2be7021SJim Ingham self.value = self.frame.FindVariable(self.var_name) 6199451b44SJordan Rupprecht if self.value.GetError().Fail(): 6299451b44SJordan Rupprecht print("Failed to get foo value: %s" % (self.value.GetError().GetCString())) 6399451b44SJordan Rupprecht 6499451b44SJordan Rupprecht StepWithChild.__init__(self, thread_plan) 6599451b44SJordan Rupprecht 6699451b44SJordan Rupprecht def queue_child_thread_plan(self): 6799451b44SJordan Rupprecht le = self.frame.GetLineEntry() 6899451b44SJordan Rupprecht start_addr = le.GetStartAddress() 6999451b44SJordan Rupprecht start = start_addr.GetLoadAddress(self.target) 7099451b44SJordan Rupprecht end = le.GetEndAddress().GetLoadAddress(self.target) 712238dcc3SJonas Devlieghere return self.thread_plan.QueueThreadPlanForStepOverRange(start_addr, end - start) 7299451b44SJordan Rupprecht 7399451b44SJordan Rupprecht def should_stop(self, event): 7499451b44SJordan Rupprecht if not self.child_thread_plan.IsPlanComplete(): 7599451b44SJordan Rupprecht return False 7699451b44SJordan Rupprecht 7799451b44SJordan Rupprecht # If we've stepped out of this frame, stop. 7899451b44SJordan Rupprecht if not self.frame.IsValid(): 79c2be7021SJim Ingham self.thread_plan.SetPlanComplete(True) 8099451b44SJordan Rupprecht return True 8199451b44SJordan Rupprecht 8299451b44SJordan Rupprecht if not self.value.IsValid(): 83c2be7021SJim Ingham self.thread_plan.SetPlanComplete(True) 8499451b44SJordan Rupprecht return True 8599451b44SJordan Rupprecht 8699451b44SJordan Rupprecht if not self.value.GetValueDidChange(): 8799451b44SJordan Rupprecht self.child_thread_plan = self.queue_child_thread_plan() 8899451b44SJordan Rupprecht return False 8999451b44SJordan Rupprecht else: 90c2be7021SJim Ingham self.thread_plan.SetPlanComplete(True) 9199451b44SJordan Rupprecht return True 92d3dfd8ceSJim Ingham 93c2be7021SJim Ingham def stop_description(self, stream): 94c2be7021SJim Ingham stream.Print(f"Stepped until {self.var_name} changed.") 95c2be7021SJim Ingham 962238dcc3SJonas Devlieghere 97d3dfd8ceSJim Ingham# This plan does nothing, but sets stop_mode to the 98d3dfd8ceSJim Ingham# value of GetStopOthers for this plan. 992238dcc3SJonas Devlieghereclass StepReportsStopOthers: 100d3dfd8ceSJim Ingham stop_mode_dict = {} 101d3dfd8ceSJim Ingham 102*9a9ec228SMed Ismail Bennani def __init__(self, thread_plan, args_data): 103d3dfd8ceSJim Ingham self.thread_plan = thread_plan 1041370a1cbSMed Ismail Bennani self.key = str(args_data.GetValueForKey("token").GetUnsignedIntegerValue(1000)) 105d3dfd8ceSJim Ingham 106d3dfd8ceSJim Ingham def should_stop(self, event): 107d3dfd8ceSJim Ingham self.thread_plan.SetPlanComplete(True) 1082238dcc3SJonas Devlieghere StepReportsStopOthers.stop_mode_dict[ 1092238dcc3SJonas Devlieghere self.key 1102238dcc3SJonas Devlieghere ] = self.thread_plan.GetStopOthers() 111d3dfd8ceSJim Ingham return True 112d3dfd8ceSJim Ingham 113d3dfd8ceSJim Ingham def should_step(self): 114d3dfd8ceSJim Ingham return True 115d3dfd8ceSJim Ingham 116d3dfd8ceSJim Ingham def explains_stop(self, event): 117d3dfd8ceSJim Ingham return True 118