diff options
7 files changed, 77 insertions, 0 deletions
diff --git a/lldb/include/lldb/API/SBModule.h b/lldb/include/lldb/API/SBModule.h index d73267f8af5..7a10e9fc96b 100644 --- a/lldb/include/lldb/API/SBModule.h +++ b/lldb/include/lldb/API/SBModule.h @@ -309,6 +309,7 @@ public: lldb::SBFileSpec GetSymbolFileSpec() const; lldb::SBAddress GetObjectFileHeaderAddress() const; + lldb::SBAddress GetObjectFileEntryPointAddress() const; private: friend class SBAddress; diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/expr-entry-bp/Makefile b/lldb/packages/Python/lldbsuite/test/functionalities/expr-entry-bp/Makefile new file mode 100644 index 00000000000..0d70f259501 --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/functionalities/expr-entry-bp/Makefile @@ -0,0 +1,5 @@ +LEVEL = ../../make + +C_SOURCES := main.c + +include $(LEVEL)/Makefile.rules diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/expr-entry-bp/TestExprEntryBP.py b/lldb/packages/Python/lldbsuite/test/functionalities/expr-entry-bp/TestExprEntryBP.py new file mode 100644 index 00000000000..56abc19f4f3 --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/functionalities/expr-entry-bp/TestExprEntryBP.py @@ -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) diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/expr-entry-bp/main.c b/lldb/packages/Python/lldbsuite/test/functionalities/expr-entry-bp/main.c new file mode 100644 index 00000000000..168fc9c8ccb --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/functionalities/expr-entry-bp/main.c @@ -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); +} diff --git a/lldb/scripts/interface/SBModule.i b/lldb/scripts/interface/SBModule.i index adda954e5bf..32b771c4d02 100644 --- a/lldb/scripts/interface/SBModule.i +++ b/lldb/scripts/interface/SBModule.i @@ -332,6 +332,9 @@ public: lldb::SBAddress GetObjectFileHeaderAddress() const; + lldb::SBAddress + GetObjectFileEntryPointAddress() const; + bool operator == (const lldb::SBModule &rhs) const; diff --git a/lldb/source/API/SBModule.cpp b/lldb/source/API/SBModule.cpp index de9bd3e9a5e..9c029c518e0 100644 --- a/lldb/source/API/SBModule.cpp +++ b/lldb/source/API/SBModule.cpp @@ -591,3 +591,14 @@ lldb::SBAddress SBModule::GetObjectFileHeaderAddress() const { } 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; +} diff --git a/lldb/source/Target/StopInfo.cpp b/lldb/source/Target/StopInfo.cpp index 6965f585615..145426cfcf7 100644 --- a/lldb/source/Target/StopInfo.cpp +++ b/lldb/source/Target/StopInfo.cpp @@ -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," |