[Lldb-commits] [PATCH] D100261: [lldb] [gdb-remote server] Support selecting process via Hg

2021-07-02 Thread Michał Górny via Phabricator via lldb-commits
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rGb7c140335beb: [lldb] [gdb-remote server] Support selecting 
process via Hg (authored by mgorny).
Herald added a project: LLDB.

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D100261/new/

https://reviews.llvm.org/D100261

Files:
  lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
  lldb/test/API/tools/lldb-server/TestGdbRemoteFork.py

Index: lldb/test/API/tools/lldb-server/TestGdbRemoteFork.py
===
--- lldb/test/API/tools/lldb-server/TestGdbRemoteFork.py
+++ lldb/test/API/tools/lldb-server/TestGdbRemoteFork.py
@@ -16,7 +16,7 @@
 self.reset_test_sequence()
 
 # continue and expect fork
-fork_regex = "[$]T.*;{}:p([0-9a-f]*)[.]([0-9a-f]*).*".format(variant)
+fork_regex = "[$]T.*;{}:p([0-9a-f]+)[.]([0-9a-f]+).*".format(variant)
 self.test_sequence.add_log_lines([
 "read packet: $c#00",
 {"direction": "send", "regex": fork_regex,
@@ -57,3 +57,137 @@
 {"direction": "send", "regex": r"[$]W00#.*"},
 ], True)
 self.expect_gdbremote_sequence()
+
+def fork_and_follow_test(self, variant):
+self.build()
+self.prep_debug_monitor_and_inferior(inferior_args=[variant])
+self.add_qSupported_packets(["multiprocess+",
+ "{}-events+".format(variant)])
+ret = self.expect_gdbremote_sequence()
+self.assertIn("{}-events+".format(variant), ret["qSupported_response"])
+self.reset_test_sequence()
+
+# continue and expect fork
+procinfo_regex = "[$]pid:([0-9a-f]+);.*"
+fork_regex = "[$]T.*;{}:p([0-9a-f]+)[.]([0-9a-f]+).*".format(variant)
+self.test_sequence.add_log_lines([
+"read packet: $qProcessInfo#00",
+{"direction": "send", "regex": procinfo_regex,
+ "capture": {1: "parent_pid"}},
+"read packet: $c#00",
+{"direction": "send", "regex": fork_regex,
+ "capture": {1: "pid", 2: "tid"}},
+], True)
+ret = self.expect_gdbremote_sequence()
+parent_pid, pid, tid = (int(ret[x], 16) for x
+in ("parent_pid", "pid", "tid"))
+self.reset_test_sequence()
+
+# switch to the forked child
+self.test_sequence.add_log_lines([
+"read packet: $Hgp{:x}.{:x}#00".format(pid, tid),
+{"direction": "send", "regex": r"[$]OK#.*"},
+"read packet: $Hcp{:x}.{:x}#00".format(pid, tid),
+{"direction": "send", "regex": r"[$]OK#.*"},
+], True)
+
+# detach the parent
+self.test_sequence.add_log_lines([
+"read packet: $D;{:x}#00".format(parent_pid),
+{"direction": "send", "regex": r"[$]OK#.*"},
+], True)
+ret = self.expect_gdbremote_sequence()
+self.reset_test_sequence()
+
+# resume the child
+self.test_sequence.add_log_lines([
+"read packet: $c#00",
+{"direction": "send", "regex": r"[$]W00#.*"},
+], True)
+self.expect_gdbremote_sequence()
+
+@add_test_categories(["fork"])
+def test_fork_follow(self):
+self.fork_and_follow_test("fork")
+
+@add_test_categories(["fork"])
+def test_vfork_follow(self):
+self.fork_and_follow_test("vfork")
+
+@add_test_categories(["fork"])
+def test_select_wrong_pid(self):
+self.build()
+self.prep_debug_monitor_and_inferior()
+self.add_qSupported_packets(["multiprocess+"])
+ret = self.expect_gdbremote_sequence()
+self.assertIn("multiprocess+", ret["qSupported_response"])
+self.reset_test_sequence()
+
+# get process pid
+procinfo_regex = "[$]pid:([0-9a-f]+);.*"
+self.test_sequence.add_log_lines([
+"read packet: $qProcessInfo#00",
+{"direction": "send", "regex": procinfo_regex,
+ "capture": {1: "pid"}},
+"read packet: $qC#00",
+{"direction": "send", "regex": "[$]QC([0-9a-f]+)#.*",
+ "capture": {1: "tid"}},
+], True)
+ret = self.expect_gdbremote_sequence()
+pid, tid = (int(ret[x], 16) for x in ("pid", "tid"))
+self.reset_test_sequence()
+
+# try switching to correct pid
+self.test_sequence.add_log_lines([
+"read packet: $Hgp{:x}.{:x}#00".format(pid, tid),
+{"direction": "send", "regex": r"[$]OK#.*"},
+"read packet: $Hcp{:x}.{:x}#00".format(pid, tid),
+{"direction": "send", "regex": r"[$]OK#.*"},
+], True)
+ret = self.expect_gdbremote_sequence()
+
+# try switching to invalid tid
+self.test_sequence.add_log_lines([
+"read 

[Lldb-commits] [PATCH] D100261: [lldb] [gdb-remote server] Support selecting process via Hg

2021-07-01 Thread Jonas Devlieghere via Phabricator via lldb-commits
JDevlieghere added inline comments.



Comment at: 
lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp:2121
+return SendErrorResponse(llvm::make_error(
+inconvertibleErrorCode(), "Malformed thread-id"));
+

mgorny wrote:
> JDevlieghere wrote:
> > Would it be useful to say "Malformed thread-id for process-id {}"? 
> In this context, 'thread-id' is GDB protocol jargon for 'PID and/or TID'. So 
> if it's malformed, then we don't really have a process ID here. I suppose I 
> could try replacing 'thread-id' with something more verbose but I'm not sure 
> if this is the kind of error end users will be dealing with.
Fair enough. Thanks for the explanation! 


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D100261/new/

https://reviews.llvm.org/D100261

___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D100261: [lldb] [gdb-remote server] Support selecting process via Hg

2021-07-01 Thread Michał Górny via Phabricator via lldb-commits
mgorny added inline comments.



Comment at: 
lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp:2121
+return SendErrorResponse(llvm::make_error(
+inconvertibleErrorCode(), "Malformed thread-id"));
+

JDevlieghere wrote:
> Would it be useful to say "Malformed thread-id for process-id {}"? 
In this context, 'thread-id' is GDB protocol jargon for 'PID and/or TID'. So if 
it's malformed, then we don't really have a process ID here. I suppose I could 
try replacing 'thread-id' with something more verbose but I'm not sure if this 
is the kind of error end users will be dealing with.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D100261/new/

https://reviews.llvm.org/D100261

___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D100261: [lldb] [gdb-remote server] Support selecting process via Hg

2021-06-30 Thread Jonas Devlieghere via Phabricator via lldb-commits
JDevlieghere accepted this revision.
JDevlieghere added a comment.
This revision is now accepted and ready to land.

I'm probably not the most qualified to sign off on this, but the review has 
stalled and I don't see anything obviously wrong here so LGTM.




Comment at: 
lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp:2121
+return SendErrorResponse(llvm::make_error(
+inconvertibleErrorCode(), "Malformed thread-id"));
+

Would it be useful to say "Malformed thread-id for process-id {}"? 


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D100261/new/

https://reviews.llvm.org/D100261

___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D100261: [lldb] [gdb-remote server] Support selecting process via Hg

2021-04-28 Thread Michał Górny via Phabricator via lldb-commits
mgorny added inline comments.



Comment at: 
lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp:2130
+return SendErrorResponse(llvm::make_error(
+inconvertibleErrorCode(), "No current process and no PID provided"));
+

rovka wrote:
> Just a drive-by comment: The previous behaviour was to send 0x15 when the 
> current process ID was invalid. Should we do that here?
I've originally did that but it was kinda hackish and @labath didn't like it.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D100261/new/

https://reviews.llvm.org/D100261

___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D100261: [lldb] [gdb-remote server] Support selecting process via Hg

2021-04-28 Thread Diana Picus via Phabricator via lldb-commits
rovka added inline comments.



Comment at: 
lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp:2130
+return SendErrorResponse(llvm::make_error(
+inconvertibleErrorCode(), "No current process and no PID provided"));
+

Just a drive-by comment: The previous behaviour was to send 0x15 when the 
current process ID was invalid. Should we do that here?


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D100261/new/

https://reviews.llvm.org/D100261

___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D100261: [lldb] [gdb-remote server] Support selecting process via Hg

2021-04-24 Thread Michał Górny via Phabricator via lldb-commits
mgorny updated this revision to Diff 340310.
mgorny added a comment.

Add tests.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D100261/new/

https://reviews.llvm.org/D100261

Files:
  lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
  lldb/test/API/tools/lldb-server/TestGdbRemoteFork.py

Index: lldb/test/API/tools/lldb-server/TestGdbRemoteFork.py
===
--- lldb/test/API/tools/lldb-server/TestGdbRemoteFork.py
+++ lldb/test/API/tools/lldb-server/TestGdbRemoteFork.py
@@ -16,7 +16,7 @@
 self.reset_test_sequence()
 
 # continue and expect fork
-fork_regex = "[$]T.*;{}:p([0-9a-f]*)[.]([0-9a-f]*).*".format(variant)
+fork_regex = "[$]T.*;{}:p([0-9a-f]+)[.]([0-9a-f]+).*".format(variant)
 self.test_sequence.add_log_lines([
 "read packet: $c#00",
 {"direction": "send", "regex": fork_regex,
@@ -57,3 +57,137 @@
 {"direction": "send", "regex": r"[$]W00#.*"},
 ], True)
 self.expect_gdbremote_sequence()
+
+def fork_and_follow_test(self, variant):
+self.build()
+self.prep_debug_monitor_and_inferior(inferior_args=[variant])
+self.add_qSupported_packets(["multiprocess+",
+ "{}-events+".format(variant)])
+ret = self.expect_gdbremote_sequence()
+self.assertIn("{}-events+".format(variant), ret["qSupported_response"])
+self.reset_test_sequence()
+
+# continue and expect fork
+procinfo_regex = "[$]pid:([0-9a-f]+);.*"
+fork_regex = "[$]T.*;{}:p([0-9a-f]+)[.]([0-9a-f]+).*".format(variant)
+self.test_sequence.add_log_lines([
+"read packet: $qProcessInfo#00",
+{"direction": "send", "regex": procinfo_regex,
+ "capture": {1: "parent_pid"}},
+"read packet: $c#00",
+{"direction": "send", "regex": fork_regex,
+ "capture": {1: "pid", 2: "tid"}},
+], True)
+ret = self.expect_gdbremote_sequence()
+parent_pid, pid, tid = (int(ret[x], 16) for x
+in ("parent_pid", "pid", "tid"))
+self.reset_test_sequence()
+
+# switch to the forked child
+self.test_sequence.add_log_lines([
+"read packet: $Hgp{:x}.{:x}#00".format(pid, tid),
+{"direction": "send", "regex": r"[$]OK#.*"},
+"read packet: $Hcp{:x}.{:x}#00".format(pid, tid),
+{"direction": "send", "regex": r"[$]OK#.*"},
+], True)
+
+# detach the parent
+self.test_sequence.add_log_lines([
+"read packet: $D;{:x}#00".format(parent_pid),
+{"direction": "send", "regex": r"[$]OK#.*"},
+], True)
+ret = self.expect_gdbremote_sequence()
+self.reset_test_sequence()
+
+# resume the child
+self.test_sequence.add_log_lines([
+"read packet: $c#00",
+{"direction": "send", "regex": r"[$]W00#.*"},
+], True)
+self.expect_gdbremote_sequence()
+
+@add_test_categories(["fork"])
+def test_fork_follow(self):
+self.fork_and_follow_test("fork")
+
+@add_test_categories(["fork"])
+def test_vfork_follow(self):
+self.fork_and_follow_test("vfork")
+
+@add_test_categories(["fork"])
+def test_select_wrong_pid(self):
+self.build()
+self.prep_debug_monitor_and_inferior()
+self.add_qSupported_packets(["multiprocess+"])
+ret = self.expect_gdbremote_sequence()
+self.assertIn("multiprocess+", ret["qSupported_response"])
+self.reset_test_sequence()
+
+# get process pid
+procinfo_regex = "[$]pid:([0-9a-f]+);.*"
+self.test_sequence.add_log_lines([
+"read packet: $qProcessInfo#00",
+{"direction": "send", "regex": procinfo_regex,
+ "capture": {1: "pid"}},
+"read packet: $qC#00",
+{"direction": "send", "regex": "[$]QC([0-9a-f]+)#.*",
+ "capture": {1: "tid"}},
+], True)
+ret = self.expect_gdbremote_sequence()
+pid, tid = (int(ret[x], 16) for x in ("pid", "tid"))
+self.reset_test_sequence()
+
+# try switching to correct pid
+self.test_sequence.add_log_lines([
+"read packet: $Hgp{:x}.{:x}#00".format(pid, tid),
+{"direction": "send", "regex": r"[$]OK#.*"},
+"read packet: $Hcp{:x}.{:x}#00".format(pid, tid),
+{"direction": "send", "regex": r"[$]OK#.*"},
+], True)
+ret = self.expect_gdbremote_sequence()
+
+# try switching to invalid tid
+self.test_sequence.add_log_lines([
+"read packet: $Hgp{:x}.{:x}#00".format(pid, tid+1),
+{"direction": "send", "regex": r"[$]E15#.*"},
+"read packet: $Hcp{:x}.{:x}#00".format(pid, tid+1),
+{"direction": "send", "regex": r"[$]E15#.*"},
+   

[Lldb-commits] [PATCH] D100261: [lldb] [gdb-remote server] Support selecting process via Hg

2021-04-14 Thread Michał Górny via Phabricator via lldb-commits
mgorny updated this revision to Diff 337541.
mgorny marked an inline comment as done.
mgorny added a comment.

Revert accidental whitespace change.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D100261/new/

https://reviews.llvm.org/D100261

Files:
  lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp


Index: 
lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
===
--- lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
+++ lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
@@ -2055,16 +2055,6 @@
 GDBRemoteCommunicationServerLLGS::Handle_H(StringExtractorGDBRemote ) {
   Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
 
-  // Fail if we don't have a current process.
-  if (!m_current_process ||
-  (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) {
-LLDB_LOGF(
-log,
-"GDBRemoteCommunicationServerLLGS::%s failed, no process available",
-__FUNCTION__);
-return SendErrorResponse(0x15);
-  }
-
   // Parse out which variant of $H is requested.
   packet.SetFilePos(strlen("H"));
   if (packet.GetBytesLeft() < 1) {
@@ -2076,14 +2066,14 @@
   }
 
   const char h_variant = packet.GetChar();
-  lldb::pid_t default_pid;
+  NativeProcessProtocol *default_process;
   switch (h_variant) {
   case 'g':
-default_pid = m_current_process->GetID();
+default_process = m_current_process;
 break;
 
   case 'c':
-default_pid = m_continue_process->GetID();
+default_process = m_continue_process;
 break;
 
   default:
@@ -2096,16 +2086,32 @@
   }
 
   // Parse out the thread number.
-  llvm::Expected tid_ret =
-  ReadTid(packet, /*allow_all=*/true, default_pid);
-  if (!tid_ret)
-return SendErrorResponse(tid_ret.takeError());
+  auto pid_tid = packet.GetPidTid(default_process ? default_process->GetID()
+  : LLDB_INVALID_PROCESS_ID);
+  if (!pid_tid)
+return SendErrorResponse(llvm::make_error(
+inconvertibleErrorCode(), "Malformed thread-id"));
+
+  lldb::pid_t pid = pid_tid->first;
+  lldb::tid_t tid = pid_tid->second;
+
+  if (pid == StringExtractorGDBRemote::AllProcesses)
+return SendUnimplementedResponse("Selecting all processes not supported");
+  if (pid == LLDB_INVALID_PROCESS_ID)
+return SendErrorResponse(llvm::make_error(
+inconvertibleErrorCode(), "No current process and no PID provided"));
+
+  // Check the process ID and find respective process instance.
+  auto new_process_it = m_debugged_processes.find(pid);
+  if (new_process_it == m_debugged_processes.end())
+return SendErrorResponse(llvm::make_error(
+inconvertibleErrorCode(),
+llvm::formatv("No process with PID {0} debugged", pid)));
 
-  lldb::tid_t tid = tid_ret.get();
   // Ensure we have the given thread when not specifying -1 (all threads) or 0
   // (any thread).
   if (tid != LLDB_INVALID_THREAD_ID && tid != 0) {
-NativeThreadProtocol *thread = m_current_process->GetThreadByID(tid);
+NativeThreadProtocol *thread = new_process_it->second->GetThreadByID(tid);
 if (!thread) {
   LLDB_LOGF(log,
 "GDBRemoteCommunicationServerLLGS::%s failed, tid %" PRIu64
@@ -2115,13 +2121,15 @@
 }
   }
 
-  // Now switch the given thread type.
+  // Now switch the given process and thread type.
   switch (h_variant) {
   case 'g':
+m_current_process = new_process_it->second.get();
 SetCurrentThreadID(tid);
 break;
 
   case 'c':
+m_continue_process = new_process_it->second.get();
 SetContinueThreadID(tid);
 break;
 


Index: lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
===
--- lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
+++ lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
@@ -2055,16 +2055,6 @@
 GDBRemoteCommunicationServerLLGS::Handle_H(StringExtractorGDBRemote ) {
   Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
 
-  // Fail if we don't have a current process.
-  if (!m_current_process ||
-  (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) {
-LLDB_LOGF(
-log,
-"GDBRemoteCommunicationServerLLGS::%s failed, no process available",
-__FUNCTION__);
-return SendErrorResponse(0x15);
-  }
-
   // Parse out which variant of $H is requested.
   packet.SetFilePos(strlen("H"));
   if (packet.GetBytesLeft() < 1) {
@@ -2076,14 +2066,14 @@
   }
 
   const char h_variant = packet.GetChar();
-  lldb::pid_t default_pid;
+  NativeProcessProtocol *default_process;
   switch (h_variant) {
   case 'g':
-default_pid = m_current_process->GetID();
+default_process = m_current_process;
 break;
 
   case 'c':
-default_pid = m_continue_process->GetID();
+default_process = 

[Lldb-commits] [PATCH] D100261: [lldb] [gdb-remote server] Support selecting process via Hg

2021-04-14 Thread Michał Górny via Phabricator via lldb-commits
mgorny added inline comments.



Comment at: 
lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp:2102
+  if (pid == StringExtractorGDBRemote::AllProcesses)
+return SendUnimplementedResponse("Selecting all processes not supported");
+  if (pid == LLDB_INVALID_PROCESS_ID)

labath wrote:
> Does it ever make sense to have more than one (process or thread) selected? 
> If not, an error response may be more appropriate..
Good question.

As for PID, I don't think that the client would do something like that within 
foreseeable future.

However, sending all-TIDs are technically supported in our LLGS client code. I 
don't know whether it's actually used anywhere, though.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D100261/new/

https://reviews.llvm.org/D100261

___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D100261: [lldb] [gdb-remote server] Support selecting process via Hg

2021-04-14 Thread Pavel Labath via Phabricator via lldb-commits
labath added inline comments.



Comment at: 
lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp:2102
+  if (pid == StringExtractorGDBRemote::AllProcesses)
+return SendUnimplementedResponse("Selecting all processes not supported");
+  if (pid == LLDB_INVALID_PROCESS_ID)

Does it ever make sense to have more than one (process or thread) selected? If 
not, an error response may be more appropriate..



Comment at: 
lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h:234
   const llvm::ArrayRef client_features) override;
-
 private:

revert


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D100261/new/

https://reviews.llvm.org/D100261

___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D100261: [lldb] [gdb-remote server] Support selecting process via Hg

2021-04-13 Thread Michał Górny via Phabricator via lldb-commits
mgorny updated this revision to Diff 337241.
mgorny added a comment.

Rebase.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D100261/new/

https://reviews.llvm.org/D100261

Files:
  lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
  lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h

Index: lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
===
--- lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
+++ lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
@@ -231,7 +231,6 @@
 
   virtual std::vector HandleFeatures(
   const llvm::ArrayRef client_features) override;
-
 private:
   llvm::Expected> BuildTargetXml();
 
Index: lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
===
--- lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
+++ lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
@@ -2058,16 +2058,6 @@
 GDBRemoteCommunicationServerLLGS::Handle_H(StringExtractorGDBRemote ) {
   Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
 
-  // Fail if we don't have a current process.
-  if (!m_current_process ||
-  (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) {
-LLDB_LOGF(
-log,
-"GDBRemoteCommunicationServerLLGS::%s failed, no process available",
-__FUNCTION__);
-return SendErrorResponse(0x15);
-  }
-
   // Parse out which variant of $H is requested.
   packet.SetFilePos(strlen("H"));
   if (packet.GetBytesLeft() < 1) {
@@ -2079,14 +2069,14 @@
   }
 
   const char h_variant = packet.GetChar();
-  lldb::pid_t default_pid;
+  NativeProcessProtocol *default_process;
   switch (h_variant) {
   case 'g':
-default_pid = m_current_process->GetID();
+default_process = m_current_process;
 break;
 
   case 'c':
-default_pid = m_continue_process->GetID();
+default_process = m_continue_process;
 break;
 
   default:
@@ -2099,16 +2089,32 @@
   }
 
   // Parse out the thread number.
-  llvm::Expected tid_ret =
-  ReadTid(packet, /*allow_all=*/true, default_pid);
-  if (!tid_ret)
-return SendErrorResponse(tid_ret.takeError());
+  auto pid_tid = packet.GetPidTid(default_process ? default_process->GetID()
+  : LLDB_INVALID_PROCESS_ID);
+  if (!pid_tid)
+return SendErrorResponse(llvm::make_error(
+inconvertibleErrorCode(), "Malformed thread-id"));
+
+  lldb::pid_t pid = pid_tid->first;
+  lldb::tid_t tid = pid_tid->second;
+
+  if (pid == StringExtractorGDBRemote::AllProcesses)
+return SendUnimplementedResponse("Selecting all processes not supported");
+  if (pid == LLDB_INVALID_PROCESS_ID)
+return SendErrorResponse(llvm::make_error(
+inconvertibleErrorCode(), "No current process and no PID provided"));
+
+  // Check the process ID and find respective process instance.
+  auto new_process_it = m_debugged_processes.find(pid);
+  if (new_process_it == m_debugged_processes.end())
+return SendErrorResponse(llvm::make_error(
+inconvertibleErrorCode(),
+llvm::formatv("No process with PID {0} debugged", pid)));
 
-  lldb::tid_t tid = tid_ret.get();
   // Ensure we have the given thread when not specifying -1 (all threads) or 0
   // (any thread).
   if (tid != LLDB_INVALID_THREAD_ID && tid != 0) {
-NativeThreadProtocol *thread = m_current_process->GetThreadByID(tid);
+NativeThreadProtocol *thread = new_process_it->second->GetThreadByID(tid);
 if (!thread) {
   LLDB_LOGF(log,
 "GDBRemoteCommunicationServerLLGS::%s failed, tid %" PRIu64
@@ -2118,13 +2124,15 @@
 }
   }
 
-  // Now switch the given thread type.
+  // Now switch the given process and thread type.
   switch (h_variant) {
   case 'g':
+m_current_process = new_process_it->second.get();
 SetCurrentThreadID(tid);
 break;
 
   case 'c':
+m_continue_process = new_process_it->second.get();
 SetContinueThreadID(tid);
 break;
 
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D100261: [lldb] [gdb-remote server] Support selecting process via Hg

2021-04-11 Thread Michał Górny via Phabricator via lldb-commits
mgorny created this revision.
mgorny added reviewers: labath, emaste, krytarowski.
mgorny requested review of this revision.

Support using the extended thread-id syntax with Hg packet to select
a subprocess.  This makes it possible to start providing support for
running some of the debugger packets against another subprocesses.


https://reviews.llvm.org/D100261

Files:
  lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
  lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h

Index: lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
===
--- lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
+++ lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
@@ -90,6 +90,7 @@
   const NativeProcessProtocol::Factory _process_factory;
   lldb::tid_t m_current_tid = LLDB_INVALID_THREAD_ID;
   lldb::tid_t m_continue_tid = LLDB_INVALID_THREAD_ID;
+  lldb::pid_t m_current_pid = LLDB_INVALID_PROCESS_ID;
   std::recursive_mutex m_debugged_process_mutex;
   std::unique_ptr m_debugged_process_up;
   std::unordered_map>
@@ -233,9 +234,17 @@
 
   // Verify and get the process instance selected by the client.
   // If run is true, the process selected by "Hc" packet will be returned,
-  // otherwise the one selected by "Hg" will be used.  Returns nullptr if there
-  // is no process debugged.
-  NativeProcessProtocol *GetCurrentProcess(bool run) const;
+  // otherwise the one selected by "Hg" will be used.
+  //
+  // If allow_subprocess is true, a subprocess instance may be returned.
+  // Otherwise, only the main process can be returned and the function will
+  // return nullptr if a subprocess is selected.
+  //
+  // Returns nullptr if there is no process debugged.
+  NativeProcessProtocol *GetCurrentProcess(bool run,
+   bool allow_subprocess = false) const;
+
+  void SetCurrentProcessID(lldb::pid_t pid, lldb::tid_t tid);
 
 private:
   llvm::Expected> BuildTargetXml();
Index: lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
===
--- lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
+++ lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
@@ -1624,6 +1624,9 @@
   m_current_tid = tid;
   if (m_debugged_process_up)
 m_debugged_process_up->SetCurrentThreadID(m_current_tid);
+
+  // Reset subprocess support
+  m_current_pid = LLDB_INVALID_PROCESS_ID;
 }
 
 void GDBRemoteCommunicationServerLLGS::SetContinueThreadID(lldb::tid_t tid) {
@@ -2081,12 +2084,32 @@
   }
 
   // Parse out the thread number.
-  llvm::Expected tid_ret =
-  ReadTid(packet, /*run=*/h_variant == 'c', /*allow_all=*/true);
-  if (!tid_ret)
-return SendErrorResponse(tid_ret.takeError());
+  auto *process = GetCurrentProcess(h_variant == 'c', true);
+  auto pid_tid =
+  packet.GetPidTid(process ? process->GetID() : LLDB_INVALID_PROCESS_ID);
+  if (!pid_tid)
+return SendErrorResponse(llvm::make_error(
+inconvertibleErrorCode(), "Malformed thread-id"));
+
+  lldb::pid_t pid = pid_tid->first;
+  lldb::tid_t tid = pid_tid->second;
+
+  if (pid == StringExtractorGDBRemote::AllProcesses)
+return SendUnimplementedResponse("Selecting all processes not supported");
+  if (pid != m_debugged_process_up->GetID()) {
+// Is it a subprocess?
+if (m_additional_processes.find(pid) == m_additional_processes.end())
+  return SendErrorResponse(llvm::make_error(
+  inconvertibleErrorCode(),
+  llvm::formatv("PID {0} not debugged", pid)));
+if (h_variant != 'g')
+  return SendUnimplementedResponse(
+  "Hc packet for subprocess not supported");
+
+SetCurrentProcessID(pid, tid);
+return SendOKResponse();
+  }
 
-  lldb::tid_t tid = tid_ret.get();
   // Ensure we have the given thread when not specifying -1 (all threads) or 0
   // (any thread).
   if (tid != LLDB_INVALID_THREAD_ID && tid != 0) {
@@ -2622,7 +2645,7 @@
 GDBRemoteCommunication::PacketResult
 GDBRemoteCommunicationServerLLGS::Handle_z(StringExtractorGDBRemote ) {
   // Ensure we have a process.
-  auto *process = GetCurrentProcess(false);
+  auto *process = GetCurrentProcess(false, true);
   if (!process) {
 Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
 LLDB_LOG(log, "failed, no process available");
@@ -3622,12 +3645,33 @@
"Enabling protocol extensions failed: {0}");
 }
 
-NativeProcessProtocol *
-GDBRemoteCommunicationServerLLGS::GetCurrentProcess(bool run) const {
+NativeProcessProtocol *GDBRemoteCommunicationServerLLGS::GetCurrentProcess(
+bool run, bool allow_subprocess) const {
   // Fail if we don't have a current process.
   if (!m_debugged_process_up ||
   (m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID))
 return nullptr;