aboutsummaryrefslogtreecommitdiff
path: root/lldb/test/API/functionalities/breakpoint/consecutive_breakpoints/TestConsecutiveBreakpoints.py
blob: 351fae6b27678d9e9a0bc0909252450eab0d295f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
"""
Test that we handle breakpoints on consecutive instructions correctly.
"""

import lldb
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil


class ConsecutiveBreakpointsTestCase(TestBase):
    def prepare_test(self):
        self.build()

        (
            self.target,
            self.process,
            self.thread,
            bkpt,
        ) = lldbutil.run_to_source_breakpoint(
            self, "Set breakpoint here", lldb.SBFileSpec("main.cpp")
        )

        # Set breakpoint to the next instruction
        frame = self.thread.GetFrameAtIndex(0)

        address = frame.GetPCAddress()
        instructions = self.target.ReadInstructions(address, 2)
        self.assertEqual(len(instructions), 2)
        self.bkpt_address = instructions[1].GetAddress()
        self.breakpoint2 = self.target.BreakpointCreateByAddress(
            self.bkpt_address.GetLoadAddress(self.target)
        )
        self.assertTrue(
            self.breakpoint2 and self.breakpoint2.GetNumLocations() == 1,
            VALID_BREAKPOINT,
        )

    def finish_test(self):
        # Run the process until termination
        self.process.Continue()
        self.assertState(self.process.GetState(), lldb.eStateExited)

    @no_debug_info_test
    def test_continue(self):
        """Test that continue stops at the second breakpoint."""
        self.prepare_test()

        self.process.Continue()
        self.assertState(self.process.GetState(), lldb.eStateStopped)
        # We should be stopped at the second breakpoint
        self.thread = lldbutil.get_one_thread_stopped_at_breakpoint(
            self.process, self.breakpoint2
        )
        self.assertIsNotNone(
            self.thread, "Expected one thread to be stopped at breakpoint 2"
        )

        self.finish_test()

    @no_debug_info_test
    def test_single_step(self):
        """Test that single step stops at the second breakpoint."""
        self.prepare_test()

        # Instruction step to the next instruction
        # We haven't executed breakpoint2 yet, we're sitting at it now.
        step_over = False
        self.thread.StepInstruction(step_over)

        step_over = False
        self.thread.StepInstruction(step_over)

        # We've now hit the breakpoint and this StepInstruction has
        # been interrupted, it is still sitting on the thread plan stack.

        self.assertState(self.process.GetState(), lldb.eStateStopped)
        self.assertEqual(
            self.thread.GetFrameAtIndex(0).GetPCAddress().GetLoadAddress(self.target),
            self.bkpt_address.GetLoadAddress(self.target),
        )

        # One more instruction to complete the Step that was interrupted
        # earlier.
        self.thread.StepInstruction(step_over)
        strm = lldb.SBStream()
        self.thread.GetDescription(strm)
        self.assertIn("instruction step into", strm.GetData())
        self.assertIsNotNone(self.thread, "Expected to see that step-in had completed")

        self.finish_test()

    @no_debug_info_test
    @skipIf(
        oslist=["windows"],
        archs=["x86_64"],
        bugnumber="github.com/llvm/llvm-project/issues/138083",
    )
    def test_single_step_thread_specific(self):
        """Test that single step stops, even though the second breakpoint is not valid."""
        self.prepare_test()

        # Choose a thread other than the current one. A non-existing thread is
        # fine.
        thread_index = self.process.GetNumThreads() + 1
        self.assertFalse(self.process.GetThreadAtIndex(thread_index).IsValid())
        self.breakpoint2.SetThreadIndex(thread_index)

        step_over = False
        self.thread.StepInstruction(step_over)

        self.assertState(self.process.GetState(), lldb.eStateStopped)
        self.assertEqual(
            self.thread.GetFrameAtIndex(0).GetPCAddress().GetLoadAddress(self.target),
            self.bkpt_address.GetLoadAddress(self.target),
        )
        self.assertEqual(
            self.thread.GetStopReason(),
            lldb.eStopReasonPlanComplete,
            "Stop reason should be 'plan complete'",
        )

        # Hit our second breakpoint
        self.process.Continue()

        self.finish_test()