199451b44SJordan Rupprecht""" 299451b44SJordan RupprechtTest breakpoint conditions with 'breakpoint modify -c <expr> id'. 399451b44SJordan Rupprecht""" 499451b44SJordan Rupprecht 599451b44SJordan Rupprechtimport lldb 699451b44SJordan Rupprechtfrom lldbsuite.test.decorators import * 799451b44SJordan Rupprechtfrom lldbsuite.test.lldbtest import * 899451b44SJordan Rupprechtfrom lldbsuite.test import lldbutil 999451b44SJordan Rupprecht 1099451b44SJordan Rupprecht 1199451b44SJordan Rupprechtclass BreakpointConditionsTestCase(TestBase): 1299451b44SJordan Rupprecht def test_breakpoint_condition_and_run_command(self): 1399451b44SJordan Rupprecht """Exercise breakpoint condition with 'breakpoint modify -c <expr> id'.""" 1499451b44SJordan Rupprecht self.build() 1599451b44SJordan Rupprecht self.breakpoint_conditions() 1699451b44SJordan Rupprecht 1799451b44SJordan Rupprecht def test_breakpoint_condition_inline_and_run_command(self): 1899451b44SJordan Rupprecht """Exercise breakpoint condition inline with 'breakpoint set'.""" 1999451b44SJordan Rupprecht self.build() 2099451b44SJordan Rupprecht self.breakpoint_conditions(inline=True) 2199451b44SJordan Rupprecht 222238dcc3SJonas Devlieghere @add_test_categories(["pyapi"]) 2399451b44SJordan Rupprecht def test_breakpoint_condition_and_python_api(self): 2499451b44SJordan Rupprecht """Use Python APIs to set breakpoint conditions.""" 2599451b44SJordan Rupprecht self.build() 2699451b44SJordan Rupprecht self.breakpoint_conditions_python() 2799451b44SJordan Rupprecht 282238dcc3SJonas Devlieghere @add_test_categories(["pyapi"]) 2999451b44SJordan Rupprecht def test_breakpoint_invalid_condition_and_python_api(self): 3099451b44SJordan Rupprecht """Use Python APIs to set breakpoint conditions.""" 3199451b44SJordan Rupprecht self.build() 3299451b44SJordan Rupprecht self.breakpoint_invalid_conditions_python() 3399451b44SJordan Rupprecht 3499451b44SJordan Rupprecht def setUp(self): 3599451b44SJordan Rupprecht # Call super's setUp(). 3699451b44SJordan Rupprecht TestBase.setUp(self) 3799451b44SJordan Rupprecht # Find the line number to of function 'c'. 3899451b44SJordan Rupprecht self.line1 = line_number( 392238dcc3SJonas Devlieghere "main.c", '// Find the line number of function "c" here.' 402238dcc3SJonas Devlieghere ) 4199451b44SJordan Rupprecht self.line2 = line_number( 422238dcc3SJonas Devlieghere "main.c", "// Find the line number of c's parent call here." 432238dcc3SJonas Devlieghere ) 4499451b44SJordan Rupprecht 4599451b44SJordan Rupprecht def breakpoint_conditions(self, inline=False): 4699451b44SJordan Rupprecht """Exercise breakpoint condition with 'breakpoint modify -c <expr> id'.""" 4799451b44SJordan Rupprecht exe = self.getBuildArtifact("a.out") 4899451b44SJordan Rupprecht self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) 4999451b44SJordan Rupprecht 5099451b44SJordan Rupprecht if inline: 5199451b44SJordan Rupprecht # Create a breakpoint by function name 'c' and set the condition. 5299451b44SJordan Rupprecht lldbutil.run_break_set_by_symbol( 5399451b44SJordan Rupprecht self, 5499451b44SJordan Rupprecht "c", 5599451b44SJordan Rupprecht extra_options="-c 'val == 3'", 5699451b44SJordan Rupprecht num_expected_locations=1, 572238dcc3SJonas Devlieghere sym_exact=True, 582238dcc3SJonas Devlieghere ) 5999451b44SJordan Rupprecht else: 6099451b44SJordan Rupprecht # Create a breakpoint by function name 'c'. 6199451b44SJordan Rupprecht lldbutil.run_break_set_by_symbol( 622238dcc3SJonas Devlieghere self, "c", num_expected_locations=1, sym_exact=True 632238dcc3SJonas Devlieghere ) 6499451b44SJordan Rupprecht 6599451b44SJordan Rupprecht # And set a condition on the breakpoint to stop on when 'val == 3'. 6699451b44SJordan Rupprecht self.runCmd("breakpoint modify -c 'val == 3' 1") 6799451b44SJordan Rupprecht 6899451b44SJordan Rupprecht # Now run the program. 6999451b44SJordan Rupprecht self.runCmd("run", RUN_SUCCEEDED) 7099451b44SJordan Rupprecht 7199451b44SJordan Rupprecht # The process should be stopped at this point. 722238dcc3SJonas Devlieghere self.expect("process status", PROCESS_STOPPED, patterns=["Process .* stopped"]) 7399451b44SJordan Rupprecht 7499451b44SJordan Rupprecht # 'frame variable --show-types val' should return 3 due to breakpoint condition. 7599451b44SJordan Rupprecht self.expect( 7699451b44SJordan Rupprecht "frame variable --show-types val", 7799451b44SJordan Rupprecht VARIABLES_DISPLAYED_CORRECTLY, 782238dcc3SJonas Devlieghere startstr="(int) val = 3", 792238dcc3SJonas Devlieghere ) 8099451b44SJordan Rupprecht 8199451b44SJordan Rupprecht # Also check the hit count, which should be 3, by design. 822238dcc3SJonas Devlieghere self.expect( 832238dcc3SJonas Devlieghere "breakpoint list -f", 842238dcc3SJonas Devlieghere BREAKPOINT_HIT_ONCE, 852238dcc3SJonas Devlieghere substrs=["resolved = 1", "Condition: val == 3", "hit count = 1"], 862238dcc3SJonas Devlieghere ) 8799451b44SJordan Rupprecht 8899451b44SJordan Rupprecht # The frame #0 should correspond to main.c:36, the executable statement 8999451b44SJordan Rupprecht # in function name 'c'. And the parent frame should point to 9099451b44SJordan Rupprecht # main.c:24. 912238dcc3SJonas Devlieghere self.expect( 922238dcc3SJonas Devlieghere "thread backtrace", 932238dcc3SJonas Devlieghere STOPPED_DUE_TO_BREAKPOINT_CONDITION, 9499451b44SJordan Rupprecht # substrs = ["stop reason = breakpoint"], 952238dcc3SJonas Devlieghere patterns=[ 962238dcc3SJonas Devlieghere "frame #0.*main.c:%d" % self.line1, 972238dcc3SJonas Devlieghere "frame #1.*main.c:%d" % self.line2, 982238dcc3SJonas Devlieghere ], 992238dcc3SJonas Devlieghere ) 10099451b44SJordan Rupprecht 10199451b44SJordan Rupprecht # Test that "breakpoint modify -c ''" clears the condition for the last 10299451b44SJordan Rupprecht # created breakpoint, so that when the breakpoint hits, val == 1. 10399451b44SJordan Rupprecht self.runCmd("process kill") 10499451b44SJordan Rupprecht self.runCmd("breakpoint modify -c ''") 10599451b44SJordan Rupprecht self.expect( 10699451b44SJordan Rupprecht "breakpoint list -f", 10799451b44SJordan Rupprecht BREAKPOINT_STATE_CORRECT, 10899451b44SJordan Rupprecht matching=False, 1092238dcc3SJonas Devlieghere substrs=["Condition:"], 1102238dcc3SJonas Devlieghere ) 11199451b44SJordan Rupprecht 11299451b44SJordan Rupprecht # Now run the program again. 11399451b44SJordan Rupprecht self.runCmd("run", RUN_SUCCEEDED) 11499451b44SJordan Rupprecht 11599451b44SJordan Rupprecht # The process should be stopped at this point. 1162238dcc3SJonas Devlieghere self.expect("process status", PROCESS_STOPPED, patterns=["Process .* stopped"]) 11799451b44SJordan Rupprecht 11899451b44SJordan Rupprecht # 'frame variable --show-types val' should return 1 since it is the first breakpoint hit. 11999451b44SJordan Rupprecht self.expect( 12099451b44SJordan Rupprecht "frame variable --show-types val", 12199451b44SJordan Rupprecht VARIABLES_DISPLAYED_CORRECTLY, 1222238dcc3SJonas Devlieghere startstr="(int) val = 1", 1232238dcc3SJonas Devlieghere ) 12499451b44SJordan Rupprecht 12599451b44SJordan Rupprecht self.runCmd("process kill") 12699451b44SJordan Rupprecht 12799451b44SJordan Rupprecht def breakpoint_conditions_python(self): 12899451b44SJordan Rupprecht """Use Python APIs to set breakpoint conditions.""" 12954c26872SRaphael Isemann target = self.createTestTarget() 13099451b44SJordan Rupprecht 13199451b44SJordan Rupprecht # Now create a breakpoint on main.c by name 'c'. 1322238dcc3SJonas Devlieghere breakpoint = target.BreakpointCreateByName("c", "a.out") 133b321b429SJonas Devlieghere self.trace("breakpoint:", breakpoint) 1342238dcc3SJonas Devlieghere self.assertTrue( 1352238dcc3SJonas Devlieghere breakpoint and breakpoint.GetNumLocations() == 1, VALID_BREAKPOINT 1362238dcc3SJonas Devlieghere ) 13799451b44SJordan Rupprecht 13899451b44SJordan Rupprecht # We didn't associate a thread index with the breakpoint, so it should 13999451b44SJordan Rupprecht # be invalid. 1402238dcc3SJonas Devlieghere self.assertEqual( 1412238dcc3SJonas Devlieghere breakpoint.GetThreadIndex(), 1422238dcc3SJonas Devlieghere lldb.UINT32_MAX, 1432238dcc3SJonas Devlieghere "The thread index should be invalid", 1442238dcc3SJonas Devlieghere ) 14599451b44SJordan Rupprecht # The thread name should be invalid, too. 1469c246882SJordan Rupprecht self.assertIsNone( 1479c246882SJordan Rupprecht breakpoint.GetThreadName(), "The thread name should be invalid" 1482238dcc3SJonas Devlieghere ) 14999451b44SJordan Rupprecht 15099451b44SJordan Rupprecht # Let's set the thread index for this breakpoint and verify that it is, 15199451b44SJordan Rupprecht # indeed, being set correctly. 15299451b44SJordan Rupprecht # There's only one thread for the process. 15399451b44SJordan Rupprecht breakpoint.SetThreadIndex(1) 1542238dcc3SJonas Devlieghere self.assertEqual( 1552238dcc3SJonas Devlieghere breakpoint.GetThreadIndex(), 1, "The thread index has been set correctly" 1562238dcc3SJonas Devlieghere ) 15799451b44SJordan Rupprecht 15899451b44SJordan Rupprecht # Get the breakpoint location from breakpoint after we verified that, 15999451b44SJordan Rupprecht # indeed, it has one location. 16099451b44SJordan Rupprecht location = breakpoint.GetLocationAtIndex(0) 1612238dcc3SJonas Devlieghere self.assertTrue(location and location.IsEnabled(), VALID_BREAKPOINT_LOCATION) 16299451b44SJordan Rupprecht 16399451b44SJordan Rupprecht # Set the condition on the breakpoint location. 1642238dcc3SJonas Devlieghere location.SetCondition("val == 3") 1652238dcc3SJonas Devlieghere self.expect(location.GetCondition(), exe=False, startstr="val == 3") 16699451b44SJordan Rupprecht 16799451b44SJordan Rupprecht # Now launch the process, and do not stop at entry point. 1682238dcc3SJonas Devlieghere process = target.LaunchSimple(None, None, self.get_process_working_directory()) 16999451b44SJordan Rupprecht self.assertTrue(process, PROCESS_IS_VALID) 17099451b44SJordan Rupprecht 17199451b44SJordan Rupprecht # Frame #0 should be on self.line1 and the break condition should hold. 17299451b44SJordan Rupprecht from lldbsuite.test.lldbutil import get_stopped_thread 1732238dcc3SJonas Devlieghere 17499451b44SJordan Rupprecht thread = get_stopped_thread(process, lldb.eStopReasonBreakpoint) 17599451b44SJordan Rupprecht self.assertTrue( 17699451b44SJordan Rupprecht thread.IsValid(), 1772238dcc3SJonas Devlieghere "There should be a thread stopped due to breakpoint condition", 1782238dcc3SJonas Devlieghere ) 179*3c3851f3SKendal Harland 18099451b44SJordan Rupprecht frame0 = thread.GetFrameAtIndex(0) 1812238dcc3SJonas Devlieghere var = frame0.FindValue("val", lldb.eValueTypeVariableArgument) 182*3c3851f3SKendal Harland self.assertEqual( 183*3c3851f3SKendal Harland frame0.GetLineEntry().GetLine(), 184*3c3851f3SKendal Harland self.line1, 185*3c3851f3SKendal Harland "The debugger stopped on the correct line", 1862238dcc3SJonas Devlieghere ) 187*3c3851f3SKendal Harland self.assertEqual(var.GetValue(), "3") 18899451b44SJordan Rupprecht 18999451b44SJordan Rupprecht # The hit count for the breakpoint should be 1. 190619e2e09SDave Lee self.assertEqual(breakpoint.GetHitCount(), 1) 19199451b44SJordan Rupprecht 19299451b44SJordan Rupprecht # Test that the condition expression didn't create a result variable: 19399451b44SJordan Rupprecht options = lldb.SBExpressionOptions() 19499451b44SJordan Rupprecht value = frame0.EvaluateExpression("$0", options) 1952238dcc3SJonas Devlieghere self.assertTrue( 1962238dcc3SJonas Devlieghere value.GetError().Fail(), "Conditions should not make result variables." 1972238dcc3SJonas Devlieghere ) 19899451b44SJordan Rupprecht process.Continue() 19999451b44SJordan Rupprecht 20099451b44SJordan Rupprecht def breakpoint_invalid_conditions_python(self): 20199451b44SJordan Rupprecht """Use Python APIs to set breakpoint conditions.""" 20299451b44SJordan Rupprecht exe = self.getBuildArtifact("a.out") 20399451b44SJordan Rupprecht 20499451b44SJordan Rupprecht # Create a target by the debugger. 20599451b44SJordan Rupprecht target = self.dbg.CreateTarget(exe) 20699451b44SJordan Rupprecht self.assertTrue(target, VALID_TARGET) 20799451b44SJordan Rupprecht 20899451b44SJordan Rupprecht # Now create a breakpoint on main.c by name 'c'. 2092238dcc3SJonas Devlieghere breakpoint = target.BreakpointCreateByName("c", "a.out") 210b321b429SJonas Devlieghere self.trace("breakpoint:", breakpoint) 2112238dcc3SJonas Devlieghere self.assertTrue( 2122238dcc3SJonas Devlieghere breakpoint and breakpoint.GetNumLocations() == 1, VALID_BREAKPOINT 2132238dcc3SJonas Devlieghere ) 21499451b44SJordan Rupprecht 21599451b44SJordan Rupprecht # Set the condition on the breakpoint. 2162238dcc3SJonas Devlieghere breakpoint.SetCondition("no_such_variable == not_this_one_either") 2172238dcc3SJonas Devlieghere self.expect( 2182238dcc3SJonas Devlieghere breakpoint.GetCondition(), 2192238dcc3SJonas Devlieghere exe=False, 2202238dcc3SJonas Devlieghere startstr="no_such_variable == not_this_one_either", 2212238dcc3SJonas Devlieghere ) 22299451b44SJordan Rupprecht 22399451b44SJordan Rupprecht # Now launch the process, and do not stop at entry point. 2242238dcc3SJonas Devlieghere process = target.LaunchSimple(None, None, self.get_process_working_directory()) 22599451b44SJordan Rupprecht self.assertTrue(process, PROCESS_IS_VALID) 22699451b44SJordan Rupprecht 22799451b44SJordan Rupprecht # Frame #0 should be on self.line1 and the break condition should hold. 22899451b44SJordan Rupprecht from lldbsuite.test.lldbutil import get_stopped_thread 2292238dcc3SJonas Devlieghere 23099451b44SJordan Rupprecht thread = get_stopped_thread(process, lldb.eStopReasonBreakpoint) 23199451b44SJordan Rupprecht self.assertTrue( 23299451b44SJordan Rupprecht thread.IsValid(), 2332238dcc3SJonas Devlieghere "There should be a thread stopped due to breakpoint condition", 2342238dcc3SJonas Devlieghere ) 23599451b44SJordan Rupprecht frame0 = thread.GetFrameAtIndex(0) 2362238dcc3SJonas Devlieghere var = frame0.FindValue("val", lldb.eValueTypeVariableArgument) 237619e2e09SDave Lee self.assertEqual(frame0.GetLineEntry().GetLine(), self.line1) 23899451b44SJordan Rupprecht 23999451b44SJordan Rupprecht # The hit count for the breakpoint should be 1. 240619e2e09SDave Lee self.assertEqual(breakpoint.GetHitCount(), 1) 241