rdar://problem/11533713
authorJohnny Chen <johnny.chen@apple.com>
Fri, 25 May 2012 21:10:46 +0000 (21:10 +0000)
committerJohnny Chen <johnny.chen@apple.com>
Fri, 25 May 2012 21:10:46 +0000 (21:10 +0000)
Allow setting conditions inline with breakpoints.  Add test cases.

llvm-svn: 157497

lldb/source/Commands/CommandObjectBreakpoint.cpp
lldb/source/Commands/CommandObjectBreakpoint.h
lldb/test/functionalities/breakpoint/breakpoint_conditions/TestBreakpointConditions.py

index 63bcb62..4f0af6a 100644 (file)
@@ -49,6 +49,7 @@ AddBreakpointDescription (Stream *s, Breakpoint *bp, lldb::DescriptionLevel leve
 
 CommandObjectBreakpointSet::CommandOptions::CommandOptions(CommandInterpreter &interpreter) :
     Options (interpreter),
+    m_condition (),
     m_filenames (),
     m_line_num (0),
     m_column (0),
@@ -91,6 +92,9 @@ CommandObjectBreakpointSet::CommandOptions::g_option_table[] =
     { LLDB_OPT_SET_ALL, false, "ignore-count", 'i', required_argument,   NULL, 0, eArgTypeCount,
         "Set the number of times this breakpoint is skipped before stopping." },
 
+    { LLDB_OPT_SET_ALL, false, "condition",    'c', required_argument, NULL, 0, eArgTypeExpression,
+        "The breakpoint stops only if this condition expression evaluates to true."},
+
     { LLDB_OPT_SET_ALL, false, "thread-index", 'x', required_argument, NULL, 0, eArgTypeThreadIndex,
         "The breakpoint stops only for the thread whose index matches this argument."},
 
@@ -111,7 +115,7 @@ CommandObjectBreakpointSet::CommandOptions::g_option_table[] =
 
     // Comment out this option for the moment, as we don't actually use it, but will in the future.
     // This way users won't see it, but the infrastructure is left in place.
-    //    { 0, false, "column",     'c', required_argument, NULL, "<column>",
+    //    { 0, false, "column",     'C', required_argument, NULL, "<column>",
     //    "Set the breakpoint by source location at this particular column."},
 
     { LLDB_OPT_SET_2, true, "address", 'a', required_argument, NULL, 0, eArgTypeAddress,
@@ -179,10 +183,14 @@ CommandObjectBreakpointSet::CommandOptions::SetOptionValue (uint32_t option_idx,
                 error.SetErrorStringWithFormat ("invalid address string '%s'", option_arg);
             break;
 
-        case 'c':
+        case 'C':
             m_column = Args::StringToUInt32 (option_arg, 0);
             break;
 
+        case 'c':
+            m_condition.assign(option_arg);
+            break;
+
         case 'f':
             m_filenames.AppendIfUnique (FileSpec(option_arg, false));
             break;
@@ -325,6 +333,7 @@ CommandObjectBreakpointSet::CommandOptions::SetOptionValue (uint32_t option_idx,
 void
 CommandObjectBreakpointSet::CommandOptions::OptionParsingStarting ()
 {
+    m_condition.clear();
     m_filenames.Clear();
     m_line_num = 0;
     m_column = 0;
@@ -586,6 +595,9 @@ CommandObjectBreakpointSet::Execute
             
         if (m_options.m_ignore_count != 0)
             bp->GetOptions()->SetIgnoreCount(m_options.m_ignore_count);
+
+        if (!m_options.m_condition.empty())
+            bp->GetOptions()->SetCondition(m_options.m_condition.c_str());
     }
     
     if (bp)
index c944745..143b954 100644 (file)
@@ -98,6 +98,7 @@ public:
 
         // Instance variables to hold the values for command options.
 
+        std::string m_condition;
         FileSpecList m_filenames;
         uint32_t m_line_num;
         uint32_t m_column;
index d9c50d7..bd5df2d 100644 (file)
@@ -14,28 +14,41 @@ class BreakpointConditionsTestCase(TestBase):
 
     @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
     @dsym_test
-    def test_with_dsym_and_run_command(self):
+    def test_breakpoint_condition_with_dsym_and_run_command(self):
         """Exercise breakpoint condition with 'breakpoint modify -c <expr> id'."""
         self.buildDsym()
         self.breakpoint_conditions()
 
     @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
+    @dsym_test
+    def test_breakpoint_condition_inline_with_dsym_and_run_command(self):
+        """Exercise breakpoint condition inline with 'breakpoint set'."""
+        self.buildDsym()
+        self.breakpoint_conditions(inline=True)
+
+    @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
     @python_api_test
     @dsym_test
-    def test_with_dsym_and_python_api(self):
+    def test_breakpoint_condition_with_dsym_and_python_api(self):
         """Use Python APIs to set breakpoint conditions."""
         self.buildDsym()
         self.breakpoint_conditions_python()
 
     @dwarf_test
-    def test_with_dwarf_and_run_command(self):
+    def test_breakpoint_condition_with_dwarf_and_run_command(self):
         """Exercise breakpoint condition with 'breakpoint modify -c <expr> id'."""
         self.buildDwarf()
         self.breakpoint_conditions()
 
+    @dwarf_test
+    def test_breakpoint_condition_inline_with_dwarf_and_run_command(self):
+        """Exercise breakpoint condition inline with 'breakpoint set'."""
+        self.buildDwarf()
+        self.breakpoint_conditions(inline=True)
+
     @python_api_test
     @dwarf_test
-    def test_with_dwarf_and_python_api(self):
+    def test_breakpoint_condition_with_dwarf_and_python_api(self):
         """Use Python APIs to set breakpoint conditions."""
         self.buildDwarf()
         self.breakpoint_conditions_python()
@@ -47,17 +60,22 @@ class BreakpointConditionsTestCase(TestBase):
         self.line1 = line_number('main.c', '// Find the line number of function "c" here.')
         self.line2 = line_number('main.c', "// Find the line number of c's parent call here.")
 
-    def breakpoint_conditions(self):
+    def breakpoint_conditions(self, inline=False):
         """Exercise breakpoint condition with 'breakpoint modify -c <expr> id'."""
         exe = os.path.join(os.getcwd(), "a.out")
         self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
 
-        # Create a breakpoint by function name 'c'.
-        self.expect("breakpoint set -n c", BREAKPOINT_CREATED,
-            startstr = "Breakpoint created: 1: name = 'c', locations = 1")
-
-        # And set a condition on the breakpoint to stop on when 'val == 3'.
-        self.runCmd("breakpoint modify -c 'val == 3' 1")
+        if inline:
+            # Create a breakpoint by function name 'c' and set the condition.
+            self.expect("breakpoint set -n c -c 'val == 3'", BREAKPOINT_CREATED,
+                startstr = "Breakpoint created: 1: name = 'c', locations = 1")
+        else:
+            # Create a breakpoint by function name 'c'.
+            self.expect("breakpoint set -n c", BREAKPOINT_CREATED,
+                startstr = "Breakpoint created: 1: name = 'c', locations = 1")
+
+            # And set a condition on the breakpoint to stop on when 'val == 3'.
+            self.runCmd("breakpoint modify -c 'val == 3' 1")
 
         # Now run the program.
         self.runCmd("run", RUN_SUCCEEDED)