[Lldb-commits] [lldb] [lldb] Implement basic support for reverse-continue (PR #99736)

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

https://github.com/rocallahan created 
https://github.com/llvm/llvm-project/pull/99736

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 for use by *tests only*.

The majority of this PR is test infrastructure (about 700 of the 950 lines 
added).

>From ce13a715cf12571431b5d7cfc9293dfaa1ff2d4b 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 |   4 +
 .../Python/lldbsuite/test/gdbclientutils.py   |   5 +-
 .../Python/lldbsuite/test/lldbgdbproxy.py | 176 
 .../Python/lldbsuite/test/lldbreverse.py  | 415 ++
 .../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   | 119 -
 .../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 |  79 
 .../functionalities/reverse-execution/main.c  |  12 +
 lldb/tools/lldb-dap/JSONUtils.cpp |   3 +
 lldb/tools/lldb-dap/LLDBUtils.cpp |   1 +
 25 files changed, 946 insertions(+), 28 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 

[Lldb-commits] [lldb] [lldb] Implement basic support for reverse-continue (PR #99736)

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

rocallahan wrote:

BTW this was discussed in 
https://discourse.llvm.org/t/how-to-test-reverse-execution-support-in-lldb/79696.

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] Implement basic support for reverse-continue (PR #99736)

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


@@ -160,6 +160,8 @@ class LLDB_API SBProcess {
 
   lldb::SBError Continue();
 
+  lldb::SBError ReverseContinue();

rocallahan wrote:

Yeah OK.

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-22 Thread Robert O'Callahan via lldb-commits


@@ -1395,6 +1395,94 @@ 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;
+
+// Number of threads continuing with "C", i.e. continuing with a signal to 
deliver.
+const size_t num_continue_C_tids = m_continue_C_tids.size();
+// Number of threads continuing with "s", i.e. single-stepping.
+const size_t num_continue_s_tids = m_continue_s_tids.size();
+// Number of threads continuing with "S", i.e. single-stepping with a 
signal to deliver.
+const size_t num_continue_S_tids = m_continue_S_tids.size();
+// We can only `bc` to reverse-continue all threads,
+// or `bs` to reverse-step the current thread (which may also
+// reverse-continue other threads by some amount).
+// These packets do not support delivering signals.
+if (num_continue_C_tids > 0 || num_continue_S_tids > 0) {
+  error.SetErrorString("can't deliver signals while running in reverse");
+  LLDB_LOGF(log, "ProcessGDBRemote::DoResumeReverse: Signals not 
supported");
+  return error;
+}
+
+if (num_continue_s_tids > 0) {
+  if (num_continue_s_tids > 1) {
+error.SetErrorString("can't step multiple threads while 
reverse-stepping");
+LLDB_LOGF(log, "ProcessGDBRemote::DoResumeReverse: can't step multiple 
threads");
+return error;
+  }
+
+  if (!m_gdb_comm.GetReverseStepSupported()) {
+error.SetErrorString("target does not support reverse-stepping");
+LLDB_LOGF(log, "ProcessGDBRemote::DoResumeReverse: target does not 
support reverse-stepping");
+return error;
+  }
+
+  m_gdb_comm.SetCurrentThreadForRun(m_continue_s_tids.front());
+  continue_packet.PutCString("bs");
+} else {
+  if (!m_gdb_comm.GetReverseContinueSupported()) {
+error.SetErrorString("target does not support reverse-continue");
+LLDB_LOGF(log, "ProcessGDBRemote::DoResumeReverse: target does not 
support reverse-continue");
+return error;
+  }
+
+  // All threads continue whether requested or not ---
+  // we can't change how threads ran in the past.
+  continue_packet.PutCString("bc");
+}
+
+EventSP event_sp;
+if (!m_async_thread.IsJoinable()) {
+  error.SetErrorString("Trying to resume but the async thread is dead.");
+  LLDB_LOGF(log, "ProcessGDBRemote::DoResumeReverse: Trying to resume but 
the "
+ "async thread is dead.");
+  return error;
+}
+
+auto data_sp =
+std::make_shared(continue_packet.GetString());
+m_async_broadcaster.BroadcastEvent(eBroadcastBitAsyncContinue, data_sp);
+
+if (!listener_sp->GetEvent(event_sp, std::chrono::seconds(5))) {

rocallahan wrote:

This was copied from `ProcessGDBRemote::DoResume()`. I can refactor that.

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-22 Thread Robert O'Callahan via lldb-commits


@@ -3264,6 +3266,11 @@ Status Process::PrivateResume() {
   // filters before resuming.
   UpdateAutomaticSignalFiltering();
 
+  if (m_last_run_direction != direction) {

rocallahan wrote:

TBH I don't understand thread plans very well yet so I was trying to avoid 
interacting with them. I guess implementing your suggestion means extending 
thread plans with a `RunDirection`, and/or creating new plan subclasses? And 
then we'd have to test a lot of interactions. Would it be OK to defer that to a 
future patch to keep this patch reasonably small?

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-22 Thread Robert O'Callahan via lldb-commits


@@ -3264,6 +3266,11 @@ Status Process::PrivateResume() {
   // filters before resuming.
   UpdateAutomaticSignalFiltering();
 
+  if (m_last_run_direction != direction) {

rocallahan wrote:

I'm a bit worried that in general thread plans have a lot of complexity, and 
adding more complexity by allowing multiple stacked plans with different 
directions might be bad enough for maintainability that it's overall a bad idea.

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-22 Thread Robert O'Callahan via lldb-commits


@@ -3264,6 +3266,11 @@ Status Process::PrivateResume() {
   // filters before resuming.
   UpdateAutomaticSignalFiltering();
 
+  if (m_last_run_direction != direction) {

rocallahan wrote:

If the user does "continue", hits a breakpoint, does "reverse-step", and then 
"reverse-continue" presumably we do have to abandon the original "continue". 
Since this patch only implements "reverse-continue" maybe always abandoning the 
thread plans actually the right thing to do for now?

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-22 Thread Robert O'Callahan via lldb-commits

https://github.com/rocallahan edited 
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-22 Thread Robert O'Callahan via lldb-commits


@@ -3281,7 +3288,11 @@ Status Process::PrivateResume() {
 "Process::PrivateResume PreResumeActions failed, not resuming.");
   } else {
 m_mod_id.BumpResumeID();
-error = DoResume();
+if (direction == eRunForward) {
+  error = DoResume();

rocallahan wrote:

The advantage of separate `DoResume()` and `DoResumeReverse()` methods is that 
`Process` subclasses that don't support reverse execution don't have to change 
at all; they inherit the default `DoResumeReverse()` that returns an error. If 
I make `DoResume()` take a direction parameter then those implementations 
(three out of four AFAICT) need to add a check of the direction parameter. It's 
not a big deal, I'll change it.

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-22 Thread Robert O'Callahan via lldb-commits

rocallahan wrote:

> You might have to be careful in the case where someone runs a function call, 
> stops at a breakpoint in the function call and decides to go backwards in the 
> function execution (if that's possible).

That is not possible in rr. During user function calls it responds to reverse 
execution requests with an immediate stop.

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-22 Thread Robert O'Callahan via lldb-commits

https://github.com/rocallahan updated 
https://github.com/llvm/llvm-project/pull/99736

>From 5ecca71b03027e132f3b75612c0783a68eafdf4f 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|  20 +-
 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 |   6 +-
 lldb/source/API/SBThread.cpp  |   2 +
 .../source/Interpreter/CommandInterpreter.cpp |   3 +-
 .../Process/Linux/NativeThreadLinux.cpp   |   3 +
 .../Process/MacOSX-Kernel/ProcessKDP.cpp  |   9 +-
 .../Process/MacOSX-Kernel/ProcessKDP.h|   2 +-
 .../Process/Windows/Common/ProcessWindows.cpp |   8 +-
 .../Process/Windows/Common/ProcessWindows.h   |   2 +-
 .../GDBRemoteCommunicationClient.cpp  |  22 +
 .../gdb-remote/GDBRemoteCommunicationClient.h |   6 +
 .../GDBRemoteCommunicationServerLLGS.cpp  |   1 +
 .../Process/gdb-remote/ProcessGDBRemote.cpp   |  78 +++-
 .../Process/gdb-remote/ProcessGDBRemote.h |   2 +-
 .../Process/scripted/ScriptedProcess.cpp  |  11 +-
 .../Process/scripted/ScriptedProcess.h|   2 +-
 lldb/source/Target/Process.cpp|  25 +-
 lldb/source/Target/StopInfo.cpp   |  29 ++
 lldb/source/Target/Thread.cpp |   8 +-
 .../reverse-execution/Makefile|   3 +
 .../TestReverseContinueBreakpoints.py | 119 +
 .../TestReverseContinueNotSupported.py|  29 ++
 .../functionalities/reverse-execution/main.c  |  14 +
 lldb/tools/lldb-dap/JSONUtils.cpp |   3 +
 lldb/tools/lldb-dap/LLDBUtils.cpp |   1 +
 32 files changed, 976 insertions(+), 44 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/TestReverseContinueNotSupported.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..cb7775ae94e46 100644
--- a/lldb/include/lldb/API/SBProcess.h
+++ b/lldb/include/lldb/API/SBProcess.h
@@ -158,7 +158,7 @@ class LLDB_API SBProcess {
 
   lldb::SBError Destroy();
 
-  lldb::SBError Continue();
+  lldb::SBError Continue(RunDirection direction = RunDirection::eRunForward);
 
   lldb::SBError Stop();
 
diff --git a/lldb/include/lldb/Target/Process.h 
b/lldb/include/lldb/Target/Process.h
index c8475db8ae160..51d9c166fdda5 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.
   ///
@@ -1129,10 +1129,15 @@ class Process : public 
std::enable_shared_from_this,
   /// \see Thread:Resume()
   /// \see Thread:Step()
   /// \see Thread:Suspend()
-  virtual Status DoResume() {
+  virtual Status DoResume(lldb::RunDirection direction) {
 Status error;
-error.SetErrorStringWithFormatv(
-"error: {0} does not support resuming processes", GetPluginName());
+if (direction == lldb::RunDirection::eRunForward) {
+  error.SetErrorStringWithFormatv(
+  "error: {0} does not support resuming processes", GetPluginName());
+} else {
+  error.SetErrorStringWithFormatv(
+  "error: {0} does not support reverse execution of processes", 
GetPluginName());
+}
 return error;
   }
 
@@ -2

[Lldb-commits] [lldb] [lldb] Implement basic support for reverse-continue (PR #99736)

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


@@ -3281,7 +3288,11 @@ Status Process::PrivateResume() {
 "Process::PrivateResume PreResumeActions failed, not resuming.");
   } else {
 m_mod_id.BumpResumeID();
-error = DoResume();
+if (direction == eRunForward) {
+  error = DoResume();

rocallahan wrote:

I've updated the branch with all these changes.

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-23 Thread Robert O'Callahan via lldb-commits


@@ -0,0 +1,176 @@
+import logging
+import os
+import os.path
+import random
+
+import lldb
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test.gdbclientutils import *
+import lldbgdbserverutils
+from lldbsuite.support import seven
+
+
+class GDBProxyTestBase(TestBase):
+"""
+Base class for gdbserver proxy tests.
+
+This class will setup and start a mock GDB server for the test to use.
+It pases through requests to a regular lldb-server/debugserver and
+forwards replies back to the LLDB under test.
+"""
+
+"""The gdbserver that we implement."""
+server = None
+"""The inner lldb-server/debugserver process that we proxy requests 
into."""
+monitor_server = None
+monitor_sock = None
+
+server_socket_class = TCPServerSocket
+
+DEFAULT_TIMEOUT = 20 * (10 if ("ASAN_OPTIONS" in os.environ) else 1)
+
+_verbose_log_handler = None
+_log_formatter = logging.Formatter(fmt="%(asctime)-15s %(levelname)-8s 
%(message)s")
+
+def setUpBaseLogging(self):
+self.logger = logging.getLogger(__name__)
+
+if len(self.logger.handlers) > 0:
+return  # We have set up this handler already
+
+self.logger.propagate = False
+self.logger.setLevel(logging.DEBUG)
+
+# log all warnings to stderr
+handler = logging.StreamHandler()
+handler.setLevel(logging.WARNING)
+handler.setFormatter(self._log_formatter)
+self.logger.addHandler(handler)
+
+def setUp(self):
+TestBase.setUp(self)
+
+self.setUpBaseLogging()
+
+if self.isVerboseLoggingRequested():
+# If requested, full logs go to a log file
+log_file_name = self.getLogBasenameForCurrentTest() + "-proxy.log"
+self._verbose_log_handler = logging.FileHandler(
+   log_file_name
+)
+self._verbose_log_handler.setFormatter(self._log_formatter)
+self._verbose_log_handler.setLevel(logging.DEBUG)
+self.logger.addHandler(self._verbose_log_handler)
+
+self.port = self.get_next_port()

rocallahan wrote:

Yes, fixed.

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-23 Thread Robert O'Callahan via lldb-commits


@@ -0,0 +1,119 @@
+import lldb
+import time
+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"])

rocallahan wrote:

Yes, thanks for that.

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-23 Thread Robert O'Callahan via lldb-commits


@@ -158,7 +158,7 @@ class LLDB_API SBProcess {
 
   lldb::SBError Destroy();
 
-  lldb::SBError Continue();
+  lldb::SBError Continue(RunDirection direction = RunDirection::eRunForward);

rocallahan wrote:

Yeah, I originally wrote everything as you suggested, and @jimingham asked me 
to change it to what you see now. So I need you two to come to an agreement and 
tell me what it is.

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-23 Thread Robert O'Callahan via lldb-commits


@@ -1363,6 +1374,43 @@ Status ProcessGDBRemote::DoResume() {
   }
 }
 
+if (direction == RunDirection::eRunReverse && continue_packet_error) {
+  if (num_continue_C_tids > 0 || num_continue_S_tids > 0) {
+error.SetErrorString("can't deliver signals while running in reverse");
+LLDB_LOGF(log, "ProcessGDBRemote::DoResumeReverse: Signals not 
supported");
+return error;
+  }
+
+  if (num_continue_s_tids > 0) {
+if (num_continue_s_tids > 1) {
+  error.SetErrorString("can't step multiple threads while 
reverse-stepping");
+  LLDB_LOGF(log, "ProcessGDBRemote::DoResumeReverse: can't step 
multiple threads");
+  return error;
+}
+
+if (!m_gdb_comm.GetReverseStepSupported()) {
+  error.SetErrorString("target does not support reverse-stepping");
+  LLDB_LOGF(log, "ProcessGDBRemote::DoResumeReverse: target does not 
support reverse-stepping");
+  return error;
+}
+
+m_gdb_comm.SetCurrentThreadForRun(m_continue_s_tids.front());
+continue_packet.PutCString("bs");
+  } else {
+if (!m_gdb_comm.GetReverseContinueSupported()) {

rocallahan wrote:

We need to determine whether we're going to step or continue first, so we can 
check whether the specific packet (`bs` or `bc`) we need is supported. I 
suppose we could collapse them into one feature flag and check that flag a bit 
earlier --- that would work fine in practice --- but I think what I have here, 
with a feature flag check right where we use that exact feature,  is a little 
more intuitive. I think the priority here should be the simplest, clearest 
code; "user tries to reverse-continue but that's not supported" is not a case 
that needs to be optimized.

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-23 Thread Robert O'Callahan via lldb-commits

https://github.com/rocallahan updated 
https://github.com/llvm/llvm-project/pull/99736

>From 026930762e967f84f48f8958c2448734692ad62f 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|  20 +-
 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 | 175 
 .../Python/lldbsuite/test/lldbreverse.py  | 418 ++
 .../Python/lldbsuite/test/lldbtest.py |   2 +
 lldb/source/API/SBProcess.cpp |   6 +-
 lldb/source/API/SBThread.cpp  |   2 +
 .../source/Interpreter/CommandInterpreter.cpp |   3 +-
 .../Process/Linux/NativeThreadLinux.cpp   |   3 +
 .../Process/MacOSX-Kernel/ProcessKDP.cpp  |   9 +-
 .../Process/MacOSX-Kernel/ProcessKDP.h|   2 +-
 .../Process/Windows/Common/ProcessWindows.cpp |   8 +-
 .../Process/Windows/Common/ProcessWindows.h   |   2 +-
 .../GDBRemoteCommunicationClient.cpp  |  22 +
 .../gdb-remote/GDBRemoteCommunicationClient.h |   6 +
 .../GDBRemoteCommunicationServerLLGS.cpp  |   1 +
 .../Process/gdb-remote/ProcessGDBRemote.cpp   |  78 +++-
 .../Process/gdb-remote/ProcessGDBRemote.h |   2 +-
 .../Process/scripted/ScriptedProcess.cpp  |  11 +-
 .../Process/scripted/ScriptedProcess.h|   2 +-
 lldb/source/Target/Process.cpp|  25 +-
 lldb/source/Target/StopInfo.cpp   |  29 ++
 lldb/source/Target/Thread.cpp |   8 +-
 .../reverse-execution/Makefile|   3 +
 .../TestReverseContinueBreakpoints.py | 115 +
 .../TestReverseContinueNotSupported.py|  30 ++
 .../functionalities/reverse-execution/main.c  |  14 +
 lldb/tools/lldb-dap/JSONUtils.cpp |   3 +
 lldb/tools/lldb-dap/LLDBUtils.cpp |   1 +
 32 files changed, 972 insertions(+), 44 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/TestReverseContinueNotSupported.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..cb7775ae94e46 100644
--- a/lldb/include/lldb/API/SBProcess.h
+++ b/lldb/include/lldb/API/SBProcess.h
@@ -158,7 +158,7 @@ class LLDB_API SBProcess {
 
   lldb::SBError Destroy();
 
-  lldb::SBError Continue();
+  lldb::SBError Continue(RunDirection direction = RunDirection::eRunForward);
 
   lldb::SBError Stop();
 
diff --git a/lldb/include/lldb/Target/Process.h 
b/lldb/include/lldb/Target/Process.h
index c8475db8ae160..51d9c166fdda5 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.
   ///
@@ -1129,10 +1129,15 @@ class Process : public 
std::enable_shared_from_this,
   /// \see Thread:Resume()
   /// \see Thread:Step()
   /// \see Thread:Suspend()
-  virtual Status DoResume() {
+  virtual Status DoResume(lldb::RunDirection direction) {
 Status error;
-error.SetErrorStringWithFormatv(
-"error: {0} does not support resuming processes", GetPluginName());
+if (direction == lldb::RunDirection::eRunForward) {
+  error.SetErrorStringWithFormatv(
+  "error: {0} does not support resuming processes", GetPluginName());
+} else {
+  error.SetErrorStringWithFormatv(
+  "error: {0} does not support reverse execution of processes", 
GetPluginName());
+}
 return error;
   }
 
@@ -2

[Lldb-commits] [lldb] [lldb] Implement basic support for reverse-continue (PR #99736)

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

rocallahan wrote:

> Most of the execution control logic should just know "forward" and 
> "backwards", but then whether those are implemented by using the reverse 
> debugging machinery or by allowing the program to run for realz will be know 
> deeper in the execution control machinery - most likely governed by the 
> thread plans.

Actually LLDB is (and should be) oblivious to whether the gdbserver is running 
the program "for realz" or not.

When using rr, we currently *never* run the program "for realz" while the user 
is in a debugging session. The workflow is: a) record a program run and save 
the recording to disk b) replay the run with the debugger attached. During b), 
both forward and reverse execution are "on rails", only observing what happened 
during recording. (Ok, ignoring user-requested function calls made through the 
debugger for now.)

UndoDB and gdb's reverse execution are a bit different. They do support the 
workflow you're thinking of, where the program is actually "live" while you 
explore history in the past. But the distinction between "replaying through 
history" and "runinng live" is never surfaced in the gdbserver protocol and 
from the debugger's point of view I don't think it should matter.

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-25 Thread Robert O'Callahan via lldb-commits

rocallahan wrote:

> First off, for systems that do past motion and forward motion, there are 
> things you really can't do effectively in the past, like set variable values 
> and have that make any difference. So we probably will need to know whether 
> we're executing in the immutable past or the mutable present.

Fair point, but AFAIK with all these backends when you try to change state in a 
situation where that's not allowed, you just get an error from the backend. The 
gdbserver protocol doesn't tell you in advance whether that will be possible. I 
don't think this impacts LLDB really, as long as you don't crash when a state 
change fails.

> I am running "for realz", and I do a forward "next" which hits a breakpoint 
> before the next concludes.  I step over another function at that breakpoint.  
> I realize I wish I had stepped into it, so I do a "reverse next" - is that 
> how you do it - or set a breakpoint in the function and reverse continue.

FWIW rr doesn't support this workflow, but UndoDB does.

> Then I step around in the past a bit till I see what I wanted to see.  Then 
> I'm done with the past, and want to go back to the present.  Since the last 
> persistent action I had done was the original next, then `continue` should 
> take up that next (going forward) and complete it.  That is all pretty 
> straightforward, the "TheadPlanStepOverRange" - which is the current plan on 
> the plan stack - for that next knows it's going forward, so first it pushes a 
> "ThreadPlanTakeMeToThePresent" and when that completes, it can continue with 
> its forward motion.

In this case, I think ThreadPlanStepOverRange will just resume with a 
forward-continue packet. The backend continues forward through the recorded 
history until it reaches the end of the history, i.e. the current state of the 
stopped debuggee. Then it automatically resumes the debuggee and keeps going. 
There is no need for a ThreadPlanTakeMeToThePresent.

> So for systems that support live reverse debugging, I do think we'll need a 
> "reset to the present" gesture, and plans will need to know whether they are 
> operating on the past or present.

I think we'll need to have per-plan directions in some way, yes, but not "reset 
to the present".

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-26 Thread Robert O'Callahan via lldb-commits

rocallahan wrote:

One thing that's not entirely clear to me from the discussion so far: 
apparently the public API rules allow adding an overload of 
`SBProcess::Continue()` with a direction parameter. Do they allow just adding a 
direction parameter to the existing overload *with a default value*? Because 
the latter seems exactly like the former in practice, to me.

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-26 Thread Robert O'Callahan via lldb-commits

https://github.com/rocallahan updated 
https://github.com/llvm/llvm-project/pull/99736

>From e9a44b4cfd2e3423fbf5ac75124530cc2bb8afed 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 |   1 +
 lldb/include/lldb/Target/Process.h|  20 +-
 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 | 175 
 .../Python/lldbsuite/test/lldbreverse.py  | 418 ++
 .../Python/lldbsuite/test/lldbtest.py |   2 +
 lldb/source/API/SBProcess.cpp |   8 +-
 lldb/source/API/SBThread.cpp  |   2 +
 .../source/Interpreter/CommandInterpreter.cpp |   3 +-
 .../Process/Linux/NativeThreadLinux.cpp   |   3 +
 .../Process/MacOSX-Kernel/ProcessKDP.cpp  |   9 +-
 .../Process/MacOSX-Kernel/ProcessKDP.h|   2 +-
 .../Process/Windows/Common/ProcessWindows.cpp |   8 +-
 .../Process/Windows/Common/ProcessWindows.h   |   2 +-
 .../GDBRemoteCommunicationClient.cpp  |  22 +
 .../gdb-remote/GDBRemoteCommunicationClient.h |   6 +
 .../GDBRemoteCommunicationServerLLGS.cpp  |   1 +
 .../Process/gdb-remote/ProcessGDBRemote.cpp   |  78 +++-
 .../Process/gdb-remote/ProcessGDBRemote.h |   2 +-
 .../Process/scripted/ScriptedProcess.cpp  |  11 +-
 .../Process/scripted/ScriptedProcess.h|   2 +-
 lldb/source/Target/Process.cpp|  25 +-
 lldb/source/Target/StopInfo.cpp   |  29 ++
 lldb/source/Target/Thread.cpp |   8 +-
 .../reverse-execution/Makefile|   3 +
 .../TestReverseContinueBreakpoints.py | 115 +
 .../TestReverseContinueNotSupported.py|  30 ++
 .../functionalities/reverse-execution/main.c  |  14 +
 lldb/tools/lldb-dap/JSONUtils.cpp |   3 +
 lldb/tools/lldb-dap/LLDBUtils.cpp |   1 +
 32 files changed, 975 insertions(+), 42 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/TestReverseContinueNotSupported.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..ba069014defd2 100644
--- a/lldb/include/lldb/API/SBProcess.h
+++ b/lldb/include/lldb/API/SBProcess.h
@@ -159,6 +159,7 @@ class LLDB_API SBProcess {
   lldb::SBError Destroy();
 
   lldb::SBError Continue();
+  lldb::SBError Continue(RunDirection direction);
 
   lldb::SBError Stop();
 
diff --git a/lldb/include/lldb/Target/Process.h 
b/lldb/include/lldb/Target/Process.h
index c8475db8ae160..51d9c166fdda5 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.
   ///
@@ -1129,10 +1129,15 @@ class Process : public 
std::enable_shared_from_this,
   /// \see Thread:Resume()
   /// \see Thread:Step()
   /// \see Thread:Suspend()
-  virtual Status DoResume() {
+  virtual Status DoResume(lldb::RunDirection direction) {
 Status error;
-error.SetErrorStringWithFormatv(
-"error: {0} does not support resuming processes", GetPluginName());
+if (direction == lldb::RunDirection::eRunForward) {
+  error.SetErrorStringWithFormatv(
+  "error: {0} does not support resuming processes", GetPluginName());
+} else {
+  error.SetErrorStringWithFormatv(
+  "error: {0} does not support reverse execution of processes", 
GetPluginName());
+}
 return error;
   }
 
@@ -2367,6 +2372,8 @@ class Process 

[Lldb-commits] [lldb] [lldb] Implement basic support for reverse-continue (PR #99736)

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

rocallahan wrote:

> The two are different when it comes to the ABI

Yeah OK. I've fixed that.

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-29 Thread Robert O'Callahan via lldb-commits

rocallahan wrote:

> As it stands, this will allow "reverse continue to a breakpoint", right?

Using rr as the backend you can reverse-continue to any stop, including 
signals, watchpoints and the "history boundary" i.e. start of time. I expect 
the other stop types don't work well yet. I plan to work on them next. We can 
delay adding the CLI for reverse-continue until they work adequately.

> But once "in the past" you wouldn't be able to do either forward or reverse 
> steps, you are just going to navigate by breakpoint?

After reverse-continue you can do any kind of forward execution you want. With 
LLDB + rr, you're always "in the past" since during debugging rr always/only 
navigates history; when you're at a certain point in time the state of LLDB and 
rr is independent of whether you got there by forward or reverse execution. And 
LLDB + rr is pretty much fully functional already --- except for the absence of 
reverse-execution commands.

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-29 Thread Robert O'Callahan via lldb-commits

rocallahan wrote:

> Is there a notion of "reverse stepping" like "take me to the line that 
> preceded this one in execution history", and if so what contains the logic 
> that does that?

rr supports the "bs" gdbserver packet to reverse-step a single instruction (and 
so does the test proxy I'm adding here). To "reverse-next one line" we will 
need to implement a thread plan that uses a combination of 
reverse-step-instruction and reverse-continue-to-breakpoint. That's future 
work. It may be difficult, and it's also not very high priority because it 
tends not to get used very much by gdb users.

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-08-04 Thread Robert O'Callahan via lldb-commits

rocallahan wrote:

@clayborg as far as I can tell, the ball is currently in your court to respond 
to @jimingham ... thanks in advance

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-08-09 Thread Robert O'Callahan via lldb-commits

rocallahan wrote:

> > @clayborg as far as I can tell, the ball is currently in your court to 
> > respond to @jimingham ... thanks in advance
> 
> Sounds like Jim is on the fence with a SetDirection + existing APIs and 
> adding a direction to the calls. I am fine with either approach as long as 
> Jim is ok with it because Jim is the code owner of the thread plans so he has 
> better knowledge. Let me know if I missed any comment I should respond to 
> other than this.

The initial disagreement here was that you advocated for a `ReverseContinue()` 
function (etc) while Jim didn't want to add `Reverse` versions of functions. It 
sounds like you're on board with the latter now, so thanks for that.

So now the question is whether to expose a persistent "current direction" flag 
or pass the direction as a parameter (defaulting to "forward") to each call to 
a function that advances execution.

> It really comes down to how the GUI and command line commands work for 
> reverse debugging. So a few questions:
> 
> * Do GUI debuggers have different buttons for reverse stepping and 
> running? Or is there a direction button and then the existing process control 
> buttons remain the same (reverse continue, reverse step in/out/over)

I've only seen them use separate buttons, see e.g. [CLion + 
UndoDB](https://blog.jetbrains.com/clion/2016/09/undo-for-clion/).

> * For command line do we have different comments for forward and reverse, 
> or a direction command followed by normal commands?

GDB [supports 
both](https://sourceware.org/gdb/current/onlinedocs/gdb.html/Reverse-Execution.html).
 However, in practice I've never seen anyone use `set exec-direction`. My LLDB 
CLI patch adds a `-R` option to `thread continue`.

> If the GUI and command line have separate buttons and commands, then we 
> should probably go with adding the direction to each API.

OK, then I believe my current code is satisfactory.

> I could see us adding more options to the `SBThreadStepOptions` API in the 
> future and then our public API for `SBThread::StepOver` doesn't need to 
> change.

Sure. My current code doesn't support reverse stepping and the number of 
options to the `Continue()` APIs is small (zero currently for 
`SBProcess::Continue()`) so this isn't an issue yet.

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-08-09 Thread Robert O'Callahan via lldb-commits

https://github.com/rocallahan updated 
https://github.com/llvm/llvm-project/pull/99736

>From 52b133ee9fda7b6cc3b6300756e7b8ec82a6a9bf 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 |   1 +
 lldb/include/lldb/Target/Process.h|  20 +-
 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 | 175 
 .../Python/lldbsuite/test/lldbreverse.py  | 418 ++
 .../Python/lldbsuite/test/lldbtest.py |   2 +
 lldb/source/API/SBProcess.cpp |   8 +-
 lldb/source/API/SBThread.cpp  |   2 +
 .../source/Interpreter/CommandInterpreter.cpp |   3 +-
 .../Process/Linux/NativeThreadLinux.cpp   |   3 +
 .../Process/MacOSX-Kernel/ProcessKDP.cpp  |   9 +-
 .../Process/MacOSX-Kernel/ProcessKDP.h|   2 +-
 .../Process/Windows/Common/ProcessWindows.cpp |   8 +-
 .../Process/Windows/Common/ProcessWindows.h   |   2 +-
 .../GDBRemoteCommunicationClient.cpp  |  22 +
 .../gdb-remote/GDBRemoteCommunicationClient.h |   6 +
 .../GDBRemoteCommunicationServerLLGS.cpp  |   1 +
 .../Process/gdb-remote/ProcessGDBRemote.cpp   |  78 +++-
 .../Process/gdb-remote/ProcessGDBRemote.h |   2 +-
 .../Process/scripted/ScriptedProcess.cpp  |  11 +-
 .../Process/scripted/ScriptedProcess.h|   2 +-
 lldb/source/Target/Process.cpp|  23 +-
 lldb/source/Target/StopInfo.cpp   |  29 ++
 lldb/source/Target/Thread.cpp |   8 +-
 .../reverse-execution/Makefile|   3 +
 .../TestReverseContinueBreakpoints.py | 115 +
 .../TestReverseContinueNotSupported.py|  30 ++
 .../functionalities/reverse-execution/main.c  |  14 +
 lldb/tools/lldb-dap/JSONUtils.cpp |   3 +
 lldb/tools/lldb-dap/LLDBUtils.cpp |   1 +
 32 files changed, 974 insertions(+), 41 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/TestReverseContinueNotSupported.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 778be795839901..ba069014defd24 100644
--- a/lldb/include/lldb/API/SBProcess.h
+++ b/lldb/include/lldb/API/SBProcess.h
@@ -159,6 +159,7 @@ class LLDB_API SBProcess {
   lldb::SBError Destroy();
 
   lldb::SBError Continue();
+  lldb::SBError Continue(RunDirection direction);
 
   lldb::SBError Stop();
 
diff --git a/lldb/include/lldb/Target/Process.h 
b/lldb/include/lldb/Target/Process.h
index cf16fbc812aa48..5fa6d54838f8c8 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.
   ///
@@ -1129,10 +1129,15 @@ class Process : public 
std::enable_shared_from_this,
   /// \see Thread:Resume()
   /// \see Thread:Step()
   /// \see Thread:Suspend()
-  virtual Status DoResume() {
+  virtual Status DoResume(lldb::RunDirection direction) {
 Status error;
-error.SetErrorStringWithFormatv(
-"error: {0} does not support resuming processes", GetPluginName());
+if (direction == lldb::RunDirection::eRunForward) {
+  error.SetErrorStringWithFormatv(
+  "error: {0} does not support resuming processes", GetPluginName());
+} else {
+  error.SetErrorStringWithFormatv(
+  "error: {0} does not support reverse execution of processes", 
GetPluginName());
+}
 return error;
   }
 
@@ -2373,6 +2378,8 @@ class Proc

[Lldb-commits] [lldb] [lldb] Implement basic support for reverse-continue (PR #99736)

2024-08-09 Thread Robert O'Callahan via lldb-commits

https://github.com/rocallahan updated 
https://github.com/llvm/llvm-project/pull/99736

>From 3aa5a6f08487314f12b7b0d2d13ccd20f306f16c 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 |   1 +
 lldb/include/lldb/Target/Process.h|  20 +-
 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 | 175 
 .../Python/lldbsuite/test/lldbreverse.py  | 418 ++
 .../Python/lldbsuite/test/lldbtest.py |   2 +
 lldb/source/API/SBProcess.cpp |   8 +-
 lldb/source/API/SBThread.cpp  |   2 +
 .../source/Interpreter/CommandInterpreter.cpp |   3 +-
 .../Process/Linux/NativeThreadLinux.cpp   |   3 +
 .../Process/MacOSX-Kernel/ProcessKDP.cpp  |   9 +-
 .../Process/MacOSX-Kernel/ProcessKDP.h|   2 +-
 .../Process/Windows/Common/ProcessWindows.cpp |   8 +-
 .../Process/Windows/Common/ProcessWindows.h   |   2 +-
 .../GDBRemoteCommunicationClient.cpp  |  22 +
 .../gdb-remote/GDBRemoteCommunicationClient.h |   6 +
 .../GDBRemoteCommunicationServerLLGS.cpp  |   1 +
 .../Process/gdb-remote/ProcessGDBRemote.cpp   |  78 +++-
 .../Process/gdb-remote/ProcessGDBRemote.h |   2 +-
 .../Process/scripted/ScriptedProcess.cpp  |  11 +-
 .../Process/scripted/ScriptedProcess.h|   2 +-
 lldb/source/Target/Process.cpp|  25 +-
 lldb/source/Target/StopInfo.cpp   |  29 ++
 lldb/source/Target/Thread.cpp |   8 +-
 .../reverse-execution/Makefile|   3 +
 .../TestReverseContinueBreakpoints.py | 115 +
 .../TestReverseContinueNotSupported.py|  30 ++
 .../functionalities/reverse-execution/main.c  |  14 +
 lldb/tools/lldb-dap/JSONUtils.cpp |   3 +
 lldb/tools/lldb-dap/LLDBUtils.cpp |   1 +
 32 files changed, 975 insertions(+), 42 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/TestReverseContinueNotSupported.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 778be795839901..ba069014defd24 100644
--- a/lldb/include/lldb/API/SBProcess.h
+++ b/lldb/include/lldb/API/SBProcess.h
@@ -159,6 +159,7 @@ class LLDB_API SBProcess {
   lldb::SBError Destroy();
 
   lldb::SBError Continue();
+  lldb::SBError Continue(RunDirection direction);
 
   lldb::SBError Stop();
 
diff --git a/lldb/include/lldb/Target/Process.h 
b/lldb/include/lldb/Target/Process.h
index cf16fbc812aa48..5fa6d54838f8c8 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.
   ///
@@ -1129,10 +1129,15 @@ class Process : public 
std::enable_shared_from_this,
   /// \see Thread:Resume()
   /// \see Thread:Step()
   /// \see Thread:Suspend()
-  virtual Status DoResume() {
+  virtual Status DoResume(lldb::RunDirection direction) {
 Status error;
-error.SetErrorStringWithFormatv(
-"error: {0} does not support resuming processes", GetPluginName());
+if (direction == lldb::RunDirection::eRunForward) {
+  error.SetErrorStringWithFormatv(
+  "error: {0} does not support resuming processes", GetPluginName());
+} else {
+  error.SetErrorStringWithFormatv(
+  "error: {0} does not support reverse execution of processes", 
GetPluginName());
+}
 return error;
   }
 
@@ -2373,6 +2378,8 @@ class Proc

[Lldb-commits] [lldb] [lldb] Implement basic support for reverse-continue (PR #99736)

2024-08-19 Thread Robert O'Callahan via lldb-commits

rocallahan wrote:

@clayborg @jimingham I think the issues you have raised so far are 
satisfactorily addressed by the current code. Can you confirm that is true? And 
if so, can we proceed with the actual code review? 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 #112079)

2024-10-11 Thread Robert O'Callahan via lldb-commits

https://github.com/rocallahan updated 
https://github.com/llvm/llvm-project/pull/112079

>From c373425ab4be848bb376d2710e13efafb6058d11 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 |   1 +
 lldb/include/lldb/Target/Process.h|  23 +-
 lldb/include/lldb/Target/StopInfo.h   |   6 +
 lldb/include/lldb/lldb-enumerations.h |   6 +
 .../Python/lldbsuite/test/gdbclientutils.py   |   5 +-
 .../Python/lldbsuite/test/lldbgdbproxy.py | 179 +++
 .../Python/lldbsuite/test/lldbreverse.py  | 444 ++
 .../Python/lldbsuite/test/lldbtest.py |   2 +
 lldb/source/API/SBProcess.cpp |   8 +-
 lldb/source/API/SBThread.cpp  |   2 +
 .../source/Interpreter/CommandInterpreter.cpp |   3 +-
 .../Process/Linux/NativeThreadLinux.cpp   |   3 +
 .../Process/MacOSX-Kernel/ProcessKDP.cpp  |  10 +-
 .../Process/MacOSX-Kernel/ProcessKDP.h|   2 +-
 .../Process/Windows/Common/ProcessWindows.cpp |   9 +-
 .../Process/Windows/Common/ProcessWindows.h   |   2 +-
 .../GDBRemoteCommunicationClient.cpp  |  22 +
 .../gdb-remote/GDBRemoteCommunicationClient.h |   6 +
 .../GDBRemoteCommunicationServerLLGS.cpp  |   1 +
 .../Process/gdb-remote/ProcessGDBRemote.cpp   |  88 +++-
 .../Process/gdb-remote/ProcessGDBRemote.h |   2 +-
 .../Process/scripted/ScriptedProcess.cpp  |  10 +-
 .../Process/scripted/ScriptedProcess.h|   2 +-
 lldb/source/Target/Process.cpp|  38 +-
 lldb/source/Target/StopInfo.cpp   |  29 ++
 lldb/source/Target/Thread.cpp |   8 +-
 .../reverse-execution/Makefile|   3 +
 .../TestReverseContinueBreakpoints.py | 123 +
 .../TestReverseContinueNotSupported.py|  30 ++
 .../functionalities/reverse-execution/main.c  |  14 +
 lldb/tools/lldb-dap/JSONUtils.cpp |   3 +
 lldb/tools/lldb-dap/LLDBUtils.cpp |   1 +
 32 files changed, 1035 insertions(+), 50 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/TestReverseContinueNotSupported.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 1624e02070b1b2..8b8ed830b54cc0 100644
--- a/lldb/include/lldb/API/SBProcess.h
+++ b/lldb/include/lldb/API/SBProcess.h
@@ -159,6 +159,7 @@ class LLDB_API SBProcess {
   lldb::SBError Destroy();
 
   lldb::SBError Continue();
+  lldb::SBError Continue(RunDirection direction);
 
   lldb::SBError Stop();
 
diff --git a/lldb/include/lldb/Target/Process.h 
b/lldb/include/lldb/Target/Process.h
index b8c53a474ba6b9..6efeb0d3694a6a 100644
--- a/lldb/include/lldb/Target/Process.h
+++ b/lldb/include/lldb/Target/Process.h
@@ -857,10 +857,11 @@ 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.
   ///
@@ -1104,9 +1105,15 @@ class Process : public 
std::enable_shared_from_this,
   /// \see Thread:Resume()
   /// \see Thread:Step()
   /// \see Thread:Suspend()
-  virtual Status DoResume() {
-return Status::FromErrorStringWithFormatv(
-"error: {0} does not support resuming processes", GetPluginName());
+  virtual Status DoResume(lldb::RunDirection direction) {
+if (direction == lldb::RunDirection::eRunForward) {
+  return Status::FromErrorStringWithFormatv(
+  "error: {0} does not support resuming processes", GetPluginName());
+} else {
+  return Status::FromErrorStringWithFormatv(
+  "error: {0} does not support reverse execution of processes",
+  GetPluginName());
+}
   }
 
   

[Lldb-commits] [lldb] [lldb] Implement basic support for reverse-continue (PR #99736)

2024-10-11 Thread Robert O'Callahan via lldb-commits

rocallahan wrote:

> added @skipIfDarwin markers to the TestReverseContinueBreakpoints.py and 
> TestReverseContinueNotSupported.py API tests because lldb-server is not 
> supported in gdbserver mode on Darwin systems

So there is no LLDB-based daemon that implements the gdbserver protocol on 
Darwin systems?

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 #112079)

2024-10-19 Thread Robert O'Callahan via lldb-commits

rocallahan wrote:

> @rocallahan does rr work on Mac?

No, it doesn't. It does work on Linux AAarch64 though.

> This didn't work because we also build lldb-server on macOS.

Hmm, so lldb-server is built on macOS but we're not supposed to use it?

https://github.com/llvm/llvm-project/pull/112079
___
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 #112079)

2024-10-19 Thread Robert O'Callahan via lldb-commits

rocallahan wrote:

I'd like the tests to work on Mac. I'm getting some assistance and we'll report 
back in a few days.

https://github.com/llvm/llvm-project/pull/112079
___
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-10-10 Thread Robert O'Callahan via lldb-commits

rocallahan wrote:

> @rocallahan Let me know if you need me to merge this on your behalf.

Please do! 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-10-10 Thread Robert O'Callahan via lldb-commits

rocallahan wrote:

I don't know what your normal protocol is but maybe you should revert it while 
I debug the failure?

The last successful CI run in this PR was from September 25.

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 #112079)

2024-10-22 Thread Robert O'Callahan via lldb-commits

https://github.com/rocallahan updated 
https://github.com/llvm/llvm-project/pull/112079

>From bb96e6ddd2d6448be01b1965591cf8ee77e14569 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 |   1 +
 lldb/include/lldb/Target/Process.h|  23 +-
 lldb/include/lldb/Target/StopInfo.h   |   6 +
 lldb/include/lldb/lldb-enumerations.h |   6 +
 .../Python/lldbsuite/test/gdbclientutils.py   |   5 +-
 .../Python/lldbsuite/test/lldbgdbproxy.py | 178 +++
 .../Python/lldbsuite/test/lldbreverse.py  | 445 ++
 .../Python/lldbsuite/test/lldbtest.py |   2 +
 lldb/source/API/SBProcess.cpp |   8 +-
 lldb/source/API/SBThread.cpp  |   2 +
 .../source/Interpreter/CommandInterpreter.cpp |   3 +-
 .../Process/Linux/NativeThreadLinux.cpp   |   3 +
 .../Process/MacOSX-Kernel/ProcessKDP.cpp  |   9 +-
 .../Process/MacOSX-Kernel/ProcessKDP.h|   2 +-
 .../Process/Windows/Common/ProcessWindows.cpp |   9 +-
 .../Process/Windows/Common/ProcessWindows.h   |   2 +-
 .../GDBRemoteCommunicationClient.cpp  |  22 +
 .../gdb-remote/GDBRemoteCommunicationClient.h |   6 +
 .../GDBRemoteCommunicationServerLLGS.cpp  |   1 +
 .../Process/gdb-remote/ProcessGDBRemote.cpp   |  88 +++-
 .../Process/gdb-remote/ProcessGDBRemote.h |   2 +-
 .../Process/scripted/ScriptedProcess.cpp  |  10 +-
 .../Process/scripted/ScriptedProcess.h|   2 +-
 lldb/source/Target/Process.cpp|  38 +-
 lldb/source/Target/StopInfo.cpp   |  29 ++
 lldb/source/Target/Thread.cpp |   8 +-
 .../reverse-execution/Makefile|   3 +
 .../TestReverseContinueBreakpoints.py | 123 +
 .../TestReverseContinueNotSupported.py|  30 ++
 .../functionalities/reverse-execution/main.c  |  14 +
 lldb/tools/lldb-dap/JSONUtils.cpp |   3 +
 lldb/tools/lldb-dap/LLDBUtils.cpp |   1 +
 32 files changed, 1034 insertions(+), 50 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/TestReverseContinueNotSupported.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 1624e02070b1b2..8b8ed830b54cc0 100644
--- a/lldb/include/lldb/API/SBProcess.h
+++ b/lldb/include/lldb/API/SBProcess.h
@@ -159,6 +159,7 @@ class LLDB_API SBProcess {
   lldb::SBError Destroy();
 
   lldb::SBError Continue();
+  lldb::SBError Continue(RunDirection direction);
 
   lldb::SBError Stop();
 
diff --git a/lldb/include/lldb/Target/Process.h 
b/lldb/include/lldb/Target/Process.h
index b8c53a474ba6b9..6efeb0d3694a6a 100644
--- a/lldb/include/lldb/Target/Process.h
+++ b/lldb/include/lldb/Target/Process.h
@@ -857,10 +857,11 @@ 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.
   ///
@@ -1104,9 +1105,15 @@ class Process : public 
std::enable_shared_from_this,
   /// \see Thread:Resume()
   /// \see Thread:Step()
   /// \see Thread:Suspend()
-  virtual Status DoResume() {
-return Status::FromErrorStringWithFormatv(
-"error: {0} does not support resuming processes", GetPluginName());
+  virtual Status DoResume(lldb::RunDirection direction) {
+if (direction == lldb::RunDirection::eRunForward) {
+  return Status::FromErrorStringWithFormatv(
+  "error: {0} does not support resuming processes", GetPluginName());
+} else {
+  return Status::FromErrorStringWithFormatv(
+  "error: {0} does not support reverse execution of processes",
+  GetPluginName());
+}
   }
 
   

[Lldb-commits] [lldb] [lldb] Implement basic support for reverse-continue (PR #112079)

2024-10-11 Thread Robert O'Callahan via lldb-commits

https://github.com/rocallahan created 
https://github.com/llvm/llvm-project/pull/112079

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.

>From 6bd33589417195eafe945f2d2f57b01352f56568 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 |   1 +
 lldb/include/lldb/Target/Process.h|  21 +-
 lldb/include/lldb/Target/StopInfo.h   |   6 +
 lldb/include/lldb/lldb-enumerations.h |   6 +
 .../Python/lldbsuite/test/gdbclientutils.py   |   5 +-
 .../Python/lldbsuite/test/lldbgdbproxy.py | 175 
 .../Python/lldbsuite/test/lldbreverse.py  | 418 ++
 .../Python/lldbsuite/test/lldbtest.py |   2 +
 lldb/source/API/SBProcess.cpp |   8 +-
 lldb/source/API/SBThread.cpp  |   2 +
 .../source/Interpreter/CommandInterpreter.cpp |   3 +-
 .../Process/Linux/NativeThreadLinux.cpp   |   3 +
 .../Process/MacOSX-Kernel/ProcessKDP.cpp  |   9 +-
 .../Process/MacOSX-Kernel/ProcessKDP.h|   2 +-
 .../Process/Windows/Common/ProcessWindows.cpp |   8 +-
 .../Process/Windows/Common/ProcessWindows.h   |   2 +-
 .../GDBRemoteCommunicationClient.cpp  |  22 +
 .../gdb-remote/GDBRemoteCommunicationClient.h |   6 +
 .../GDBRemoteCommunicationServerLLGS.cpp  |   1 +
 .../Process/gdb-remote/ProcessGDBRemote.cpp   |  77 +++-
 .../Process/gdb-remote/ProcessGDBRemote.h |   2 +-
 .../Process/scripted/ScriptedProcess.cpp  |   9 +-
 .../Process/scripted/ScriptedProcess.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 | 115 +
 .../TestReverseContinueNotSupported.py|  30 ++
 .../functionalities/reverse-execution/main.c  |  14 +
 lldb/tools/lldb-dap/JSONUtils.cpp |   3 +
 lldb/tools/lldb-dap/LLDBUtils.cpp |   1 +
 32 files changed, 978 insertions(+), 44 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/TestReverseContinueNotSupported.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 1624e02070b1b2..8b8ed830b54cc0 100644
--- a/lldb/include/lldb/API/SBProcess.h
+++ b/lldb/include/lldb/API/SBProcess.h
@@ -159,6 +159,7 @@ class LLDB_API SBProcess {
   lldb::SBError Destroy();
 
   lldb::SBError Continue();
+  lldb::SBError Continue(RunDirection direction);
 
   lldb::SBError Stop();
 
diff --git a/lldb/include/lldb/Target/Process.h 
b/lldb/include/lldb/Target/Process.h
index b8c53a474ba6b9..fe7fbc50fd5770 100644
--- a/lldb/include/lldb/Target/Process.h
+++ b/lldb/include/lldb/Target/Process.h
@@ -857,10 +857,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.
   ///
@@ -1104,9 +1104,14 @@ class Process : public 
std::enable_shared_from_this,
   /// \see Thread:Resume()
   /// \see Thread:Step()
   /// \see Thread:Suspend()
-  virtual Status DoResume() {
-return Status::FromErrorStringWithFormatv(
-"error: {0} does not support resuming 

[Lldb-commits] [lldb] [lldb] Implement basic support for reverse-continue (PR #99736)

2024-10-11 Thread Robert O'Callahan via lldb-commits

rocallahan wrote:

I have created a new PR #112079 to continue work on this.
Is there a way to run the full post-merge CI test suite against a Github PR?

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 #112079)

2024-10-11 Thread Robert O'Callahan via lldb-commits

https://github.com/rocallahan edited 
https://github.com/llvm/llvm-project/pull/112079
___
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 #112079)

2024-10-11 Thread Robert O'Callahan via lldb-commits

https://github.com/rocallahan updated 
https://github.com/llvm/llvm-project/pull/112079

>From 9f33f8e5e0efb74772022c4ffadb65a6aefedf55 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 |   1 +
 lldb/include/lldb/Target/Process.h|  23 +-
 lldb/include/lldb/Target/StopInfo.h   |   6 +
 lldb/include/lldb/lldb-enumerations.h |   6 +
 .../Python/lldbsuite/test/gdbclientutils.py   |   5 +-
 .../Python/lldbsuite/test/lldbgdbproxy.py | 179 +++
 .../Python/lldbsuite/test/lldbreverse.py  | 444 ++
 .../Python/lldbsuite/test/lldbtest.py |   2 +
 lldb/source/API/SBProcess.cpp |   8 +-
 lldb/source/API/SBThread.cpp  |   2 +
 .../source/Interpreter/CommandInterpreter.cpp |   3 +-
 .../Process/Linux/NativeThreadLinux.cpp   |   3 +
 .../Process/MacOSX-Kernel/ProcessKDP.cpp  |  10 +-
 .../Process/MacOSX-Kernel/ProcessKDP.h|   2 +-
 .../Process/Windows/Common/ProcessWindows.cpp |   9 +-
 .../Process/Windows/Common/ProcessWindows.h   |   2 +-
 .../GDBRemoteCommunicationClient.cpp  |  22 +
 .../gdb-remote/GDBRemoteCommunicationClient.h |   6 +
 .../GDBRemoteCommunicationServerLLGS.cpp  |   1 +
 .../Process/gdb-remote/ProcessGDBRemote.cpp   |  88 +++-
 .../Process/gdb-remote/ProcessGDBRemote.h |   2 +-
 .../Process/scripted/ScriptedProcess.cpp  |  10 +-
 .../Process/scripted/ScriptedProcess.h|   2 +-
 lldb/source/Target/Process.cpp|  38 +-
 lldb/source/Target/StopInfo.cpp   |  29 ++
 lldb/source/Target/Thread.cpp |   8 +-
 .../reverse-execution/Makefile|   3 +
 .../TestReverseContinueBreakpoints.py | 123 +
 .../TestReverseContinueNotSupported.py|  30 ++
 .../functionalities/reverse-execution/main.c  |  14 +
 lldb/tools/lldb-dap/JSONUtils.cpp |   3 +
 lldb/tools/lldb-dap/LLDBUtils.cpp |   1 +
 32 files changed, 1035 insertions(+), 50 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/TestReverseContinueNotSupported.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 1624e02070b1b2..8b8ed830b54cc0 100644
--- a/lldb/include/lldb/API/SBProcess.h
+++ b/lldb/include/lldb/API/SBProcess.h
@@ -159,6 +159,7 @@ class LLDB_API SBProcess {
   lldb::SBError Destroy();
 
   lldb::SBError Continue();
+  lldb::SBError Continue(RunDirection direction);
 
   lldb::SBError Stop();
 
diff --git a/lldb/include/lldb/Target/Process.h 
b/lldb/include/lldb/Target/Process.h
index b8c53a474ba6b9..6efeb0d3694a6a 100644
--- a/lldb/include/lldb/Target/Process.h
+++ b/lldb/include/lldb/Target/Process.h
@@ -857,10 +857,11 @@ 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.
   ///
@@ -1104,9 +1105,15 @@ class Process : public 
std::enable_shared_from_this,
   /// \see Thread:Resume()
   /// \see Thread:Step()
   /// \see Thread:Suspend()
-  virtual Status DoResume() {
-return Status::FromErrorStringWithFormatv(
-"error: {0} does not support resuming processes", GetPluginName());
+  virtual Status DoResume(lldb::RunDirection direction) {
+if (direction == lldb::RunDirection::eRunForward) {
+  return Status::FromErrorStringWithFormatv(
+  "error: {0} does not support resuming processes", GetPluginName());
+} else {
+  return Status::FromErrorStringWithFormatv(
+  "error: {0} does not support reverse execution of processes",
+  GetPluginName());
+}
   }
 
   

[Lldb-commits] [lldb] [lldb] Implement basic support for reverse-continue (PR #112079)

2024-10-11 Thread Robert O'Callahan via lldb-commits

rocallahan wrote:

I adapted the code from here 
https://github.com/llvm/llvm-project/blob/a62768c427ec1f34d7c3823021a6c5a794709103/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py#L516
 into `lldbgdbproxy.py`:
```
+lldb_server_exe = lldbgdbserverutils.get_lldb_server_exe()
+if lldb_server_exe is None:
+self.debug_monitor_exe = lldbgdbserverutils.get_debugserver_exe()
+self.assertTrue(self.debug_monitor_exe is not None)
+self.debug_monitor_extra_args = []
+else:
+self.debug_monitor_exe = lldb_server_exe
+self.debug_monitor_extra_args = ["gdbserver"]
```
That's supposed to select `debugserver` when `lldb_server` is not available. I 
guess that isn't working. Should it work?

https://github.com/llvm/llvm-project/pull/112079
___
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 #112079)

2024-10-14 Thread Robert O'Callahan via lldb-commits

rocallahan wrote:

> I'd say that this is failing because macos generates slightly different 
> packet sequences, and the test is not expecting those.

Makes sense. But given Mac tests don't run against PRs, and I don't have a Mac, 
how am I supposed to debug this?

https://github.com/llvm/llvm-project/pull/112079
___
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 #112079)

2024-11-11 Thread Robert O'Callahan via lldb-commits

rocallahan wrote:

> My notion was that when you push a plan that has an intention to run in a 
> direction, if the plan above it on the stack was going in the opposite 
> direction, it has to be popped.

That's in the current code in this PR but I agree that was the wrong direction. 
My experimental 
[reverse-continue-thread-plan](https://github.com/rocallahan/llvm-project/tree/reverse-continue-thread-plan)
 branch doesn't do this.

> After all, you might be doing a backwards direction next, but hit a 
> breakpoint while doing that. You then want to step FORWARDS from that 
> breakpoint to check something out.

Right.

> Then if stepping backwards and forwards were working like lldb stepping 
> currently works, you'd expect "continue" to return control to the backwards 
> next to finish out the operation.

There's a UX issue here: in the scenario you describe (hit breakpoint during 
reverse-next, step forward, continue) *should* the reverse-step be resumed? 
Personally I think not. I think it's very confusing if "continue" ever causes 
reverse execution (and likewise if "reverse-continue" ever causes forward 
execution). So in this case I would say "reverse-continue" should resume the 
reverse-next but "continue" should pop it.

This is helpful discussion but it doesn't directly address my question in 
https://github.com/llvm/llvm-project/pull/112079#issuecomment-2468857787. Can 
we focus on that?

https://github.com/llvm/llvm-project/pull/112079
___
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 #112079)

2024-11-11 Thread Robert O'Callahan via lldb-commits

rocallahan wrote:

Giving ThreadPlans a direction gets complicated when there are multiple 
runnable threads, because the topmost plans for different runnable threads 
could disagree about the execution direction, which is obviously unworkable. In 
my experimental branch I linked above, I resolve this by defaulting to forward 
execution if there's a disagreement and popping reverse-execution plans from 
runnable threads until all the topmost plans agree on forward execution. But 
this means that reverse-continue has to push a `ThreadPlanReverseContinue` onto 
all threads' plan stacks. So when the reverse-continue is over we really need 
to pop those `ThreadPlanReverseContinue`s from all threads.

https://github.com/llvm/llvm-project/pull/112079
___
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 #112079)

2024-11-11 Thread Robert O'Callahan via lldb-commits

rocallahan wrote:

The approach I implemented fails when evaluating a breakpoint condition 
requires running a function in the target process, e.g. evaluating a breakpoint 
condition that's a function call, or calling `mmap()` to allocate memory for 
JITted code. That pushes a `ThreadPlanCallFunction` onto the plan stack and 
resumes the target in the forward direction. With my code as-is, switching 
directions discards all thread plans before resuming, so we discard the 
`ThreadPlanCallFunction` and everything breaks.

In this case we need the `ThreadPlanCallFunction` to complete normally and then 
when the breakpoint condition has finished evaluating to false, resume 
execution in the reverse direction. So it seems like we should use the thread 
plan stack --- associate a direction with each thread plan, so 
`ThreadPlanCallFunction` executes forward and completes, but after it has been 
popped, the thread plan below it will tell us to execute in reverse.

So I tried adding a virtual function `ThreadPlan::GetDirection()` and 
[introducing 
`ThreadPlanReverseContinue`](https://github.com/rocallahan/llvm-project/tree/reverse-continue-thread-plan)
 which executes in reverse. `SBProcess::ReverseContinue()` pushes a 
`ThreadPlanReverseContinue` onto the plan stack and resumes. There is big 
question about when/how this plan should be removed. In principle we should 
remove it when a stop is reported to the user. I tried making 
`ThreadPlanReverseContinue::MischiefManaged()` always return true. That doesn't 
work because it makes us pop the `ThreadPlanReverseContinue` before the 
breakpoint condition is even evaluated. So what would be a good way to pop 
`ThreadPlanReverseContinue`?

An alternative approach would be to store a "current direction" in 
`ThreadPlanBase` and have `SBProcess::Continue/ReverseContinue` both set it. 
But that is kind of scary because any execution command that doesn't go through 
`SBProcess::Continue/ReverseContinue` will resume in the last-used direction. 
But let me know if that sounds better.

@jimingham this all sounds like your territory.

https://github.com/llvm/llvm-project/pull/112079
___
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 #112079)

2024-11-11 Thread Robert O'Callahan via lldb-commits

rocallahan wrote:

Thanks, that sounds OK but I don't see how it would help with my main question 
right now:
> So what would be a good way to pop `ThreadPlanReverseContinue`?

Put it another way: if we change the plan stack state to request reverse 
execution (push a `ThreadPlanReverseContinue`, or change some state on 
`ThreadPlanBase`), when/how would be the right place in the code to undo that 
change? It has to happen before any user-initiated forward-execution command 
resumes the target, but it must not happen when we stop for a breakpoint whose 
condition turns out to be false.

https://github.com/llvm/llvm-project/pull/112079
___
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 #112079)

2024-11-12 Thread Robert O'Callahan via lldb-commits

rocallahan wrote:

> I worry that in a situation like this where there's a pending task people 
> will go the wrong way and lose important state because they forgot that 
> "continue" doesn't mean "continue what I was doing" - which is what it 
> currently means in lldb

I don't know of any other debugger that supports the equivalent of a thread 
plan stack, and even though I've been neck-deep in debuggers for a long time I 
didn't know about this LLDB feature until I started working on this PR, so TBH 
I think most users will assume "continue" works like any other debugger and 
just resumes execution forwards, and are surprised (hopefully in a good way) 
if/when they discover it's more complicated than that. And therefore will be 
surprised in a bad way if/when they discover that "continue" runs backwards in 
some situations.

> I think ultimately I'm arguing against requiring: "we either have all forward 
> or all backwards plans on any given thread plan stack" because I don't think 
> that is flexible enough to support all the use cases we want to support.

I agree and as I said above, I've already removed that requirement in my 
experimental branch. I haven't added a notion of "no-direction-opinion" plans 
yet, but most of what you said above makes sense even if we don't have that.

Let's consider a really simple case where the user does a reverse-continue, 
hits an unconditional breakpoint, and then wants to execute forwards. One 
question is, what command should they use to execute forwards? I've been 
assuming that they would just use `process continue`, but if you really want 
`process continue` to resume the reverse-continue and we should have a separate 
command or flag to switch to forwards, we can do that. We should probably 
settle this now because it's quite fundamental.

The other question is, what should the thread plan stacks look like during this 
scenario?

https://github.com/llvm/llvm-project/pull/112079
___
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-09-21 Thread Robert O'Callahan via lldb-commits

rocallahan wrote:

@clayborg @jimingham Can I please have some love? I don't want to keep telling 
users "you should be using GDB" and I've done a significant amount of work here.

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-09-24 Thread Robert O'Callahan via lldb-commits


@@ -142,6 +142,9 @@ class StopInfo : public 
std::enable_shared_from_this {
   static lldb::StopInfoSP
   CreateStopReasonProcessorTrace(Thread &thread, const char *description);
 
+  static lldb::StopInfoSP

rocallahan wrote:

Adding a 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-09-24 Thread Robert O'Callahan via lldb-commits


@@ -510,8 +510,9 @@ def start(self):
 self._thread.start()
 
 def stop(self):
-self._thread.join()
-self._thread = None
+if self._thread is not None:

rocallahan wrote:

This is not an LLDB stop or an LLDB thread. `thread_`  is the `MockGdbServer`'s 
Python worker thread, and `stop()` is the method you call to shut down the 
server. I'm making this method work in the case where you call `stop()` before 
`start()` has been called, in the `GDBProxyTestBase.tearDown()` test 
scaffolding.

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-09-24 Thread Robert O'Callahan via lldb-commits


@@ -3271,6 +3273,11 @@ Status Process::PrivateResume() {
   if (!GetModID().IsLastResumeForUserExpression())
 ResetExtendedCrashInfoDict();
 
+  if (m_last_run_direction != direction) {

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-09-24 Thread Robert O'Callahan via lldb-commits

https://github.com/rocallahan edited 
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-09-24 Thread Robert O'Callahan via lldb-commits

https://github.com/rocallahan edited 
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-09-24 Thread Robert O'Callahan via lldb-commits

rocallahan wrote:

> Ack, sorry I'm bad at the formalities.

No problem. Thank you for your time.

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-09-24 Thread Robert O'Callahan via lldb-commits


@@ -158,7 +158,7 @@ class LLDB_API SBProcess {
 
   lldb::SBError Destroy();
 
-  lldb::SBError Continue();
+  lldb::SBError Continue(RunDirection direction = RunDirection::eRunForward);

rocallahan wrote:

I have made this change.

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-09-24 Thread Robert O'Callahan via lldb-commits


@@ -203,11 +203,17 @@ ProcessWindows::DoAttachToProcessWithID(lldb::pid_t pid,
   return error;
 }
 
-Status ProcessWindows::DoResume() {
+Status ProcessWindows::DoResume(RunDirection direction) {
   Log *log = GetLog(WindowsLog::Process);
   llvm::sys::ScopedLock lock(m_mutex);
   Status error;
 
+  if (direction == RunDirection::eRunReverse) {

rocallahan wrote:

The decision was to use a direction flag.

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-09-24 Thread Robert O'Callahan via lldb-commits


@@ -3139,6 +3146,7 @@ void PruneThreadPlans();
// m_currently_handling_do_on_removals are true,
// Resume will only request a resume, using this
// flag to check.
+  lldb::RunDirection m_last_run_direction;

rocallahan wrote:

Jim indicated that he doesn't want it initialized inline here.

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-09-24 Thread Robert O'Callahan via lldb-commits


@@ -402,9 +402,16 @@ lldb_private::DynamicLoader 
*ProcessKDP::GetDynamicLoader() {
 
 Status ProcessKDP::WillResume() { return Status(); }
 
-Status ProcessKDP::DoResume() {
+Status ProcessKDP::DoResume(RunDirection direction) {

rocallahan wrote:

The decision was to use a direction flag.

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-09-24 Thread Robert O'Callahan via lldb-commits

https://github.com/rocallahan edited 
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-09-24 Thread Robert O'Callahan via lldb-commits


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

rocallahan wrote:

The decision was to use a direction flag.

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-09-24 Thread Robert O'Callahan via lldb-commits


@@ -52,7 +52,7 @@ class ProcessWindows : public Process, public ProcessDebugger 
{
   Status DoAttachToProcessWithID(
   lldb::pid_t pid,
   const lldb_private::ProcessAttachInfo &attach_info) override;
-  Status DoResume() override;
+  Status DoResume(lldb::RunDirection direction) override;

rocallahan wrote:

The decision was to use a direction flag.

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-09-24 Thread Robert O'Callahan via lldb-commits


@@ -52,7 +52,7 @@ class ScriptedProcess : public Process {
 
   void DidResume() override;
 
-  Status DoResume() override;
+  Status DoResume(lldb::RunDirection direction) override;

rocallahan wrote:

The decision was to use a direction flag.

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-09-24 Thread Robert O'Callahan via lldb-commits


@@ -90,7 +90,7 @@ class ProcessKDP : public lldb_private::Process {
   // Process Control
   lldb_private::Status WillResume() override;
 
-  lldb_private::Status DoResume() override;
+  lldb_private::Status DoResume(lldb::RunDirection direction) override;

rocallahan wrote:

The decision was to use a direction flag.

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-09-24 Thread Robert O'Callahan via lldb-commits


@@ -111,7 +111,7 @@ class ProcessGDBRemote : public Process,
   // Process Control
   Status WillResume() override;
 
-  Status DoResume() override;
+  Status DoResume(lldb::RunDirection direction) override;

rocallahan wrote:

The decision was to use a direction flag.

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-09-24 Thread Robert O'Callahan via lldb-commits


@@ -182,10 +182,17 @@ void ScriptedProcess::DidResume() {
   m_pid = GetInterface().GetProcessID();
 }
 
-Status ScriptedProcess::DoResume() {
+Status ScriptedProcess::DoResume(RunDirection direction) {

rocallahan wrote:

The decision was to use a direction flag.

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-09-24 Thread Robert O'Callahan via lldb-commits


@@ -3169,6 +3176,7 @@ void PruneThreadPlans();
// m_currently_handling_do_on_removals are true,
// Resume will only request a resume, using this
// flag to check.
+  lldb::RunDirection m_last_run_direction;

rocallahan wrote:

Ah I see. @clayborg suggested I initialize `m_last_run_direction` inline but 
fortunately I never got around to doing that :-).

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-09-24 Thread Robert O'Callahan via lldb-commits


@@ -1129,10 +1129,15 @@ class Process : public 
std::enable_shared_from_this,
   /// \see Thread:Resume()
   /// \see Thread:Step()
   /// \see Thread:Suspend()
-  virtual Status DoResume() {
+  virtual Status DoResume(lldb::RunDirection direction) {

rocallahan wrote:

The decision was to use a direction flag.

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-09-24 Thread Robert O'Callahan via lldb-commits


@@ -203,11 +203,17 @@ ProcessWindows::DoAttachToProcessWithID(lldb::pid_t pid,
   return error;
 }
 
-Status ProcessWindows::DoResume() {
+Status ProcessWindows::DoResume(RunDirection direction) {

rocallahan wrote:

The decision was to use a direction flag.

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-09-24 Thread Robert O'Callahan via lldb-commits


@@ -3169,6 +3176,7 @@ void PruneThreadPlans();
// m_currently_handling_do_on_removals are true,
// Resume will only request a resume, using this
// flag to check.
+  lldb::RunDirection m_last_run_direction;

rocallahan wrote:

> This should have a doc string. 

OK, will do.

> So I personally wouldn't initialize this one here,

Maybe I'm misunderstanding you, but I'm not initializing `m_last_run_direction` 
here.

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-09-24 Thread Robert O'Callahan via lldb-commits

https://github.com/rocallahan updated 
https://github.com/llvm/llvm-project/pull/99736

>From 4bc3e8453a2fffa7c444ed9aa4bdc51e8e54569f 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 |   1 +
 lldb/include/lldb/Target/Process.h|  21 +-
 lldb/include/lldb/Target/StopInfo.h   |   6 +
 lldb/include/lldb/lldb-enumerations.h |   6 +
 .../Python/lldbsuite/test/gdbclientutils.py   |   5 +-
 .../Python/lldbsuite/test/lldbgdbproxy.py | 175 
 .../Python/lldbsuite/test/lldbreverse.py  | 418 ++
 .../Python/lldbsuite/test/lldbtest.py |   2 +
 lldb/source/API/SBProcess.cpp |   8 +-
 lldb/source/API/SBThread.cpp  |   2 +
 .../source/Interpreter/CommandInterpreter.cpp |   3 +-
 .../Process/Linux/NativeThreadLinux.cpp   |   3 +
 .../Process/MacOSX-Kernel/ProcessKDP.cpp  |   9 +-
 .../Process/MacOSX-Kernel/ProcessKDP.h|   2 +-
 .../Process/Windows/Common/ProcessWindows.cpp |   8 +-
 .../Process/Windows/Common/ProcessWindows.h   |   2 +-
 .../GDBRemoteCommunicationClient.cpp  |  22 +
 .../gdb-remote/GDBRemoteCommunicationClient.h |   6 +
 .../GDBRemoteCommunicationServerLLGS.cpp  |   1 +
 .../Process/gdb-remote/ProcessGDBRemote.cpp   |  77 +++-
 .../Process/gdb-remote/ProcessGDBRemote.h |   2 +-
 .../Process/scripted/ScriptedProcess.cpp  |   9 +-
 .../Process/scripted/ScriptedProcess.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 | 115 +
 .../TestReverseContinueNotSupported.py|  30 ++
 .../functionalities/reverse-execution/main.c  |  14 +
 lldb/tools/lldb-dap/JSONUtils.cpp |   3 +
 lldb/tools/lldb-dap/LLDBUtils.cpp |   1 +
 32 files changed, 978 insertions(+), 44 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/TestReverseContinueNotSupported.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 1624e02070b1b2..8b8ed830b54cc0 100644
--- a/lldb/include/lldb/API/SBProcess.h
+++ b/lldb/include/lldb/API/SBProcess.h
@@ -159,6 +159,7 @@ class LLDB_API SBProcess {
   lldb::SBError Destroy();
 
   lldb::SBError Continue();
+  lldb::SBError Continue(RunDirection direction);
 
   lldb::SBError Stop();
 
diff --git a/lldb/include/lldb/Target/Process.h 
b/lldb/include/lldb/Target/Process.h
index b8c53a474ba6b9..fe7fbc50fd5770 100644
--- a/lldb/include/lldb/Target/Process.h
+++ b/lldb/include/lldb/Target/Process.h
@@ -857,10 +857,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.
   ///
@@ -1104,9 +1104,14 @@ class Process : public 
std::enable_shared_from_this,
   /// \see Thread:Resume()
   /// \see Thread:Step()
   /// \see Thread:Suspend()
-  virtual Status DoResume() {
-return Status::FromErrorStringWithFormatv(
-"error: {0} does not support resuming processes", GetPluginName());
+  virtual Status DoResume(lldb::RunDirection direction) {
+if (direction == lldb::RunDirection::eRunForward) {
+  return Status::FromErrorStringWithFormatv(
+  "error: {0} does not support resuming processes", GetPluginName());
+} else {
+  return Status::FromErrorStringWithFormatv(
+  "error: {0} does not support reverse execution of processes", 
GetPluginName());
+}
   }
 
   /// Called after resuming a process.
@

[Lldb-commits] [lldb] [lldb] Implement basic support for reverse-continue (PR #99736)

2024-09-24 Thread Robert O'Callahan via lldb-commits

rocallahan wrote:

I see @clayborg still has a "change requested" hold on this PR. As far as I can 
tell all his comments have been addressed.

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] Unify/improve MainLoop signal handling (PR #115197)

2024-11-14 Thread Robert O'Callahan via lldb-commits

rocallahan wrote:

In any case I am OOO and mostly offline until Nov 26.

Rob


https://github.com/llvm/llvm-project/pull/115197
___
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 #112079)

2024-11-26 Thread Robert O'Callahan via lldb-commits

https://github.com/rocallahan updated 
https://github.com/llvm/llvm-project/pull/112079

>From 6d8f3ccf7b30334853e07e141f41545d68870bb8 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::ContinueInDirection()` 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.
with a Python implementation of *very limited* record-and-replay
functionality.
---
 lldb/include/lldb/API/SBProcess.h |   1 +
 lldb/include/lldb/Target/Process.h|  18 +-
 lldb/include/lldb/Target/StopInfo.h   |   7 +
 lldb/include/lldb/Target/Thread.h |  12 +-
 lldb/include/lldb/Target/ThreadList.h |   6 +-
 lldb/include/lldb/Target/ThreadPlan.h |   2 +
 lldb/include/lldb/Target/ThreadPlanBase.h |   2 +
 lldb/include/lldb/lldb-enumerations.h |   6 +
 .../Python/lldbsuite/test/gdbclientutils.py   |   5 +-
 .../Python/lldbsuite/test/lldbgdbproxy.py | 184 +++
 .../Python/lldbsuite/test/lldbreverse.py  | 480 ++
 .../Python/lldbsuite/test/lldbtest.py |   2 +
 .../tools/lldb-server/lldbgdbserverutils.py   |  15 +-
 lldb/source/API/SBProcess.cpp |   8 +
 lldb/source/API/SBThread.cpp  |   2 +
 .../source/Interpreter/CommandInterpreter.cpp |   3 +-
 .../Process/Linux/NativeThreadLinux.cpp   |   3 +
 .../Process/MacOSX-Kernel/ProcessKDP.cpp  |   9 +-
 .../Process/MacOSX-Kernel/ProcessKDP.h|   2 +-
 .../Process/Windows/Common/ProcessWindows.cpp |   9 +-
 .../Process/Windows/Common/ProcessWindows.h   |   2 +-
 .../GDBRemoteCommunicationClient.cpp  |  22 +
 .../gdb-remote/GDBRemoteCommunicationClient.h |   6 +
 .../GDBRemoteCommunicationServerLLGS.cpp  |   1 +
 .../Process/gdb-remote/ProcessGDBRemote.cpp   |  88 +++-
 .../Process/gdb-remote/ProcessGDBRemote.h |   2 +-
 .../Process/scripted/ScriptedProcess.cpp  |  10 +-
 .../Process/scripted/ScriptedProcess.h|   2 +-
 lldb/source/Target/Process.cpp|  33 +-
 lldb/source/Target/StopInfo.cpp   |  29 ++
 lldb/source/Target/Thread.cpp |  13 +-
 lldb/source/Target/ThreadList.cpp |  62 ++-
 lldb/source/Target/ThreadPlanBase.cpp |   4 +
 .../reverse-execution/Makefile|   3 +
 .../TestReverseContinueBreakpoints.py | 151 ++
 .../TestReverseContinueNotSupported.py|  30 ++
 .../functionalities/reverse-execution/main.c  |  14 +
 lldb/tools/lldb-dap/JSONUtils.cpp |   3 +
 lldb/tools/lldb-dap/LLDBUtils.cpp |   1 +
 39 files changed, 1176 insertions(+), 76 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/TestReverseContinueNotSupported.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 1624e02070b1b2..882b8bd837131d 100644
--- a/lldb/include/lldb/API/SBProcess.h
+++ b/lldb/include/lldb/API/SBProcess.h
@@ -159,6 +159,7 @@ class LLDB_API SBProcess {
   lldb::SBError Destroy();
 
   lldb::SBError Continue();
+  lldb::SBError ContinueInDirection(lldb::RunDirection direction);
 
   lldb::SBError Stop();
 
diff --git a/lldb/include/lldb/Target/Process.h 
b/lldb/include/lldb/Target/Process.h
index b8c53a474ba6b9..7b8ec7ae39f2b7 100644
--- a/lldb/include/lldb/Target/Process.h
+++ b/lldb/include/lldb/Target/Process.h
@@ -1104,9 +1104,15 @@ class Process : public 
std::enable_shared_from_this,
   /// \see Thread:Resume()
   /// \see Thread:Step()
   /// \see Thread:Suspend()
-  virtual Status DoResume() {
-return Status::FromErrorStringWithFormatv(
-"error: {0} does not support resuming processes", GetPluginName());
+  virtual Status DoResume(lldb::RunDirection direction) {
+if (direction == lldb::RunDirection::eRunForward) {
+  return Status::FromErrorStringWithFormatv(
+  "error: {0} does not support resuming processes", GetPluginName());
+} else {
+  return Status::FromErrorStringWithFormatv(
+  "error: {0} does not support reverse execution of processes",
+  GetPluginName());
+}
   }
 
   /// Called after resuming a process.
@@ -2674,6 +2680,11 @@ void PruneThreadPlans();
 const AddressRange &range, size_t alignment,
 

[Lldb-commits] [lldb] [lldb] Implement basic support for reverse-continue (PR #112079)

2024-11-26 Thread Robert O'Callahan via lldb-commits

https://github.com/rocallahan updated 
https://github.com/llvm/llvm-project/pull/112079

>From 91d40f5e331b97a202208c221ef6b11784dc8ca2 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::ContinueInDirection()` 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.
with a Python implementation of *very limited* record-and-replay
functionality.
---
 lldb/include/lldb/API/SBProcess.h |   1 +
 lldb/include/lldb/Target/Process.h|  16 +-
 lldb/include/lldb/Target/StopInfo.h   |   7 +
 lldb/include/lldb/Target/Thread.h |  12 +-
 lldb/include/lldb/Target/ThreadList.h |   6 +-
 lldb/include/lldb/Target/ThreadPlan.h |   4 +
 lldb/include/lldb/Target/ThreadPlanBase.h |   2 +
 lldb/include/lldb/lldb-enumerations.h |   6 +
 .../Python/lldbsuite/test/gdbclientutils.py   |   5 +-
 .../Python/lldbsuite/test/lldbgdbproxy.py | 184 +++
 .../Python/lldbsuite/test/lldbreverse.py  | 480 ++
 .../Python/lldbsuite/test/lldbtest.py |   2 +
 .../tools/lldb-server/lldbgdbserverutils.py   |  15 +-
 lldb/source/API/SBProcess.cpp |   8 +
 lldb/source/API/SBThread.cpp  |   2 +
 .../source/Interpreter/CommandInterpreter.cpp |   3 +-
 .../Process/Linux/NativeThreadLinux.cpp   |   3 +
 .../Process/MacOSX-Kernel/ProcessKDP.cpp  |   9 +-
 .../Process/MacOSX-Kernel/ProcessKDP.h|   2 +-
 .../Process/Windows/Common/ProcessWindows.cpp |   9 +-
 .../Process/Windows/Common/ProcessWindows.h   |   2 +-
 .../GDBRemoteCommunicationClient.cpp  |  22 +
 .../gdb-remote/GDBRemoteCommunicationClient.h |   6 +
 .../GDBRemoteCommunicationServerLLGS.cpp  |   1 +
 .../Process/gdb-remote/ProcessGDBRemote.cpp   |  88 +++-
 .../Process/gdb-remote/ProcessGDBRemote.h |   2 +-
 .../Process/scripted/ScriptedProcess.cpp  |  10 +-
 .../Process/scripted/ScriptedProcess.h|   2 +-
 lldb/source/Target/Process.cpp|  25 +-
 lldb/source/Target/StopInfo.cpp   |  29 ++
 lldb/source/Target/Thread.cpp |  13 +-
 lldb/source/Target/ThreadList.cpp |  62 ++-
 lldb/source/Target/ThreadPlanBase.cpp |   4 +
 .../reverse-execution/Makefile|   3 +
 .../TestReverseContinueBreakpoints.py | 151 ++
 .../TestReverseContinueNotSupported.py|  30 ++
 .../functionalities/reverse-execution/main.c  |  14 +
 lldb/tools/lldb-dap/JSONUtils.cpp |   3 +
 lldb/tools/lldb-dap/LLDBUtils.cpp |   1 +
 39 files changed, 1173 insertions(+), 71 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/TestReverseContinueNotSupported.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 1624e02070b1b2..882b8bd837131d 100644
--- a/lldb/include/lldb/API/SBProcess.h
+++ b/lldb/include/lldb/API/SBProcess.h
@@ -159,6 +159,7 @@ class LLDB_API SBProcess {
   lldb::SBError Destroy();
 
   lldb::SBError Continue();
+  lldb::SBError ContinueInDirection(lldb::RunDirection direction);
 
   lldb::SBError Stop();
 
diff --git a/lldb/include/lldb/Target/Process.h 
b/lldb/include/lldb/Target/Process.h
index b8c53a474ba6b9..80663d6b1fddcb 100644
--- a/lldb/include/lldb/Target/Process.h
+++ b/lldb/include/lldb/Target/Process.h
@@ -1104,9 +1104,15 @@ class Process : public 
std::enable_shared_from_this,
   /// \see Thread:Resume()
   /// \see Thread:Step()
   /// \see Thread:Suspend()
-  virtual Status DoResume() {
-return Status::FromErrorStringWithFormatv(
-"error: {0} does not support resuming processes", GetPluginName());
+  virtual Status DoResume(lldb::RunDirection direction) {
+if (direction == lldb::RunDirection::eRunForward) {
+  return Status::FromErrorStringWithFormatv(
+  "error: {0} does not support resuming processes", GetPluginName());
+} else {
+  return Status::FromErrorStringWithFormatv(
+  "error: {0} does not support reverse execution of processes",
+  GetPluginName());
+}
   }
 
   /// Called after resuming a process.
@@ -2674,6 +2680,9 @@ void PruneThreadPlans();
 const AddressRange &range, size_t alignment,
  

[Lldb-commits] [lldb] [lldb] Implement basic support for reverse-continue (PR #112079)

2024-11-26 Thread Robert O'Callahan via lldb-commits

https://github.com/rocallahan updated 
https://github.com/llvm/llvm-project/pull/112079

>From c0904fed59e42d957e2b40698c4343fdb5582b21 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::ContinueInDirection()` 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.
with a Python implementation of *very limited* record-and-replay
functionality.
---
 lldb/include/lldb/API/SBProcess.h |   1 +
 lldb/include/lldb/Target/Process.h|  16 +-
 lldb/include/lldb/Target/StopInfo.h   |   7 +
 lldb/include/lldb/Target/Thread.h |  12 +-
 lldb/include/lldb/Target/ThreadList.h |   6 +-
 lldb/include/lldb/Target/ThreadPlan.h |   4 +
 lldb/include/lldb/Target/ThreadPlanBase.h |   2 +
 lldb/include/lldb/lldb-enumerations.h |   6 +
 .../Python/lldbsuite/test/gdbclientutils.py   |   5 +-
 .../Python/lldbsuite/test/lldbgdbproxy.py | 185 +++
 .../Python/lldbsuite/test/lldbreverse.py  | 489 ++
 .../Python/lldbsuite/test/lldbtest.py |   2 +
 .../tools/lldb-server/lldbgdbserverutils.py   |  15 +-
 lldb/source/API/SBProcess.cpp |   8 +
 lldb/source/API/SBThread.cpp  |   2 +
 .../source/Interpreter/CommandInterpreter.cpp |   3 +-
 .../Process/Linux/NativeThreadLinux.cpp   |   3 +
 .../Process/MacOSX-Kernel/ProcessKDP.cpp  |   9 +-
 .../Process/MacOSX-Kernel/ProcessKDP.h|   2 +-
 .../Process/Windows/Common/ProcessWindows.cpp |   9 +-
 .../Process/Windows/Common/ProcessWindows.h   |   2 +-
 .../GDBRemoteCommunicationClient.cpp  |  22 +
 .../gdb-remote/GDBRemoteCommunicationClient.h |   6 +
 .../GDBRemoteCommunicationServerLLGS.cpp  |   1 +
 .../Process/gdb-remote/ProcessGDBRemote.cpp   |  88 +++-
 .../Process/gdb-remote/ProcessGDBRemote.h |   2 +-
 .../Process/scripted/ScriptedProcess.cpp  |  10 +-
 .../Process/scripted/ScriptedProcess.h|   2 +-
 lldb/source/Target/Process.cpp|  25 +-
 lldb/source/Target/StopInfo.cpp   |  29 ++
 lldb/source/Target/Thread.cpp |  13 +-
 lldb/source/Target/ThreadList.cpp |  62 ++-
 lldb/source/Target/ThreadPlanBase.cpp |   4 +
 .../reverse-execution/Makefile|   3 +
 .../TestReverseContinueBreakpoints.py | 151 ++
 .../TestReverseContinueNotSupported.py|  30 ++
 .../functionalities/reverse-execution/main.c  |  14 +
 lldb/tools/lldb-dap/JSONUtils.cpp |   3 +
 lldb/tools/lldb-dap/LLDBUtils.cpp |   1 +
 39 files changed, 1183 insertions(+), 71 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/TestReverseContinueNotSupported.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 1624e02070b1b2..882b8bd837131d 100644
--- a/lldb/include/lldb/API/SBProcess.h
+++ b/lldb/include/lldb/API/SBProcess.h
@@ -159,6 +159,7 @@ class LLDB_API SBProcess {
   lldb::SBError Destroy();
 
   lldb::SBError Continue();
+  lldb::SBError ContinueInDirection(lldb::RunDirection direction);
 
   lldb::SBError Stop();
 
diff --git a/lldb/include/lldb/Target/Process.h 
b/lldb/include/lldb/Target/Process.h
index b8c53a474ba6b9..80663d6b1fddcb 100644
--- a/lldb/include/lldb/Target/Process.h
+++ b/lldb/include/lldb/Target/Process.h
@@ -1104,9 +1104,15 @@ class Process : public 
std::enable_shared_from_this,
   /// \see Thread:Resume()
   /// \see Thread:Step()
   /// \see Thread:Suspend()
-  virtual Status DoResume() {
-return Status::FromErrorStringWithFormatv(
-"error: {0} does not support resuming processes", GetPluginName());
+  virtual Status DoResume(lldb::RunDirection direction) {
+if (direction == lldb::RunDirection::eRunForward) {
+  return Status::FromErrorStringWithFormatv(
+  "error: {0} does not support resuming processes", GetPluginName());
+} else {
+  return Status::FromErrorStringWithFormatv(
+  "error: {0} does not support reverse execution of processes",
+  GetPluginName());
+}
   }
 
   /// Called after resuming a process.
@@ -2674,6 +2680,9 @@ void PruneThreadPlans();
 const AddressRange &range, size_t alignment,
  

[Lldb-commits] [lldb] [lldb] Implement basic support for reverse-continue (PR #112079)

2024-11-14 Thread Robert O'Callahan via lldb-commits

rocallahan wrote:

Ok, tell me what you think of this proposal:

1) Each thread plan has a virtual `GetDirection()` method returning 
`RunDirection`. Existing plans other than `ThreadBasePlan` return `eRunForward`.
2) There is a per-process `base direction` flag. 
`ThreadBasePlan::GetDirection()` returns the value of that flag. Defaults to 
`eRunForward`.
3) There is a new `SBProcess::ContinueInDirection(direction)` method. This 
method updates the "process base direction" flag. For simplicity, for now, _if 
the base direction changed_, pop all plans on all threads.
4) `SBProcess::Continue()` is unchanged, i.e. preserves the base direction.
5) When we resume execution:
5a) If we choose to resume a single runnable thread whose current plan has 
`StopOthers()` , just resume using that plan's direction.
5b) Otherwise use the process base direction, and before resuming, pop plans 
until all threads' current plans match that direction.

I think this is fairly simple while behaving much like what you suggest. It 
doesn't require introducing a new kind of `ThreadPlan` which is good. I think 
it can extend cleanly to support reverse-step etc.

https://github.com/llvm/llvm-project/pull/112079
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] Reland "[lldb] Implement basic support for reverse-continue" (#123906)" (PR #123945)

2025-02-07 Thread Robert O'Callahan via lldb-commits

rocallahan wrote:

@adrian-prantl can we have that help please?
Also, is that link supposed to be accessible to the public? Because it's 404 
for me.

https://github.com/llvm/llvm-project/pull/123945
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Add support for gdb-style 'x' packet (PR #124733)

2025-01-30 Thread Robert O'Callahan via lldb-commits

rocallahan wrote:

It sounds fine. rr HEAD uses the Gdb flavour for GDB and the old-LLDB flavor 
for LLDB. After a decent amount of time has passed I will update to the new 
regime.

https://github.com/llvm/llvm-project/pull/124733
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Add support for gdb-style 'x' packet (PR #124733)

2025-01-30 Thread Robert O'Callahan via lldb-commits

rocallahan wrote:

And thanks!

https://github.com/llvm/llvm-project/pull/124733
___
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 #112079)

2024-12-17 Thread Robert O'Callahan via lldb-commits

https://github.com/rocallahan updated 
https://github.com/llvm/llvm-project/pull/112079

>From b021a56268c74010eae017d2d1169ab8b79978b3 Mon Sep 17 00:00:00 2001
From: Robert O'Callahan 
Date: Tue, 17 Dec 2024 23:40:34 +
Subject: [PATCH 1/9] [lldb] Move thread-notification setup to happen later

This lets us check `run_me_only_list.GetSize()` instead of `wants_solo_run`.
---
 lldb/source/Target/ThreadList.cpp | 28 ++--
 1 file changed, 14 insertions(+), 14 deletions(-)

diff --git a/lldb/source/Target/ThreadList.cpp 
b/lldb/source/Target/ThreadList.cpp
index 1a2d7dd61c778f..b44e53e0673b47 100644
--- a/lldb/source/Target/ThreadList.cpp
+++ b/lldb/source/Target/ThreadList.cpp
@@ -540,20 +540,6 @@ bool ThreadList::WillResume() {
 }
   }
 
-  if (wants_solo_run) {
-Log *log = GetLog(LLDBLog::Step);
-if (log && log->GetVerbose())
-  LLDB_LOGF(log, "Turning on notification of new threads while single "
- "stepping a thread.");
-m_process.StartNoticingNewThreads();
-  } else {
-Log *log = GetLog(LLDBLog::Step);
-if (log && log->GetVerbose())
-  LLDB_LOGF(log, "Turning off notification of new threads while single "
- "stepping a thread.");
-m_process.StopNoticingNewThreads();
-  }
-
   // Give all the threads that are likely to run a last chance to set up their
   // state before we negotiate who is actually going to get a chance to run...
   // Don't set to resume suspended threads, and if any thread wanted to stop
@@ -607,6 +593,20 @@ bool ThreadList::WillResume() {
 }
   }
 
+  if (run_me_only_list.GetSize(false) == 0) {
+Log *log = GetLog(LLDBLog::Step);
+if (log && log->GetVerbose())
+  LLDB_LOGF(log, "Turning on notification of new threads while single "
+ "stepping a thread.");
+m_process.StartNoticingNewThreads();
+  } else {
+Log *log = GetLog(LLDBLog::Step);
+if (log && log->GetVerbose())
+  LLDB_LOGF(log, "Turning off notification of new threads while single "
+ "stepping a thread.");
+m_process.StopNoticingNewThreads();
+  }
+
   bool need_to_resume = true;
 
   if (run_me_only_list.GetSize(false) == 0) {

>From 5164b418ea8e606729b24d0705f70e040aed8757 Mon Sep 17 00:00:00 2001
From: Robert O'Callahan 
Date: Tue, 17 Dec 2024 23:46:01 +
Subject: [PATCH 2/9] [lldb] Make `Thread::WillResume()` report whether it
 pushed a `ThreadPlanStepOverBreakpoint`

We'll need this later to determine whether we need to account for
the newly-pushed `ThreadPlanStepOverBreakpoint`.
---
 lldb/include/lldb/Target/Thread.h | 13 -
 lldb/source/Target/Thread.cpp |  6 --
 2 files changed, 12 insertions(+), 7 deletions(-)

diff --git a/lldb/include/lldb/Target/Thread.h 
b/lldb/include/lldb/Target/Thread.h
index 38b65b2bc58490..ef66fa11574db9 100644
--- a/lldb/include/lldb/Target/Thread.h
+++ b/lldb/include/lldb/Target/Thread.h
@@ -200,11 +200,14 @@ class Thread : public 
std::enable_shared_from_this,
   ///The User resume state for this thread.
   lldb::StateType GetResumeState() const { return m_resume_state; }
 
-  // This function is called on all the threads before "ShouldResume" and
-  // "WillResume" in case a thread needs to change its state before the
-  // ThreadList polls all the threads to figure out which ones actually will
-  // get to run and how.
-  void SetupForResume();
+  /// This function is called on all the threads before "ShouldResume" and
+  /// "WillResume" in case a thread needs to change its state before the
+  /// ThreadList polls all the threads to figure out which ones actually will
+  /// get to run and how.
+  ///
+  /// \return
+  ///True if we pushed a ThreadPlanStepOverBreakpoint
+  bool SetupForResume();
 
   // Do not override this function, it is for thread plan logic only
   bool ShouldResume(lldb::StateType resume_state);
diff --git a/lldb/source/Target/Thread.cpp b/lldb/source/Target/Thread.cpp
index a6130f6b925bbf..b5261310970611 100644
--- a/lldb/source/Target/Thread.cpp
+++ b/lldb/source/Target/Thread.cpp
@@ -617,7 +617,7 @@ void Thread::WillStop() {
   current_plan->WillStop();
 }
 
-void Thread::SetupForResume() {
+bool Thread::SetupForResume() {
   if (GetResumeState() != eStateSuspended) {
 // First check whether this thread is going to "actually" resume at all.
 // For instance, if we're stepping from one level to the next of an
@@ -625,7 +625,7 @@ void Thread::SetupForResume() {
 // without actually running this thread.  In that case, for this thread we
 // shouldn't push a step over breakpoint plan or do that work.
 if (GetCurrentPlan()->IsVirtualStep())
-  return;
+  return false;
 
 // If we're at a breakpoint push the step-over breakpoint plan.  Do this
 // before telling the current plan it will resume, since we might change
@@ -663,11 +663,13 @@ void Thread::SetupForResume() {
   step_bp_plan->SetAutoContinue(true);

[Lldb-commits] [lldb] [lldb] Implement basic support for reverse-continue (PR #112079)

2024-12-17 Thread Robert O'Callahan via lldb-commits


@@ -115,14 +115,18 @@ class ThreadList : public ThreadCollection {
   /// If a thread can "resume" without having to resume the target, it
   /// will return false for WillResume, and then the process will not be
   /// restarted.
+  /// Sets *direction to the run direction of the thread(s) that will
+  /// be resumed. If threads that we want to run disagree about the
+  /// direction, we execute forwards and pop any of the thread plans
+  /// that requested reverse execution.
   ///
   /// \return
   ///\b true instructs the process to resume normally,
   ///\b false means start & stopped events will be generated, but
   ///the process will not actually run.  The thread must then return
   ///the correct StopInfo when asked.
   ///
-  bool WillResume();
+  bool WillResume(lldb::RunDirection *direction);

rocallahan wrote:

Made it a reference.

https://github.com/llvm/llvm-project/pull/112079
___
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 #112079)

2024-12-17 Thread Robert O'Callahan via lldb-commits


@@ -1104,9 +1104,15 @@ class Process : public 
std::enable_shared_from_this,
   /// \see Thread:Resume()
   /// \see Thread:Step()
   /// \see Thread:Suspend()
-  virtual Status DoResume() {
-return Status::FromErrorStringWithFormatv(
-"error: {0} does not support resuming processes", GetPluginName());
+  virtual Status DoResume(lldb::RunDirection direction) {
+if (direction == lldb::RunDirection::eRunForward) {
+  return Status::FromErrorStringWithFormatv(
+  "error: {0} does not support resuming processes", GetPluginName());
+} else {
+  return Status::FromErrorStringWithFormatv(
+  "error: {0} does not support reverse execution of processes",
+  GetPluginName());
+}

rocallahan wrote:

Done. I fixed this everywhere in the PR.

https://github.com/llvm/llvm-project/pull/112079
___
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 #112079)

2024-12-17 Thread Robert O'Callahan via lldb-commits


@@ -583,6 +583,14 @@ SBError SBProcess::Continue() {
   return sb_error;
 }
 
+SBError SBProcess::ContinueInDirection(RunDirection direction) {
+  ProcessSP process_sp(GetSP());
+  if (process_sp) {
+process_sp->SetBaseDirection(direction);
+  }

rocallahan wrote:

It needs to be `if (ProcessSP process_sp = GetSP())`. Done.

https://github.com/llvm/llvm-project/pull/112079
___
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 #112079)

2024-12-17 Thread Robert O'Callahan via lldb-commits


@@ -0,0 +1,185 @@
+import logging
+import os
+import os.path
+import random
+
+import lldb
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test.gdbclientutils import *
+import lldbgdbserverutils
+from lldbsuite.support import seven
+
+
+class GDBProxyTestBase(TestBase):
+"""
+Base class for gdbserver proxy tests.
+
+This class will setup and start a mock GDB server for the test to use.
+It pases through requests to a regular lldb-server/debugserver and
+forwards replies back to the LLDB under test.
+"""
+
+"""The gdbserver that we implement."""
+server = None
+"""The inner lldb-server/debugserver process that we proxy requests 
into."""
+monitor_server = None
+monitor_sock = None
+
+server_socket_class = TCPServerSocket
+
+DEFAULT_TIMEOUT = 20 * (10 if ("ASAN_OPTIONS" in os.environ) else 1)
+
+_verbose_log_handler = None
+_log_formatter = logging.Formatter(fmt="%(asctime)-15s %(levelname)-8s 
%(message)s")
+_validate_checksums = True
+
+def setUpBaseLogging(self):
+self.logger = logging.getLogger(__name__)
+
+if len(self.logger.handlers) > 0:
+return  # We have set up this handler already
+
+self.logger.propagate = False
+self.logger.setLevel(logging.DEBUG)
+
+# log all warnings to stderr
+handler = logging.StreamHandler()
+handler.setLevel(logging.WARNING)
+handler.setFormatter(self._log_formatter)
+self.logger.addHandler(handler)
+
+def setUp(self):
+TestBase.setUp(self)
+
+self.setUpBaseLogging()
+
+if self.isVerboseLoggingRequested():
+# If requested, full logs go to a log file
+log_file_name = self.getLogBasenameForCurrentTest() + "-proxy.log"
+self._verbose_log_handler = logging.FileHandler(log_file_name)
+self._verbose_log_handler.setFormatter(self._log_formatter)
+self._verbose_log_handler.setLevel(logging.DEBUG)
+self.logger.addHandler(self._verbose_log_handler)
+
+if lldbplatformutil.getPlatform() == "macosx":
+self.debug_monitor_exe = lldbgdbserverutils.get_debugserver_exe()
+self.debug_monitor_extra_args = []
+# debugserver does not produce correct checksums
+self._validate_checksums = False
+else:
+self.debug_monitor_exe = lldbgdbserverutils.get_lldb_server_exe()
+self.debug_monitor_extra_args = ["gdbserver"]
+self.assertIsNotNone(self.debug_monitor_exe)
+
+self.server = MockGDBServer(self.server_socket_class())
+self.server.responder = self
+
+def tearDown(self):
+# TestBase.tearDown will kill the process, but we need to kill it early
+# so its client connection closes and we can stop the server before
+# finally calling the base tearDown.
+if self.process() is not None:
+self.process().Kill()
+self.server.stop()
+
+self.logger.removeHandler(self._verbose_log_handler)
+self._verbose_log_handler = None
+
+TestBase.tearDown(self)
+
+def isVerboseLoggingRequested(self):
+# We will report our detailed logs if the user requested that the 
"gdb-remote" channel is
+# logged.
+return any(("gdb-remote" in channel) for channel in 
lldbtest_config.channels)
+
+def connect(self, target):
+"""
+Create a process by connecting to the mock GDB server.
+"""
+self.prep_debug_monitor_and_inferior()
+self.server.start()
+
+listener = self.dbg.GetListener()
+error = lldb.SBError()
+process = target.ConnectRemote(
+listener, self.server.get_connect_url(), "gdb-remote", error
+)
+self.assertTrue(error.Success(), error.description)
+self.assertTrue(process, PROCESS_IS_VALID)
+return process
+
+def get_next_port(self):
+return 12000 + random.randint(0, 3999)

rocallahan wrote:

Removed.

https://github.com/llvm/llvm-project/pull/112079
___
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 #112079)

2024-12-17 Thread Robert O'Callahan via lldb-commits


@@ -0,0 +1,185 @@
+import logging
+import os
+import os.path
+import random
+
+import lldb
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test.gdbclientutils import *
+import lldbgdbserverutils
+from lldbsuite.support import seven
+
+
+class GDBProxyTestBase(TestBase):
+"""
+Base class for gdbserver proxy tests.
+
+This class will setup and start a mock GDB server for the test to use.
+It pases through requests to a regular lldb-server/debugserver and
+forwards replies back to the LLDB under test.
+"""
+
+"""The gdbserver that we implement."""
+server = None
+"""The inner lldb-server/debugserver process that we proxy requests 
into."""
+monitor_server = None
+monitor_sock = None
+
+server_socket_class = TCPServerSocket
+
+DEFAULT_TIMEOUT = 20 * (10 if ("ASAN_OPTIONS" in os.environ) else 1)
+
+_verbose_log_handler = None
+_log_formatter = logging.Formatter(fmt="%(asctime)-15s %(levelname)-8s 
%(message)s")
+_validate_checksums = True
+
+def setUpBaseLogging(self):
+self.logger = logging.getLogger(__name__)
+
+if len(self.logger.handlers) > 0:
+return  # We have set up this handler already
+

rocallahan wrote:

Removed this. I had copied it from `gdbremote_testcase.py`; it seems to be 
unnecessary there too.

https://github.com/llvm/llvm-project/pull/112079
___
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 #112079)

2024-12-17 Thread Robert O'Callahan via lldb-commits

https://github.com/rocallahan updated 
https://github.com/llvm/llvm-project/pull/112079

>From 0c9f80e8d0e925cc75e6ef2696955e2a60782689 Mon Sep 17 00:00:00 2001
From: Robert O'Callahan 
Date: Tue, 17 Dec 2024 23:40:34 +
Subject: [PATCH 1/9] Move thread-notification setup to happen later and check
 run_me_only_list instead of wants_solo_run

---
 lldb/source/Target/ThreadList.cpp | 28 ++--
 1 file changed, 14 insertions(+), 14 deletions(-)

diff --git a/lldb/source/Target/ThreadList.cpp 
b/lldb/source/Target/ThreadList.cpp
index 1a2d7dd61c778f..b44e53e0673b47 100644
--- a/lldb/source/Target/ThreadList.cpp
+++ b/lldb/source/Target/ThreadList.cpp
@@ -540,20 +540,6 @@ bool ThreadList::WillResume() {
 }
   }
 
-  if (wants_solo_run) {
-Log *log = GetLog(LLDBLog::Step);
-if (log && log->GetVerbose())
-  LLDB_LOGF(log, "Turning on notification of new threads while single "
- "stepping a thread.");
-m_process.StartNoticingNewThreads();
-  } else {
-Log *log = GetLog(LLDBLog::Step);
-if (log && log->GetVerbose())
-  LLDB_LOGF(log, "Turning off notification of new threads while single "
- "stepping a thread.");
-m_process.StopNoticingNewThreads();
-  }
-
   // Give all the threads that are likely to run a last chance to set up their
   // state before we negotiate who is actually going to get a chance to run...
   // Don't set to resume suspended threads, and if any thread wanted to stop
@@ -607,6 +593,20 @@ bool ThreadList::WillResume() {
 }
   }
 
+  if (run_me_only_list.GetSize(false) == 0) {
+Log *log = GetLog(LLDBLog::Step);
+if (log && log->GetVerbose())
+  LLDB_LOGF(log, "Turning on notification of new threads while single "
+ "stepping a thread.");
+m_process.StartNoticingNewThreads();
+  } else {
+Log *log = GetLog(LLDBLog::Step);
+if (log && log->GetVerbose())
+  LLDB_LOGF(log, "Turning off notification of new threads while single "
+ "stepping a thread.");
+m_process.StopNoticingNewThreads();
+  }
+
   bool need_to_resume = true;
 
   if (run_me_only_list.GetSize(false) == 0) {

>From f5d538f5a4088a792a1e3d47eeaef9390d1ace2e Mon Sep 17 00:00:00 2001
From: Robert O'Callahan 
Date: Tue, 17 Dec 2024 23:46:01 +
Subject: [PATCH 2/9] Make Thread::WillResume report whether it pushed a
 ThreadPlanStepOverBreakpoint

---
 lldb/include/lldb/Target/Thread.h | 13 -
 lldb/source/Target/Thread.cpp |  6 --
 2 files changed, 12 insertions(+), 7 deletions(-)

diff --git a/lldb/include/lldb/Target/Thread.h 
b/lldb/include/lldb/Target/Thread.h
index 38b65b2bc58490..ef66fa11574db9 100644
--- a/lldb/include/lldb/Target/Thread.h
+++ b/lldb/include/lldb/Target/Thread.h
@@ -200,11 +200,14 @@ class Thread : public 
std::enable_shared_from_this,
   ///The User resume state for this thread.
   lldb::StateType GetResumeState() const { return m_resume_state; }
 
-  // This function is called on all the threads before "ShouldResume" and
-  // "WillResume" in case a thread needs to change its state before the
-  // ThreadList polls all the threads to figure out which ones actually will
-  // get to run and how.
-  void SetupForResume();
+  /// This function is called on all the threads before "ShouldResume" and
+  /// "WillResume" in case a thread needs to change its state before the
+  /// ThreadList polls all the threads to figure out which ones actually will
+  /// get to run and how.
+  ///
+  /// \return
+  ///True if we pushed a ThreadPlanStepOverBreakpoint
+  bool SetupForResume();
 
   // Do not override this function, it is for thread plan logic only
   bool ShouldResume(lldb::StateType resume_state);
diff --git a/lldb/source/Target/Thread.cpp b/lldb/source/Target/Thread.cpp
index a6130f6b925bbf..b5261310970611 100644
--- a/lldb/source/Target/Thread.cpp
+++ b/lldb/source/Target/Thread.cpp
@@ -617,7 +617,7 @@ void Thread::WillStop() {
   current_plan->WillStop();
 }
 
-void Thread::SetupForResume() {
+bool Thread::SetupForResume() {
   if (GetResumeState() != eStateSuspended) {
 // First check whether this thread is going to "actually" resume at all.
 // For instance, if we're stepping from one level to the next of an
@@ -625,7 +625,7 @@ void Thread::SetupForResume() {
 // without actually running this thread.  In that case, for this thread we
 // shouldn't push a step over breakpoint plan or do that work.
 if (GetCurrentPlan()->IsVirtualStep())
-  return;
+  return false;
 
 // If we're at a breakpoint push the step-over breakpoint plan.  Do this
 // before telling the current plan it will resume, since we might change
@@ -663,11 +663,13 @@ void Thread::SetupForResume() {
   step_bp_plan->SetAutoContinue(true);
 }
 QueueThreadPlan(step_bp_plan_sp, false);
+return true;
   }
 }
   }
 }
   }
+  return false;
 }
 

[Lldb-commits] [lldb] [lldb] Implement basic support for reverse-continue (PR #112079)

2024-12-17 Thread Robert O'Callahan via lldb-commits


@@ -608,19 +594,47 @@ bool ThreadList::WillResume() {
   }
 
   bool need_to_resume = true;
-
   if (run_me_only_list.GetSize(false) == 0) {
+*direction = m_process.GetBaseDirection();
+// We've determined the direction so now we can determine which
+// threads need to step over breakpoints.
+for (pos = m_threads.begin(); pos != end; ++pos) {
+  if ((*pos)->GetResumeState() != eStateSuspended &&
+  (!wants_solo_run || (*pos)->GetCurrentPlan()->StopOthers())) {
+if ((*pos)->IsOperatingSystemPluginThread() &&
+!(*pos)->GetBackingThread())
+  continue;
+if ((*pos)->SetupToStepOverBreakpointIfNeeded(*direction)) {
+  run_me_only_list.AddThread(*pos);
+  break;
+}
+  }
+}
+  } // else we'll set *direction to the direction of the chosen thread later
+  if (run_me_only_list.GetSize(false) == 0) {
+// *direction has been set to m_process.GetBaseDirection().
 // Everybody runs as they wish:
 for (pos = m_threads.begin(); pos != end; ++pos) {
   ThreadSP thread_sp(*pos);
   StateType run_state;
-  if (thread_sp->GetResumeState() != eStateSuspended)
+  if (thread_sp->GetResumeState() != eStateSuspended) {

rocallahan wrote:

Done.

https://github.com/llvm/llvm-project/pull/112079
___
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 #112079)

2024-12-17 Thread Robert O'Callahan via lldb-commits


@@ -0,0 +1,151 @@
+import lldb
+import time
+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):
+NO_DEBUG_INFO_TESTCASE = True

rocallahan wrote:

Done.

https://github.com/llvm/llvm-project/pull/112079
___
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 #112079)

2024-12-17 Thread Robert O'Callahan via lldb-commits


@@ -199,6 +199,20 @@ uint64_t 
GDBRemoteCommunicationClient::GetRemoteMaxPacketSize() {
   return m_max_packet_size;
 }
 
+bool GDBRemoteCommunicationClient::GetReverseContinueSupported() {
+  if (m_supports_reverse_continue == eLazyBoolCalculate) {
+GetRemoteQSupported();
+  }
+  return m_supports_reverse_continue == eLazyBoolYes;
+}
+
+bool GDBRemoteCommunicationClient::GetReverseStepSupported() {
+  if (m_supports_reverse_step == eLazyBoolCalculate) {
+GetRemoteQSupported();
+  }

rocallahan wrote:

Fixed this everywhere it occurred in my PR.

https://github.com/llvm/llvm-project/pull/112079
___
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 #112079)

2024-12-17 Thread Robert O'Callahan via lldb-commits

https://github.com/rocallahan updated 
https://github.com/llvm/llvm-project/pull/112079

>From 0c9f80e8d0e925cc75e6ef2696955e2a60782689 Mon Sep 17 00:00:00 2001
From: Robert O'Callahan 
Date: Tue, 17 Dec 2024 23:40:34 +
Subject: [PATCH 1/9] Move thread-notification setup to happen later and check
 run_me_only_list instead of wants_solo_run

---
 lldb/source/Target/ThreadList.cpp | 28 ++--
 1 file changed, 14 insertions(+), 14 deletions(-)

diff --git a/lldb/source/Target/ThreadList.cpp 
b/lldb/source/Target/ThreadList.cpp
index 1a2d7dd61c778f..b44e53e0673b47 100644
--- a/lldb/source/Target/ThreadList.cpp
+++ b/lldb/source/Target/ThreadList.cpp
@@ -540,20 +540,6 @@ bool ThreadList::WillResume() {
 }
   }
 
-  if (wants_solo_run) {
-Log *log = GetLog(LLDBLog::Step);
-if (log && log->GetVerbose())
-  LLDB_LOGF(log, "Turning on notification of new threads while single "
- "stepping a thread.");
-m_process.StartNoticingNewThreads();
-  } else {
-Log *log = GetLog(LLDBLog::Step);
-if (log && log->GetVerbose())
-  LLDB_LOGF(log, "Turning off notification of new threads while single "
- "stepping a thread.");
-m_process.StopNoticingNewThreads();
-  }
-
   // Give all the threads that are likely to run a last chance to set up their
   // state before we negotiate who is actually going to get a chance to run...
   // Don't set to resume suspended threads, and if any thread wanted to stop
@@ -607,6 +593,20 @@ bool ThreadList::WillResume() {
 }
   }
 
+  if (run_me_only_list.GetSize(false) == 0) {
+Log *log = GetLog(LLDBLog::Step);
+if (log && log->GetVerbose())
+  LLDB_LOGF(log, "Turning on notification of new threads while single "
+ "stepping a thread.");
+m_process.StartNoticingNewThreads();
+  } else {
+Log *log = GetLog(LLDBLog::Step);
+if (log && log->GetVerbose())
+  LLDB_LOGF(log, "Turning off notification of new threads while single "
+ "stepping a thread.");
+m_process.StopNoticingNewThreads();
+  }
+
   bool need_to_resume = true;
 
   if (run_me_only_list.GetSize(false) == 0) {

>From f5d538f5a4088a792a1e3d47eeaef9390d1ace2e Mon Sep 17 00:00:00 2001
From: Robert O'Callahan 
Date: Tue, 17 Dec 2024 23:46:01 +
Subject: [PATCH 2/9] Make Thread::WillResume report whether it pushed a
 ThreadPlanStepOverBreakpoint

---
 lldb/include/lldb/Target/Thread.h | 13 -
 lldb/source/Target/Thread.cpp |  6 --
 2 files changed, 12 insertions(+), 7 deletions(-)

diff --git a/lldb/include/lldb/Target/Thread.h 
b/lldb/include/lldb/Target/Thread.h
index 38b65b2bc58490..ef66fa11574db9 100644
--- a/lldb/include/lldb/Target/Thread.h
+++ b/lldb/include/lldb/Target/Thread.h
@@ -200,11 +200,14 @@ class Thread : public 
std::enable_shared_from_this,
   ///The User resume state for this thread.
   lldb::StateType GetResumeState() const { return m_resume_state; }
 
-  // This function is called on all the threads before "ShouldResume" and
-  // "WillResume" in case a thread needs to change its state before the
-  // ThreadList polls all the threads to figure out which ones actually will
-  // get to run and how.
-  void SetupForResume();
+  /// This function is called on all the threads before "ShouldResume" and
+  /// "WillResume" in case a thread needs to change its state before the
+  /// ThreadList polls all the threads to figure out which ones actually will
+  /// get to run and how.
+  ///
+  /// \return
+  ///True if we pushed a ThreadPlanStepOverBreakpoint
+  bool SetupForResume();
 
   // Do not override this function, it is for thread plan logic only
   bool ShouldResume(lldb::StateType resume_state);
diff --git a/lldb/source/Target/Thread.cpp b/lldb/source/Target/Thread.cpp
index a6130f6b925bbf..b5261310970611 100644
--- a/lldb/source/Target/Thread.cpp
+++ b/lldb/source/Target/Thread.cpp
@@ -617,7 +617,7 @@ void Thread::WillStop() {
   current_plan->WillStop();
 }
 
-void Thread::SetupForResume() {
+bool Thread::SetupForResume() {
   if (GetResumeState() != eStateSuspended) {
 // First check whether this thread is going to "actually" resume at all.
 // For instance, if we're stepping from one level to the next of an
@@ -625,7 +625,7 @@ void Thread::SetupForResume() {
 // without actually running this thread.  In that case, for this thread we
 // shouldn't push a step over breakpoint plan or do that work.
 if (GetCurrentPlan()->IsVirtualStep())
-  return;
+  return false;
 
 // If we're at a breakpoint push the step-over breakpoint plan.  Do this
 // before telling the current plan it will resume, since we might change
@@ -663,11 +663,13 @@ void Thread::SetupForResume() {
   step_bp_plan->SetAutoContinue(true);
 }
 QueueThreadPlan(step_bp_plan_sp, false);
+return true;
   }
 }
   }
 }
   }
+  return false;
 }
 

[Lldb-commits] [lldb] [lldb] Implement basic support for reverse-continue (PR #112079)

2024-12-17 Thread Robert O'Callahan via lldb-commits


@@ -0,0 +1,185 @@
+import logging
+import os
+import os.path
+import random
+
+import lldb
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test.gdbclientutils import *
+import lldbgdbserverutils
+from lldbsuite.support import seven
+
+
+class GDBProxyTestBase(TestBase):
+"""
+Base class for gdbserver proxy tests.
+
+This class will setup and start a mock GDB server for the test to use.
+It pases through requests to a regular lldb-server/debugserver and
+forwards replies back to the LLDB under test.
+"""
+
+"""The gdbserver that we implement."""
+server = None
+"""The inner lldb-server/debugserver process that we proxy requests 
into."""
+monitor_server = None
+monitor_sock = None
+
+server_socket_class = TCPServerSocket
+
+DEFAULT_TIMEOUT = 20 * (10 if ("ASAN_OPTIONS" in os.environ) else 1)
+
+_verbose_log_handler = None
+_log_formatter = logging.Formatter(fmt="%(asctime)-15s %(levelname)-8s 
%(message)s")
+_validate_checksums = True
+
+def setUpBaseLogging(self):
+self.logger = logging.getLogger(__name__)
+
+if len(self.logger.handlers) > 0:
+return  # We have set up this handler already
+
+self.logger.propagate = False
+self.logger.setLevel(logging.DEBUG)
+
+# log all warnings to stderr
+handler = logging.StreamHandler()
+handler.setLevel(logging.WARNING)
+handler.setFormatter(self._log_formatter)
+self.logger.addHandler(handler)
+
+def setUp(self):
+TestBase.setUp(self)
+
+self.setUpBaseLogging()
+
+if self.isVerboseLoggingRequested():
+# If requested, full logs go to a log file
+log_file_name = self.getLogBasenameForCurrentTest() + "-proxy.log"
+self._verbose_log_handler = logging.FileHandler(log_file_name)
+self._verbose_log_handler.setFormatter(self._log_formatter)
+self._verbose_log_handler.setLevel(logging.DEBUG)
+self.logger.addHandler(self._verbose_log_handler)
+
+if lldbplatformutil.getPlatform() == "macosx":
+self.debug_monitor_exe = lldbgdbserverutils.get_debugserver_exe()
+self.debug_monitor_extra_args = []
+# debugserver does not produce correct checksums
+self._validate_checksums = False
+else:
+self.debug_monitor_exe = lldbgdbserverutils.get_lldb_server_exe()
+self.debug_monitor_extra_args = ["gdbserver"]
+self.assertIsNotNone(self.debug_monitor_exe)
+
+self.server = MockGDBServer(self.server_socket_class())
+self.server.responder = self
+
+def tearDown(self):
+# TestBase.tearDown will kill the process, but we need to kill it early
+# so its client connection closes and we can stop the server before
+# finally calling the base tearDown.
+if self.process() is not None:
+self.process().Kill()
+self.server.stop()
+
+self.logger.removeHandler(self._verbose_log_handler)
+self._verbose_log_handler = None
+
+TestBase.tearDown(self)
+
+def isVerboseLoggingRequested(self):
+# We will report our detailed logs if the user requested that the 
"gdb-remote" channel is
+# logged.
+return any(("gdb-remote" in channel) for channel in 
lldbtest_config.channels)
+
+def connect(self, target):
+"""
+Create a process by connecting to the mock GDB server.
+"""
+self.prep_debug_monitor_and_inferior()
+self.server.start()
+
+listener = self.dbg.GetListener()
+error = lldb.SBError()
+process = target.ConnectRemote(
+listener, self.server.get_connect_url(), "gdb-remote", error
+)
+self.assertTrue(error.Success(), error.description)
+self.assertTrue(process, PROCESS_IS_VALID)
+return process
+
+def get_next_port(self):
+return 12000 + random.randint(0, 3999)
+
+def prep_debug_monitor_and_inferior(self):
+inferior_exe_path = self.getBuildArtifact("a.out")
+self.connect_to_debug_monitor([inferior_exe_path])
+self.assertIsNotNone(self.monitor_server)
+self.initial_handshake()
+
+def initial_handshake(self):
+self.monitor_server.send_packet(seven.bitcast_to_bytes("+"))
+reply = 
seven.bitcast_to_string(self.monitor_server.get_normal_packet())
+self.assertEqual(reply, "+")
+
self.monitor_server.send_packet(seven.bitcast_to_bytes("QStartNoAckMode"))
+reply = 
seven.bitcast_to_string(self.monitor_server.get_normal_packet())
+self.assertEqual(reply, "+")
+reply = 
seven.bitcast_to_string(self.monitor_server.get_normal_packet())
+self.assertEqual(reply, "OK")
+self.monitor_server.send_packet(seven.bitcast_to_bytes("+"))
+reply = 
seven.bitcast_to_string(self.monitor_server.get_normal_packet())
+

  1   2   >