xref: /llvm-project/lldb/test/API/functionalities/step_scripted/Steps.py (revision 37fe152e0c9f47b0a9ef9663df1ddecffef6f338)
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