[Lldb-commits] [lldb] [lldb][Windows] Fixed Host::Kill() (PR #99721)

2024-07-20 Thread Dmitry Vasilyev via lldb-commits

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)

2024-07-20 Thread Med Ismail Bennani via lldb-commits

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)

2024-07-20 Thread Dmitry Vasilyev via lldb-commits

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)

2024-07-20 Thread Dmitry Vasilyev via lldb-commits

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)

2024-07-20 Thread Walter Erquinigo via lldb-commits

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)

2024-07-20 Thread Robert O'Callahan via lldb-commits

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)

2024-07-20 Thread Robert O'Callahan via lldb-commits


@@ -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)

2024-07-20 Thread Robert O'Callahan via lldb-commits


@@ -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)

2024-07-20 Thread Robert O'Callahan via lldb-commits


@@ -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)

2024-07-20 Thread Robert O'Callahan via lldb-commits


@@ -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)

2024-07-20 Thread Robert O'Callahan via lldb-commits


@@ -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)

2024-07-20 Thread Robert O'Callahan via lldb-commits


@@ -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)

2024-07-20 Thread Robert O'Callahan via lldb-commits


@@ -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)

2024-07-20 Thread Robert O'Callahan via lldb-commits

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)

2024-07-20 Thread Martin Storsjö via lldb-commits

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)

2024-07-20 Thread Jason Molenda via lldb-commits

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)

2024-07-20 Thread Martin Storsjö via lldb-commits

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)

2024-07-20 Thread Jason Molenda via lldb-commits

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)

2024-07-20 Thread Jason Molenda via lldb-commits

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)

2024-07-20 Thread Jonas Devlieghere via lldb-commits

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