[Lldb-commits] [lldb] r347974 - [Target] Do not skip a stop on a breakpoint if a plan was completed

Aleksandr Urakov via lldb-commits lldb-commits at lists.llvm.org
Fri Nov 30 01:45:52 PST 2018


Author: aleksandr.urakov
Date: Fri Nov 30 01:45:52 2018
New Revision: 347974

URL: http://llvm.org/viewvc/llvm-project?rev=347974&view=rev
Log:
[Target] Do not skip a stop on a breakpoint if a plan was completed

Summary:
This patch fixes the next situation. On Windows clang-cl makes no stub before
the main function, so the main function is located exactly on module entry
point. May be it is the same on other platforms. So consider the following
sequence:

- set a breakpoint on main and stop there;
- try to evaluate expression, which requires a code execution on the debuggee
  side. Such an execution always returns to the module entry, and the plan waits
  for it there;
- the plan understands that it is complete now and removes its breakpoint. But
  the breakpoint site is still there, because we also have a breakpoint on
  entry;
- StopInfo analyzes a situation. It sees that we have stopped on the breakpoint
  site, and it sees that the breakpoint site has owners, and no one logical
  breakpoint is internal (because the plan is already completed and it have
  removed its breakpoint);
- StopInfo thinks that it's a user breakpoint and skips it to avoid recursive
  computations;
- the program continues.

So in this situation the program continues without a stop right after
the expression evaluation. To avoid this an additional check that
the plan was completed was added.

Reviewers: jingham, zturner, boris.ulasevich

Reviewed by: jingham

Tags: #lldb

Differential Revision: https://reviews.llvm.org/D53761

Added:
    lldb/trunk/packages/Python/lldbsuite/test/functionalities/expr-entry-bp/
    lldb/trunk/packages/Python/lldbsuite/test/functionalities/expr-entry-bp/Makefile
    lldb/trunk/packages/Python/lldbsuite/test/functionalities/expr-entry-bp/TestExprEntryBP.py
    lldb/trunk/packages/Python/lldbsuite/test/functionalities/expr-entry-bp/main.c
Modified:
    lldb/trunk/include/lldb/API/SBModule.h
    lldb/trunk/scripts/interface/SBModule.i
    lldb/trunk/source/API/SBModule.cpp
    lldb/trunk/source/Target/StopInfo.cpp

Modified: lldb/trunk/include/lldb/API/SBModule.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBModule.h?rev=347974&r1=347973&r2=347974&view=diff
==============================================================================
--- lldb/trunk/include/lldb/API/SBModule.h (original)
+++ lldb/trunk/include/lldb/API/SBModule.h Fri Nov 30 01:45:52 2018
@@ -309,6 +309,7 @@ public:
   lldb::SBFileSpec GetSymbolFileSpec() const;
 
   lldb::SBAddress GetObjectFileHeaderAddress() const;
+  lldb::SBAddress GetObjectFileEntryPointAddress() const;
 
 private:
   friend class SBAddress;

Added: lldb/trunk/packages/Python/lldbsuite/test/functionalities/expr-entry-bp/Makefile
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/functionalities/expr-entry-bp/Makefile?rev=347974&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/functionalities/expr-entry-bp/Makefile (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/functionalities/expr-entry-bp/Makefile Fri Nov 30 01:45:52 2018
@@ -0,0 +1,5 @@
+LEVEL = ../../make
+
+C_SOURCES := main.c
+
+include $(LEVEL)/Makefile.rules

Added: lldb/trunk/packages/Python/lldbsuite/test/functionalities/expr-entry-bp/TestExprEntryBP.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/functionalities/expr-entry-bp/TestExprEntryBP.py?rev=347974&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/functionalities/expr-entry-bp/TestExprEntryBP.py (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/functionalities/expr-entry-bp/TestExprEntryBP.py Fri Nov 30 01:45:52 2018
@@ -0,0 +1,34 @@
+"""
+Tests expressions evaluation when the breakpoint on module's entry is set.
+"""
+
+import lldb
+import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.lldbtest import *
+
+class ExprEntryBPTestCase(TestBase):
+
+    mydir = TestBase.compute_mydir(__file__)
+
+    NO_DEBUG_INFO_TESTCASE = True
+
+    def test_expr_entry_bp(self):
+        """Tests expressions evaluation when the breakpoint on module's entry is set."""
+        self.build()
+        self.main_source_file = lldb.SBFileSpec("main.c")
+
+        (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(self, "Set a breakpoint here", self.main_source_file)
+
+        self.assertEqual(1, bkpt.GetNumLocations())
+        entry = bkpt.GetLocationAtIndex(0).GetAddress().GetModule().GetObjectFileEntryPointAddress()
+        self.assertTrue(entry.IsValid(), "Can't get a module entry point")
+
+        entry_bp = target.BreakpointCreateBySBAddress(entry)
+        self.assertTrue(entry_bp.IsValid(), "Can't set a breakpoint on the module entry point")
+
+        result = target.EvaluateExpression("sum(7, 1)")
+        self.assertTrue(result.IsValid(), "Can't evaluate expression")
+        self.assertEqual(8, result.GetValueAsSigned())
+
+    def setUp(self):
+        TestBase.setUp(self)

Added: lldb/trunk/packages/Python/lldbsuite/test/functionalities/expr-entry-bp/main.c
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/functionalities/expr-entry-bp/main.c?rev=347974&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/functionalities/expr-entry-bp/main.c (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/functionalities/expr-entry-bp/main.c Fri Nov 30 01:45:52 2018
@@ -0,0 +1,10 @@
+#include <stdio.h>
+
+int sum(int x, int y) {
+  return x + y;
+}
+
+int main() {
+  printf("Set a breakpoint here.\n");
+  return sum(-1, 1);
+}

Modified: lldb/trunk/scripts/interface/SBModule.i
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/interface/SBModule.i?rev=347974&r1=347973&r2=347974&view=diff
==============================================================================
--- lldb/trunk/scripts/interface/SBModule.i (original)
+++ lldb/trunk/scripts/interface/SBModule.i Fri Nov 30 01:45:52 2018
@@ -332,6 +332,9 @@ public:
     lldb::SBAddress
     GetObjectFileHeaderAddress() const;
 
+    lldb::SBAddress
+    GetObjectFileEntryPointAddress() const;
+
     bool
     operator == (const lldb::SBModule &rhs) const;
              

Modified: lldb/trunk/source/API/SBModule.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBModule.cpp?rev=347974&r1=347973&r2=347974&view=diff
==============================================================================
--- lldb/trunk/source/API/SBModule.cpp (original)
+++ lldb/trunk/source/API/SBModule.cpp Fri Nov 30 01:45:52 2018
@@ -591,3 +591,14 @@ lldb::SBAddress SBModule::GetObjectFileH
   }
   return sb_addr;
 }
+
+lldb::SBAddress SBModule::GetObjectFileEntryPointAddress() const {
+  lldb::SBAddress sb_addr;
+  ModuleSP module_sp(GetSP());
+  if (module_sp) {
+    ObjectFile *objfile_ptr = module_sp->GetObjectFile();
+    if (objfile_ptr)
+      sb_addr.ref() = objfile_ptr->GetEntryPointAddress();
+  }
+  return sb_addr;
+}

Modified: lldb/trunk/source/Target/StopInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/StopInfo.cpp?rev=347974&r1=347973&r2=347974&view=diff
==============================================================================
--- lldb/trunk/source/Target/StopInfo.cpp (original)
+++ lldb/trunk/source/Target/StopInfo.cpp Fri Nov 30 01:45:52 2018
@@ -329,6 +329,19 @@ protected:
             // commands when we see the same breakpoint hit a second time.
 
             m_should_stop_is_valid = true;
+
+            // It is possible that the user has a breakpoint at the same site
+            // as the completed plan had (e.g. user has a breakpoint
+            // on a module entry point, and `ThreadPlanCallFunction` ends
+            // also there). We can't find an internal breakpoint in the loop
+            // later because it was already removed on the plan completion.
+            // So check if the plan was completed, and stop if so.
+            if (thread_sp->CompletedPlanOverridesBreakpoint()) {
+              m_should_stop = true;
+              thread_sp->ResetStopInfo();
+              return;
+            }
+
             if (log)
               log->Printf("StopInfoBreakpoint::PerformAction - Hit a "
                           "breakpoint while running an expression,"




More information about the lldb-commits mailing list