[Lldb-commits] [lldb] [lldb][Windows] Fixed Host::Kill() (PR #99721)
https://github.com/slydiman edited https://github.com/llvm/llvm-project/pull/99721 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb/Commands] Add `scripting template list` command with auto discovery (PR #97273)
https://github.com/medismailben updated https://github.com/llvm/llvm-project/pull/97273 >From 16ef7297eef25d329631fd62d126bf7a7be24c4d Mon Sep 17 00:00:00 2001 From: Med Ismail Bennani Date: Fri, 19 Jul 2024 11:08:39 -0700 Subject: [PATCH 1/2] [lldb/Target] Add GetStartSymbol method to DynamicLoader plugins This patch introduces a new method to the dynamic loader plugin, to fetch its `start` symbol. This can be useful to resolve the `start` symbol address for instance. Signed-off-by: Med Ismail Bennani --- lldb/include/lldb/Target/DynamicLoader.h | 10 +- .../MacOSX-DYLD/DynamicLoaderDarwin.cpp | 20 +++ .../MacOSX-DYLD/DynamicLoaderDarwin.h | 2 ++ 3 files changed, 31 insertions(+), 1 deletion(-) diff --git a/lldb/include/lldb/Target/DynamicLoader.h b/lldb/include/lldb/Target/DynamicLoader.h index e508d192d2759..fd3b3924c2725 100644 --- a/lldb/include/lldb/Target/DynamicLoader.h +++ b/lldb/include/lldb/Target/DynamicLoader.h @@ -10,9 +10,11 @@ #define LLDB_TARGET_DYNAMICLOADER_H #include "lldb/Core/PluginInterface.h" +#include "lldb/Symbol/Symbol.h" #include "lldb/Utility/FileSpec.h" #include "lldb/Utility/Status.h" #include "lldb/Utility/UUID.h" +#include "lldb/Utility/UnimplementedError.h" #include "lldb/lldb-defines.h" #include "lldb/lldb-forward.h" #include "lldb/lldb-private-enumerations.h" @@ -24,7 +26,6 @@ namespace lldb_private { class ModuleList; class Process; class SectionList; -class Symbol; class SymbolContext; class SymbolContextList; class Thread; @@ -329,6 +330,13 @@ class DynamicLoader : public PluginInterface { /// safe to call certain APIs or SPIs. virtual bool IsFullyInitialized() { return true; } + /// Return the `start` function \b symbol in the dynamic loader module. + /// This is the symbol the process will begin executing with + /// `process launch --stop-at-entry`. + virtual std::optional GetStartSymbol() { +return std::nullopt; + } + protected: // Utility methods for derived classes diff --git a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp index 0e17d57fa9c4f..5c6331735bde8 100644 --- a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp +++ b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp @@ -609,6 +609,26 @@ void DynamicLoaderDarwin::UpdateDYLDImageInfoFromNewImageInfo( } } +std::optional DynamicLoaderDarwin::GetStartSymbol() { + Log *log = GetLog(LLDBLog::DynamicLoader); + + auto log_err = [log](llvm::StringLiteral err_msg) -> std::nullopt_t { +LLDB_LOGV(log, "{}", err_msg); +return std::nullopt; + }; + + ModuleSP dyld_sp = GetDYLDModule(); + if (!dyld_sp) +return log_err("Couldn't retrieve DYLD module. Cannot get `start` symbol."); + + const Symbol *symbol = + dyld_sp->FindFirstSymbolWithNameAndType(ConstString("_dyld_start")); + if (!symbol) +return log_err("Cannot find `start` symbol in DYLD module."); + + return *symbol; +} + void DynamicLoaderDarwin::SetDYLDModule(lldb::ModuleSP &dyld_module_sp) { m_dyld_module_wp = dyld_module_sp; } diff --git a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.h b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.h index 8f9a29c94173f..4ac55fdf6f3af 100644 --- a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.h +++ b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.h @@ -67,6 +67,8 @@ class DynamicLoaderDarwin : public lldb_private::DynamicLoader { // Clear method for classes derived from this one virtual void DoClear() = 0; + std::optional GetStartSymbol() override; + void SetDYLDModule(lldb::ModuleSP &dyld_module_sp); lldb::ModuleSP GetDYLDModule(); >From a3aea6522b889b87c13bd82388beb8ee30919424 Mon Sep 17 00:00:00 2001 From: Med Ismail Bennani Date: Sat, 20 Jul 2024 02:07:23 -0700 Subject: [PATCH 2/2] [lldb/Commands] Add `scripting template list` command with auto discovery This patch introduces a new `template` multiword sub-command to the `scripting` top-level command. As the name suggests, this sub-command operates on scripting templates, and currently has the ability to automatically discover the various scripting extensions that lldb supports. Signed-off-by: Med Ismail Bennani --- lldb/include/lldb/Core/PluginManager.h| 20 +++ .../Interfaces/ScriptedInterface.h| 7 + .../Interfaces/ScriptedInterfaceUsages.h | 43 ++ lldb/include/lldb/lldb-private-interfaces.h | 3 + .../Commands/CommandObjectScripting.cpp | 127 +- lldb/source/Commands/Options.td | 6 + lldb/source/Core/PluginManager.cpp| 65 + lldb/source/Interpreter/CMakeLists.txt| 4 + .../Interpreter/Interfaces/CMakeLists.txt | 10 ++ .../Interfaces/ScriptedInterfaceUsages.cpp| 37 + lldb/so
[Lldb-commits] [lldb] [lldb][Windows] Fixed Host::Kill() (PR #99721)
https://github.com/slydiman updated https://github.com/llvm/llvm-project/pull/99721 >From c033ba3832141409c2dac7e7363c0c85caa2274b Mon Sep 17 00:00:00 2001 From: Dmitry Vasilyev Date: Sat, 20 Jul 2024 03:48:12 +0400 Subject: [PATCH] [lldb][Windows] Fixed Host::Kill() HostProcessWindows::Terminate() correctly uses m_process which type is process_t (HANDLE) to call ::TerminateProcess(). But Host::Kill() uses a cast from pid, which is wrong. This patch fixes #51793 --- lldb/source/Host/windows/Host.cpp | 4 +++- .../API/functionalities/gdb_remote_client/TestPlatformKill.py | 1 - 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/lldb/source/Host/windows/Host.cpp b/lldb/source/Host/windows/Host.cpp index 6908f0003eaf7..642092f61d924 100644 --- a/lldb/source/Host/windows/Host.cpp +++ b/lldb/source/Host/windows/Host.cpp @@ -103,7 +103,9 @@ lldb::thread_t Host::GetCurrentThread() { } void Host::Kill(lldb::pid_t pid, int signo) { - TerminateProcess((HANDLE)pid, 1); + AutoHandle handle(::OpenProcess(PROCESS_TERMINATE, FALSE, pid), nullptr); + if (handle.IsValid()) +::TerminateProcess(handle.get(), 1); } const char *Host::GetSignalAsCString(int signo) { return NULL; } diff --git a/lldb/test/API/functionalities/gdb_remote_client/TestPlatformKill.py b/lldb/test/API/functionalities/gdb_remote_client/TestPlatformKill.py index 46cda4d66b488..430f1871d3b30 100644 --- a/lldb/test/API/functionalities/gdb_remote_client/TestPlatformKill.py +++ b/lldb/test/API/functionalities/gdb_remote_client/TestPlatformKill.py @@ -8,7 +8,6 @@ class TestPlatformKill(GDBRemoteTestBase): @skipIfRemote -@expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr52451") def test_kill_different_platform(self): """Test connecting to a remote linux platform""" ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][Windows] Fixed Host::Kill() (PR #99721)
https://github.com/slydiman edited https://github.com/llvm/llvm-project/pull/99721 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Implement basic support for reverse-continue (PR #99736)
walter-erquinigo wrote: This is very exciting! https://github.com/llvm/llvm-project/pull/99736 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Implement basic support for reverse-continue (PR #99736)
rocallahan wrote: > I've noticed you didn't check if this works both when the debugger is in > synchronous and asynchronous in your tests. OK, I've added this. > I'm not sure what additional information does the History Boundary stop > reason provides. Can it actually provide historical data to the user ? When a user reverse-continues to the start of recorded time (typically the point where the target was initially execed), execution stops and we must report a reason. None of the existing reasons are appropriate so I created this new one. I've added an explanatory comment to its definition in `lldb-enumerations.h`. https://github.com/llvm/llvm-project/pull/99736 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Implement basic support for reverse-continue (PR #99736)
@@ -1395,6 +1395,91 @@ Status ProcessGDBRemote::DoResume() { return error; } +Status ProcessGDBRemote::DoResumeReverse() { + Status error; + Log *log = GetLog(GDBRLog::Process); + LLDB_LOGF(log, "ProcessGDBRemote::DoResumeReverse()"); + + ListenerSP listener_sp( + Listener::MakeListener("gdb-remote.resume-packet-sent")); + if (listener_sp->StartListeningForEvents( + &m_gdb_comm, GDBRemoteClientBase::eBroadcastBitRunPacketSent)) { +listener_sp->StartListeningForEvents( +&m_async_broadcaster, +ProcessGDBRemote::eBroadcastBitAsyncThreadDidExit); + +const size_t num_threads = GetThreadList().GetSize(); + +StreamString continue_packet; + +const size_t num_continue_C_tids = m_continue_C_tids.size(); +const size_t num_continue_s_tids = m_continue_s_tids.size(); +const size_t num_continue_S_tids = m_continue_S_tids.size(); rocallahan wrote: Done. https://github.com/llvm/llvm-project/pull/99736 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Implement basic support for reverse-continue (PR #99736)
@@ -0,0 +1,79 @@ +import lldb +import unittest +from lldbsuite.test.lldbtest import * +from lldbsuite.test.decorators import * +from lldbsuite.test.gdbclientutils import * +from lldbsuite.test.lldbreverse import ReverseTestBase +from lldbsuite.test import lldbutil + + +class TestReverseContinueBreakpoints(ReverseTestBase): +@add_test_categories(["dwarf"]) +def test_reverse_continue(self): +target, process, initial_threads = self.setup_recording() + +# Reverse-continue. We'll stop at the point where we started recording. +status = process.ReverseContinue() +self.assertSuccess(status) +self.expect( +"thread list", +STOPPED_DUE_TO_HISTORY_BOUNDARY, +substrs=["stopped", "stop reason = history boundary"], +) + +# Continue forward normally until the target exits. +status = process.Continue() +self.assertSuccess(status) +self.assertState(process.GetState(), lldb.eStateExited) +self.assertEqual(process.GetExitStatus(), 0) + +@add_test_categories(["dwarf"]) +def test_reverse_continue_breakpoint(self): +target, process, initial_threads = self.setup_recording() + +# Reverse-continue to the function "trigger_breakpoint". +trigger_bkpt = target.BreakpointCreateByName("trigger_breakpoint", None) +status = process.ReverseContinue() +self.assertSuccess(status) +threads_now = lldbutil.get_threads_stopped_at_breakpoint(process, trigger_bkpt) +self.assertEqual(threads_now, initial_threads) rocallahan wrote: `lldbutil.get_threads_stopped_at_breakpoint()` returns the list of threads stopped at `trigger_bkpt`, and we check that this list is the test's only thread. If we stopped somewhere else, this list will be empty. https://github.com/llvm/llvm-project/pull/99736 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Implement basic support for reverse-continue (PR #99736)
@@ -0,0 +1,79 @@ +import lldb +import unittest +from lldbsuite.test.lldbtest import * +from lldbsuite.test.decorators import * +from lldbsuite.test.gdbclientutils import * +from lldbsuite.test.lldbreverse import ReverseTestBase +from lldbsuite.test import lldbutil + + +class TestReverseContinueBreakpoints(ReverseTestBase): +@add_test_categories(["dwarf"]) +def test_reverse_continue(self): +target, process, initial_threads = self.setup_recording() + +# Reverse-continue. We'll stop at the point where we started recording. +status = process.ReverseContinue() +self.assertSuccess(status) +self.expect( +"thread list", +STOPPED_DUE_TO_HISTORY_BOUNDARY, +substrs=["stopped", "stop reason = history boundary"], +) + +# Continue forward normally until the target exits. +status = process.Continue() +self.assertSuccess(status) +self.assertState(process.GetState(), lldb.eStateExited) +self.assertEqual(process.GetExitStatus(), 0) + +@add_test_categories(["dwarf"]) +def test_reverse_continue_breakpoint(self): +target, process, initial_threads = self.setup_recording() + +# Reverse-continue to the function "trigger_breakpoint". +trigger_bkpt = target.BreakpointCreateByName("trigger_breakpoint", None) +status = process.ReverseContinue() +self.assertSuccess(status) +threads_now = lldbutil.get_threads_stopped_at_breakpoint(process, trigger_bkpt) +self.assertEqual(threads_now, initial_threads) + +@add_test_categories(["dwarf"]) +def test_reverse_continue_skip_breakpoint(self): +target, process, initial_threads = self.setup_recording() + +# Reverse-continue, skipping a disabled breakpoint at "trigger_breakpoint". +trigger_bkpt = target.BreakpointCreateByName("trigger_breakpoint", None) +trigger_bkpt.SetCondition("0") rocallahan wrote: Sorry, my comment was misleading. The goal here is to test reverse-continuing over a conditional breakpoint whose condition is false. We need to continue in the same direction we were going --- if we're not careful we continue forwards from the breakpoint instead, which is broken :-). I've fixed the comment. https://github.com/llvm/llvm-project/pull/99736 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Implement basic support for reverse-continue (PR #99736)
@@ -0,0 +1,12 @@ +static void start_recording() {} + +static void trigger_breakpoint() {} + +static void stop_recording() {} rocallahan wrote: None of that functionality interacts with reverse execution, so I don't think we need to test it in combination with reverse execution in LLDB. For most purposes reverse execution behaves just like forward execution from LLDB's point of view: there's a stop, then LLDB reads the new target state (memory and registers, mainly) to display information to the user. (There are certainly issues that aren't covered here, e.g. handling the creation and destruction of threads, handling the loading and unloading of shared libraries, and handling watchpoints all interact with reverse execution. I plan to address some of these issues in future work, with their own tests. I'm trying to keep this PR as minimal as possible.) https://github.com/llvm/llvm-project/pull/99736 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Implement basic support for reverse-continue (PR #99736)
@@ -0,0 +1,79 @@ +import lldb +import unittest +from lldbsuite.test.lldbtest import * +from lldbsuite.test.decorators import * +from lldbsuite.test.gdbclientutils import * +from lldbsuite.test.lldbreverse import ReverseTestBase +from lldbsuite.test import lldbutil + + +class TestReverseContinueBreakpoints(ReverseTestBase): +@add_test_categories(["dwarf"]) +def test_reverse_continue(self): +target, process, initial_threads = self.setup_recording() + +# Reverse-continue. We'll stop at the point where we started recording. +status = process.ReverseContinue() +self.assertSuccess(status) +self.expect( +"thread list", +STOPPED_DUE_TO_HISTORY_BOUNDARY, +substrs=["stopped", "stop reason = history boundary"], +) + +# Continue forward normally until the target exits. +status = process.Continue() +self.assertSuccess(status) +self.assertState(process.GetState(), lldb.eStateExited) +self.assertEqual(process.GetExitStatus(), 0) + +@add_test_categories(["dwarf"]) +def test_reverse_continue_breakpoint(self): +target, process, initial_threads = self.setup_recording() + +# Reverse-continue to the function "trigger_breakpoint". +trigger_bkpt = target.BreakpointCreateByName("trigger_breakpoint", None) +status = process.ReverseContinue() +self.assertSuccess(status) +threads_now = lldbutil.get_threads_stopped_at_breakpoint(process, trigger_bkpt) +self.assertEqual(threads_now, initial_threads) + +@add_test_categories(["dwarf"]) +def test_reverse_continue_skip_breakpoint(self): +target, process, initial_threads = self.setup_recording() + +# Reverse-continue, skipping a disabled breakpoint at "trigger_breakpoint". +trigger_bkpt = target.BreakpointCreateByName("trigger_breakpoint", None) +trigger_bkpt.SetCondition("0") +status = process.ReverseContinue() +self.assertSuccess(status) +self.expect( +"thread list", +STOPPED_DUE_TO_HISTORY_BOUNDARY, +substrs=["stopped", "stop reason = history boundary"], +) + +def setup_recording(self): +""" +Record execution of code between "start_recording" and "stop_recording" breakpoints. + +Returns with the target stopped at "stop_recording", with recording disabled, +ready to reverse-execute. +""" +self.build() +target = self.dbg.CreateTarget("") +process = self.connect(target) + +# Record execution from the start of the function "start_recording" +# to the start of the function "stop_recording". +start_recording_bkpt = target.BreakpointCreateByName("start_recording", None) +initial_threads = lldbutil.continue_to_breakpoint(process, start_recording_bkpt) +self.assertEqual(len(initial_threads), 1) +target.BreakpointDelete(start_recording_bkpt.GetID()) +self.start_recording() +stop_recording_bkpt = target.BreakpointCreateByName("stop_recording", None) +lldbutil.continue_to_breakpoint(process, stop_recording_bkpt) +target.BreakpointDelete(stop_recording_bkpt.GetID()) +self.stop_recording() rocallahan wrote: It's important that we only start recording at the `start_recording` function, not at the very start of the process, because recording execution from the start to `main` (which can be quite a lot of instructions) could be very slow and memory-hungry with the naive `lldbreverse` recorder. I've updated my comments to clarify this. I'm not sure how a stop-hook would help here. For efficiency we want to record the minimal range of instructions that supports the testing we want to do; the `start_recording` and `end_recording` functions mark the boundaries of that range. One-shot breakpoints would be conceptually simpler than manually deleting them, but when I wrote the API calls for one-shot it wasn't simpler. https://github.com/llvm/llvm-project/pull/99736 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Implement basic support for reverse-continue (PR #99736)
@@ -1881,18 +1970,24 @@ ThreadSP ProcessGDBRemote::SetThreadStopInfo( handled = true; } } else if (!signo) { -addr_t pc = thread_sp->GetRegisterContext()->GetPC(); -lldb::BreakpointSiteSP bp_site_sp = -thread_sp->GetProcess()->GetBreakpointSiteList().FindByAddress(pc); - -// If a thread is stopped at a breakpoint site, set that as the stop -// reason even if it hasn't executed the breakpoint instruction yet. -// We will silently step over the breakpoint when we resume execution -// and miss the fact that this thread hit the breakpoint. -if (bp_site_sp && bp_site_sp->ValidForThisThread(*thread_sp)) { - thread_sp->SetStopInfo(StopInfo::CreateStopReasonWithBreakpointSiteID( - *thread_sp, bp_site_sp->GetID())); +if (m_last_run_direction == eRunReverse) { rocallahan wrote: Good idea, thanks. https://github.com/llvm/llvm-project/pull/99736 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Implement basic support for reverse-continue (PR #99736)
@@ -1881,18 +1970,24 @@ ThreadSP ProcessGDBRemote::SetThreadStopInfo( handled = true; } } else if (!signo) { -addr_t pc = thread_sp->GetRegisterContext()->GetPC(); -lldb::BreakpointSiteSP bp_site_sp = -thread_sp->GetProcess()->GetBreakpointSiteList().FindByAddress(pc); - -// If a thread is stopped at a breakpoint site, set that as the stop -// reason even if it hasn't executed the breakpoint instruction yet. -// We will silently step over the breakpoint when we resume execution -// and miss the fact that this thread hit the breakpoint. -if (bp_site_sp && bp_site_sp->ValidForThisThread(*thread_sp)) { - thread_sp->SetStopInfo(StopInfo::CreateStopReasonWithBreakpointSiteID( - *thread_sp, bp_site_sp->GetID())); +if (m_last_run_direction == eRunReverse) { rocallahan wrote: Actually we don't need this code so I've taken it out. (The latest version of rr reports the history boundary stop using `replaylog` --- more or less standard, gdb has supported it for 16 years --- so this "signal 0 when reverse continuing" case would only be hit when using LLDB with non-latest rr, which I don't think we need to care about.) https://github.com/llvm/llvm-project/pull/99736 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Implement basic support for reverse-continue (PR #99736)
https://github.com/rocallahan updated https://github.com/llvm/llvm-project/pull/99736 >From 25e184d1f0d06c09726ef72c0b3f1966522ea3df Mon Sep 17 00:00:00 2001 From: Robert O'Callahan Date: Fri, 19 Jul 2024 22:46:42 +1200 Subject: [PATCH] [lldb] Implement basic support for reverse-continue This commit only adds support for the `SBProcess::ReverseContinue()` API. A user-accessible command for this will follow in a later commit. This feature depends on a gdbserver implementation (e.g. `rr`) providing support for the `bc` and `bs` packets. `lldb-server` does not support those packets, and there is no plan to change that. So, for testing purposes, `lldbreverse.py` wraps `lldb-server` with a Python implementation of *very limited* record-and-replay functionality. --- lldb/include/lldb/API/SBProcess.h | 2 + lldb/include/lldb/Target/Process.h| 25 +- lldb/include/lldb/Target/StopInfo.h | 3 + lldb/include/lldb/lldb-enumerations.h | 6 + .../Python/lldbsuite/test/gdbclientutils.py | 5 +- .../Python/lldbsuite/test/lldbgdbproxy.py | 176 .../Python/lldbsuite/test/lldbreverse.py | 418 ++ .../Python/lldbsuite/test/lldbtest.py | 2 + lldb/source/API/SBProcess.cpp | 20 + lldb/source/API/SBThread.cpp | 2 + .../source/Interpreter/CommandInterpreter.cpp | 3 +- .../Process/Linux/NativeThreadLinux.cpp | 3 + .../GDBRemoteCommunicationClient.cpp | 22 + .../gdb-remote/GDBRemoteCommunicationClient.h | 6 + .../GDBRemoteCommunicationServerLLGS.cpp | 1 + .../Process/gdb-remote/ProcessGDBRemote.cpp | 94 .../Process/gdb-remote/ProcessGDBRemote.h | 2 + lldb/source/Target/Process.cpp| 29 +- lldb/source/Target/StopInfo.cpp | 29 ++ lldb/source/Target/Thread.cpp | 8 +- .../reverse-execution/Makefile| 3 + .../TestReverseContinueBreakpoints.py | 119 + .../functionalities/reverse-execution/main.c | 14 + lldb/tools/lldb-dap/JSONUtils.cpp | 3 + lldb/tools/lldb-dap/LLDBUtils.cpp | 1 + 25 files changed, 979 insertions(+), 17 deletions(-) create mode 100644 lldb/packages/Python/lldbsuite/test/lldbgdbproxy.py create mode 100644 lldb/packages/Python/lldbsuite/test/lldbreverse.py create mode 100644 lldb/test/API/functionalities/reverse-execution/Makefile create mode 100644 lldb/test/API/functionalities/reverse-execution/TestReverseContinueBreakpoints.py create mode 100644 lldb/test/API/functionalities/reverse-execution/main.c diff --git a/lldb/include/lldb/API/SBProcess.h b/lldb/include/lldb/API/SBProcess.h index 778be79583990..9b17bac0093e6 100644 --- a/lldb/include/lldb/API/SBProcess.h +++ b/lldb/include/lldb/API/SBProcess.h @@ -160,6 +160,8 @@ class LLDB_API SBProcess { lldb::SBError Continue(); + lldb::SBError ReverseContinue(); + lldb::SBError Stop(); lldb::SBError Kill(); diff --git a/lldb/include/lldb/Target/Process.h b/lldb/include/lldb/Target/Process.h index c8475db8ae160..203d3484f3704 100644 --- a/lldb/include/lldb/Target/Process.h +++ b/lldb/include/lldb/Target/Process.h @@ -874,10 +874,10 @@ class Process : public std::enable_shared_from_this, /// \see Thread:Resume() /// \see Thread:Step() /// \see Thread:Suspend() - Status Resume(); + Status Resume(lldb::RunDirection direction = lldb::eRunForward); /// Resume a process, and wait for it to stop. - Status ResumeSynchronous(Stream *stream); + Status ResumeSynchronous(Stream *stream, lldb::RunDirection direction = lldb::eRunForward); /// Halts a running process. /// @@ -1136,6 +1136,22 @@ class Process : public std::enable_shared_from_this, return error; } + /// Like DoResume() but executes in reverse if supported. + /// + /// \return + /// Returns \b true if the process successfully resumes using + /// the thread run control actions, \b false otherwise. + /// + /// \see Thread:Resume() + /// \see Thread:Step() + /// \see Thread:Suspend() + virtual Status DoResumeReverse() { +Status error; +error.SetErrorStringWithFormatv( +"error: {0} does not support reverse execution of processes", GetPluginName()); +return error; + } + /// Called after resuming a process. /// /// Allow Process plug-ins to execute some code after resuming a process. @@ -2367,6 +2383,8 @@ class Process : public std::enable_shared_from_this, bool IsRunning() const; + lldb::RunDirection GetLastRunDirection() { return m_last_run_direction; } + DynamicCheckerFunctions *GetDynamicCheckers() { return m_dynamic_checkers_up.get(); } @@ -2861,7 +2879,7 @@ void PruneThreadPlans(); /// /// \return /// An Status object describing the success or failure of the resume. - Status PrivateResume(); + Status PrivateResume(lldb::RunDirection direction = lldb::eRunForward); // Called i
[Lldb-commits] [lldb] [lldb] Change lldb's breakpoint handling behavior (PR #96260)
mstorsjo wrote: FYI, I also ran into failures due to this change, when debugging on Windows (with DWARF). See the run in https://github.com/mstorsjo/actions-test/actions/runs/10020326811 vs https://github.com/mstorsjo/actions-test/actions/runs/10020393197. Thanks for reverting; hopefully it’s the same root cause as on other platforms. https://github.com/llvm/llvm-project/pull/96260 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Change lldb's breakpoint handling behavior (PR #96260)
jasonmolenda wrote: > FYI, I also ran into failures due to this change, when debugging on Windows > (with DWARF). See the run in > https://github.com/mstorsjo/actions-test/actions/runs/10020326811 vs > https://github.com/mstorsjo/actions-test/actions/runs/10020393197. Thanks for > reverting; hopefully it’s the same root cause as on other platforms. oooh that 10020393197 is surprising. It looks like we hit a breakpoint, did `finish` up until a recursive function and it resumed execution without stopping. I haven't seen that one before, and not sure how I could have introduced it. I'll def need to look at my ProcessWindows changes and again see if I can't figure out what might be going on. Aleksandr ran a slightly earlier version of the windows changes against the lldb testsuite and didn't uncover any problems, but it didn't include this test file. @mstorsjo is this test source file on-line somewhere, or can you paste it into a comment? I'll try to repo on linux or macos too, maybe it is a unique corner case unrelated to Windows that is a problem. (unlikely, but you never know if we might get lucky). Thanks for the heads-up. https://github.com/llvm/llvm-project/pull/96260 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Change lldb's breakpoint handling behavior (PR #96260)
mstorsjo wrote: > > FYI, I also ran into failures due to this change, when debugging on Windows > > (with DWARF). See the run in > > https://github.com/mstorsjo/actions-test/actions/runs/10020326811 vs > > https://github.com/mstorsjo/actions-test/actions/runs/10020393197. Thanks > > for reverting; hopefully it’s the same root cause as on other platforms. > > oooh that 10020393197 is surprising. It looks like we hit a breakpoint, did > `finish` up until a recursive function and it resumed execution without > stopping. I haven't seen that one before, and not sure how I could have > introduced it. I'll def need to look at my ProcessWindows changes and again > see if I can't figure out what might be going on. Aleksandr ran a slightly > earlier version of the windows changes against the lldb testsuite and didn't > uncover any problems, but it didn't include this test file. > > @mstorsjo is this test source file on-line somewhere, or can you paste it > into a comment? I'll try to repo on linux or macos too, maybe it is a unique > corner case unrelated to Windows that is a problem. (unlikely, but you never > know if we might get lucky). Thanks for the heads-up. The source to this testcase is https://github.com/mstorsjo/llvm-mingw/blob/master/test/hello-exception.cpp, and I put up a prebuilt binary at https://martin.st/temp/hello-exception-dwarf.exe, if you want to have a look at it in that form. I'm running LLDB with the following input: https://github.com/mstorsjo/llvm-mingw/blob/master/run-lldb-tests.sh#L111-L120 ``` # Test setting a breakpoint in LLDB, checking the backtrace when we hit it, # stepping from the breakpoint, and running to completion. cat > $SCRIPT < $OUT 2>/dev/null ``` FWIW, interestingly, the issue did seem to appear on x86_64, but not on i386. This was with a non-optimized build of it, in case that makes any difference (as it sometimes does for how unwinding etc behaves). https://github.com/llvm/llvm-project/pull/96260 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] IRMemoryMap zero address mapping fix (PR #99045)
jasonmolenda wrote: I haven't tested it (or even tried to compile it, lol) but I think this loop might be expressable as simply ``` MemoryRegionInfo region_info; while (process_sp->GetMemoryRegionInfo(ret, region_info) == err.Success() && region_info.GetRange().GetRangeEnd() - 1 < end_of_memory) { // Don't ever choose a memory region starting at address 0, // it will conflict with programs that deference null pointers. if (ret == 0) { ret = region_info.GetRange().GetRangeEnd(); continue; } // A memory region that is inaccessible, and large enough, is a good // choice. if (region_info.GetReadable() != MemoryRegionInfo::OptionalBool::eNo && region_info.GetWritable() != MemoryRegionInfo::OptionalBool::eNo && region_info.GetExecutable() != MemoryRegionInfo::OptionalBool::eNo) { if (ret + size < region_info.GetRange().GetRangeEnd()) { return ret; } } // Get the next region. ret = region_info.GetRange().GetRangeEnd(); } ``` I dropped two behaviors here - one is that it would emit a unique assert if qMemoryRegionInfo worked once, but failed for a different address. The second is that I think the old code would try to combine consecutive memory regions to make one block large enough to satisfy the size requirement (not sure it was doing this correctly). https://github.com/llvm/llvm-project/pull/99045 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] IRMemoryMap zero address mapping fix (PR #99045)
jasonmolenda wrote: Ah, but I see my misunderstanding as I look at what debugserver returns. It uses "no permissions" to indicate a memory range that is unmapped -- ``` < 23> send packet: $qMemoryRegionInfo:0#44 < 27> read packet: $start:0;size:1;#00 < 31> send packet: $qMemoryRegionInfo:1#c5 < 67> read packet: $start:1;size:4000;permissions:rx;dirty-pages:1;#00 < 31> send packet: $qMemoryRegionInfo:14000#c9 < 57> read packet: $start:14000;size:4000;permissions:r;dirty-pages:;#00 < 31> send packet: $qMemoryRegionInfo:18000#cd < 32> read packet: $start:18000;size:404000;#00 < 31> send packet: $qMemoryRegionInfo:10040c000#fc < 198> read packet: $start:10040c000;size:4;permissions:rw;dirty-pages:10040c000,10041,100414000,100418000,10041c000,10042,100424000,100428000,10042c000,10043,100434000,100438000,10043c000,10044;#00 ``` 0x18000-0x00010040c000 is a free address range in this example, and what this loop should choose if it had to find an unused memory range. That conflicts with the behavior that this PR started with originally, where no permissions were returned for any memory regions --- which looks like the way debugserver reports a free memory region. (The low 4 GB segment at the start of my output above is the PAGEZERO empty segment of virtual address space on 64-bit darwin processes) https://github.com/llvm/llvm-project/pull/99045 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][Windows] Fixed Host::Kill() (PR #99721)
https://github.com/JDevlieghere approved this pull request. Neat https://github.com/llvm/llvm-project/pull/99721 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits