brintos

brintos / llvm-project-archived public Read only

0
0
Text · 9.7 KiB · a4c9c49 Raw
262 lines · python
1"""2Test breakpoint conditions with 'breakpoint modify -c <expr> id'.3"""4 5import lldb6from lldbsuite.test.decorators import *7from lldbsuite.test.lldbtest import *8from lldbsuite.test import lldbutil9 10 11class BreakpointConditionsTestCase(TestBase):12    def test_breakpoint_condition_and_run_command(self):13        """Exercise breakpoint condition with 'breakpoint modify -c <expr> id'."""14        self.build()15        self.breakpoint_conditions()16 17    def test_breakpoint_condition_inline_and_run_command(self):18        """Exercise breakpoint condition inline with 'breakpoint set'."""19        self.build()20        self.breakpoint_conditions(inline=True)21 22    def test_breakpoint_condition_and_run_command_language(self):23        """Exercise breakpoint condition with 'breakpoint modify -c <expr> id'."""24        self.build()25        self.breakpoint_conditions(cpp=True)26 27    def test_breakpoint_condition_inline_and_run_command_language(self):28        """Exercise breakpoint condition inline with 'breakpoint set'."""29        self.build()30        self.breakpoint_conditions(inline=True, cpp=True)31 32    @add_test_categories(["pyapi"])33    def test_breakpoint_condition_and_python_api(self):34        """Use Python APIs to set breakpoint conditions."""35        self.build()36        self.breakpoint_conditions_python()37 38    @add_test_categories(["pyapi"])39    def test_breakpoint_invalid_condition_and_python_api(self):40        """Use Python APIs to set breakpoint conditions."""41        self.build()42        self.breakpoint_invalid_conditions_python()43 44    def setUp(self):45        # Call super's setUp().46        TestBase.setUp(self)47        # Find the line number to of function 'c'.48        self.line1 = line_number(49            "main.c", '// Find the line number of function "c" here.'50        )51        self.line2 = line_number(52            "main.c", "// Find the line number of c's parent call here."53        )54 55    def breakpoint_conditions(self, inline=False, cpp=False):56        """Exercise breakpoint condition with 'breakpoint modify -c <expr> id'."""57        exe = self.getBuildArtifact("a.out")58        self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)59 60        if cpp:61            condition = "&val != nullptr && val == 3"62            cmd_args = " -c '{}' -Y c++".format(condition)63        else:64            condition = "val == 3"65            cmd_args = "-c '{}'".format(condition)66 67        if inline:68            # Create a breakpoint by function name 'c' and set the condition.69            lldbutil.run_break_set_by_symbol(70                self,71                "c",72                extra_options=cmd_args,73                num_expected_locations=1,74                sym_exact=True,75            )76        else:77            # Create a breakpoint by function name 'c'.78            lldbutil.run_break_set_by_symbol(79                self, "c", num_expected_locations=1, sym_exact=True80            )81 82            # And set a condition on the breakpoint to stop on when 'val == 3'.83            self.runCmd("breakpoint modify " + cmd_args + " 1")84 85        # Now run the program.86        self.runCmd("run", RUN_SUCCEEDED)87 88        # The process should be stopped at this point.89        self.expect("process status", PROCESS_STOPPED, patterns=["Process .* stopped"])90 91        # 'frame variable --show-types val' should return 3 due to breakpoint condition.92        self.expect(93            "frame variable --show-types val",94            VARIABLES_DISPLAYED_CORRECTLY,95            startstr="(int) val = 3",96        )97 98        # Also check the hit count, which should be 3, by design.99        self.expect(100            "breakpoint list -f",101            BREAKPOINT_HIT_ONCE,102            substrs=[103                "resolved = 1",104                "Condition: {}".format(condition),105                "hit count = 1",106            ],107        )108 109        # The frame #0 should correspond to main.c:36, the executable statement110        # in function name 'c'.  And the parent frame should point to111        # main.c:24.112        self.expect(113            "thread backtrace",114            STOPPED_DUE_TO_BREAKPOINT_CONDITION,115            # substrs = ["stop reason = breakpoint"],116            patterns=[117                "frame #0.*main.c:%d" % self.line1,118                "frame #1.*main.c:%d" % self.line2,119            ],120        )121 122        # Test that "breakpoint modify -c ''" clears the condition for the last123        # created breakpoint, so that when the breakpoint hits, val == 1.124        self.runCmd("process kill")125        self.runCmd("breakpoint modify -c ''")126        self.expect(127            "breakpoint list -f",128            BREAKPOINT_STATE_CORRECT,129            matching=False,130            substrs=["Condition:"],131        )132 133        # Now run the program again.134        self.runCmd("run", RUN_SUCCEEDED)135 136        # The process should be stopped at this point.137        self.expect("process status", PROCESS_STOPPED, patterns=["Process .* stopped"])138 139        # 'frame variable --show-types val' should return 1 since it is the first breakpoint hit.140        self.expect(141            "frame variable --show-types val",142            VARIABLES_DISPLAYED_CORRECTLY,143            startstr="(int) val = 1",144        )145 146        self.runCmd("process kill")147 148    def breakpoint_conditions_python(self):149        """Use Python APIs to set breakpoint conditions."""150        target = self.createTestTarget()151 152        # Now create a breakpoint on main.c by name 'c'.153        breakpoint = target.BreakpointCreateByName("c", "a.out")154        self.trace("breakpoint:", breakpoint)155        self.assertTrue(156            breakpoint and breakpoint.GetNumLocations() == 1, VALID_BREAKPOINT157        )158 159        # We didn't associate a thread index with the breakpoint, so it should160        # be invalid.161        self.assertEqual(162            breakpoint.GetThreadIndex(),163            lldb.UINT32_MAX,164            "The thread index should be invalid",165        )166        # The thread name should be invalid, too.167        self.assertIsNone(168            breakpoint.GetThreadName(), "The thread name should be invalid"169        )170 171        # Let's set the thread index for this breakpoint and verify that it is,172        # indeed, being set correctly.173        # There's only one thread for the process.174        breakpoint.SetThreadIndex(1)175        self.assertEqual(176            breakpoint.GetThreadIndex(), 1, "The thread index has been set correctly"177        )178 179        # Get the breakpoint location from breakpoint after we verified that,180        # indeed, it has one location.181        location = breakpoint.GetLocationAtIndex(0)182        self.assertTrue(location and location.IsEnabled(), VALID_BREAKPOINT_LOCATION)183 184        # Set the condition on the breakpoint location.185        location.SetCondition("val == 3")186        self.expect(location.GetCondition(), exe=False, startstr="val == 3")187 188        # Now launch the process, and do not stop at entry point.189        process = target.LaunchSimple(None, None, self.get_process_working_directory())190        self.assertTrue(process, PROCESS_IS_VALID)191 192        # Frame #0 should be on self.line1 and the break condition should hold.193        from lldbsuite.test.lldbutil import get_stopped_thread194 195        thread = get_stopped_thread(process, lldb.eStopReasonBreakpoint)196        self.assertTrue(197            thread.IsValid(),198            "There should be a thread stopped due to breakpoint condition",199        )200 201        frame0 = thread.GetFrameAtIndex(0)202        var = frame0.FindValue("val", lldb.eValueTypeVariableArgument)203        self.assertEqual(204            frame0.GetLineEntry().GetLine(),205            self.line1,206            "The debugger stopped on the correct line",207        )208        self.assertEqual(var.GetValue(), "3")209 210        # The hit count for the breakpoint should be 1.211        self.assertEqual(breakpoint.GetHitCount(), 1)212 213        # Test that the condition expression didn't create a result variable:214        options = lldb.SBExpressionOptions()215        value = frame0.EvaluateExpression("$0", options)216        self.assertTrue(217            value.GetError().Fail(), "Conditions should not make result variables."218        )219        process.Continue()220 221    def breakpoint_invalid_conditions_python(self):222        """Use Python APIs to set breakpoint conditions."""223        exe = self.getBuildArtifact("a.out")224 225        # Create a target by the debugger.226        target = self.dbg.CreateTarget(exe)227        self.assertTrue(target, VALID_TARGET)228 229        # Now create a breakpoint on main.c by name 'c'.230        breakpoint = target.BreakpointCreateByName("c", "a.out")231        self.trace("breakpoint:", breakpoint)232        self.assertTrue(233            breakpoint and breakpoint.GetNumLocations() == 1, VALID_BREAKPOINT234        )235 236        # Set the condition on the breakpoint.237        breakpoint.SetCondition("no_such_variable == not_this_one_either")238        self.expect(239            breakpoint.GetCondition(),240            exe=False,241            startstr="no_such_variable == not_this_one_either",242        )243 244        # Now launch the process, and do not stop at entry point.245        process = target.LaunchSimple(None, None, self.get_process_working_directory())246        self.assertTrue(process, PROCESS_IS_VALID)247 248        # Frame #0 should be on self.line1 and the break condition should hold.249        from lldbsuite.test.lldbutil import get_stopped_thread250 251        thread = get_stopped_thread(process, lldb.eStopReasonBreakpoint)252        self.assertTrue(253            thread.IsValid(),254            "There should be a thread stopped due to breakpoint condition",255        )256        frame0 = thread.GetFrameAtIndex(0)257        var = frame0.FindValue("val", lldb.eValueTypeVariableArgument)258        self.assertEqual(frame0.GetLineEntry().GetLine(), self.line1)259 260        # The hit count for the breakpoint should be 1.261        self.assertEqual(breakpoint.GetHitCount(), 1)262