199451b44SJordan Rupprechtimport lldb
299451b44SJordan Rupprecht
399451b44SJordan Rupprechtclass StepWithChild:
499451b44SJordan Rupprecht    def __init__(self, thread_plan):
599451b44SJordan Rupprecht        self.thread_plan = thread_plan
699451b44SJordan Rupprecht        self.child_thread_plan = self.queue_child_thread_plan()
799451b44SJordan Rupprecht
899451b44SJordan Rupprecht    def explains_stop(self, event):
999451b44SJordan Rupprecht        return False
1099451b44SJordan Rupprecht
1199451b44SJordan Rupprecht    def should_stop(self, event):
1299451b44SJordan Rupprecht        if not self.child_thread_plan.IsPlanComplete():
1399451b44SJordan Rupprecht            return False
1499451b44SJordan Rupprecht
1599451b44SJordan Rupprecht        self.thread_plan.SetPlanComplete(True)
1699451b44SJordan Rupprecht
1799451b44SJordan Rupprecht        return True
1899451b44SJordan Rupprecht
1999451b44SJordan Rupprecht    def should_step(self):
2099451b44SJordan Rupprecht        return False
2199451b44SJordan Rupprecht
2299451b44SJordan Rupprecht    def queue_child_thread_plan(self):
2399451b44SJordan Rupprecht        return None
2499451b44SJordan Rupprecht
2599451b44SJordan Rupprechtclass StepOut(StepWithChild):
2699451b44SJordan Rupprecht    def __init__(self, thread_plan, dict):
2799451b44SJordan Rupprecht        StepWithChild.__init__(self, thread_plan)
2899451b44SJordan Rupprecht
2999451b44SJordan Rupprecht    def queue_child_thread_plan(self):
3099451b44SJordan Rupprecht        return self.thread_plan.QueueThreadPlanForStepOut(0)
3199451b44SJordan Rupprecht
3299451b44SJordan Rupprechtclass StepScripted(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.QueueThreadPlanForStepScripted("Steps.StepOut")
3899451b44SJordan Rupprecht
3999451b44SJordan Rupprecht# This plan does a step-over until a variable changes value.
4099451b44SJordan Rupprechtclass StepUntil(StepWithChild):
4199451b44SJordan Rupprecht    def __init__(self, thread_plan, args_data, dict):
4299451b44SJordan Rupprecht        self.frame = thread_plan.GetThread().frames[0]
4399451b44SJordan Rupprecht        self.target = thread_plan.GetThread().GetProcess().GetTarget()
4499451b44SJordan Rupprecht        func_entry = args_data.GetValueForKey("variable_name")
4599451b44SJordan Rupprecht
4699451b44SJordan Rupprecht        if not func_entry.IsValid():
4799451b44SJordan Rupprecht            print("Did not get a valid entry for variable_name")
4899451b44SJordan Rupprecht        func_name = func_entry.GetStringValue(100)
4999451b44SJordan Rupprecht
5099451b44SJordan Rupprecht        self.value = self.frame.FindVariable(func_name)
5199451b44SJordan Rupprecht        if self.value.GetError().Fail():
5299451b44SJordan Rupprecht            print("Failed to get foo value: %s"%(self.value.GetError().GetCString()))
5399451b44SJordan Rupprecht        else:
5499451b44SJordan Rupprecht            print("'foo' value: %d"%(self.value.GetValueAsUnsigned()))
5599451b44SJordan Rupprecht
5699451b44SJordan Rupprecht        StepWithChild.__init__(self, thread_plan)
5799451b44SJordan Rupprecht
5899451b44SJordan Rupprecht
5999451b44SJordan Rupprecht    def queue_child_thread_plan(self):
6099451b44SJordan Rupprecht        le = self.frame.GetLineEntry()
6199451b44SJordan Rupprecht        start_addr = le.GetStartAddress()
6299451b44SJordan Rupprecht        start = start_addr.GetLoadAddress(self.target)
6399451b44SJordan Rupprecht        end = le.GetEndAddress().GetLoadAddress(self.target)
6499451b44SJordan Rupprecht        return self.thread_plan.QueueThreadPlanForStepOverRange(start_addr,
6599451b44SJordan Rupprecht                                                                end - start)
6699451b44SJordan Rupprecht
6799451b44SJordan Rupprecht    def should_stop(self, event):
6899451b44SJordan Rupprecht        if not self.child_thread_plan.IsPlanComplete():
6999451b44SJordan Rupprecht            return False
7099451b44SJordan Rupprecht
7199451b44SJordan Rupprecht        # If we've stepped out of this frame, stop.
7299451b44SJordan Rupprecht        if not self.frame.IsValid():
7399451b44SJordan Rupprecht            return True
7499451b44SJordan Rupprecht
7599451b44SJordan Rupprecht        if not self.value.IsValid():
7699451b44SJordan Rupprecht            return True
7799451b44SJordan Rupprecht
7899451b44SJordan Rupprecht        if not self.value.GetValueDidChange():
7999451b44SJordan Rupprecht            self.child_thread_plan = self.queue_child_thread_plan()
8099451b44SJordan Rupprecht            return False
8199451b44SJordan Rupprecht        else:
8299451b44SJordan Rupprecht            return True
83*d3dfd8ceSJim Ingham
84*d3dfd8ceSJim Ingham# This plan does nothing, but sets stop_mode to the
85*d3dfd8ceSJim Ingham# value of GetStopOthers for this plan.
86*d3dfd8ceSJim Inghamclass StepReportsStopOthers():
87*d3dfd8ceSJim Ingham    stop_mode_dict = {}
88*d3dfd8ceSJim Ingham
89*d3dfd8ceSJim Ingham    def __init__(self, thread_plan, args_data, dict):
90*d3dfd8ceSJim Ingham        self.thread_plan = thread_plan
91*d3dfd8ceSJim Ingham        self.key = args_data.GetValueForKey("token").GetStringValue(1000)
92*d3dfd8ceSJim Ingham
93*d3dfd8ceSJim Ingham    def should_stop(self, event):
94*d3dfd8ceSJim Ingham        self.thread_plan.SetPlanComplete(True)
95*d3dfd8ceSJim Ingham        print("Called in should_stop")
96*d3dfd8ceSJim Ingham        StepReportsStopOthers.stop_mode_dict[self.key] = self.thread_plan.GetStopOthers()
97*d3dfd8ceSJim Ingham        return True
98*d3dfd8ceSJim Ingham
99*d3dfd8ceSJim Ingham    def should_step(self):
100*d3dfd8ceSJim Ingham        return True
101*d3dfd8ceSJim Ingham
102*d3dfd8ceSJim Ingham    def explains_stop(self, event):
103*d3dfd8ceSJim Ingham        return True
104