llvmorg-github-actions[bot] wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-lldb

Author: Charles Zablit (charles-zablit)

<details>
<summary>Changes</summary>

The client kept the previously-selected thread across stops, ignoring the 
primary tid from the server in `T&lt;sig&gt;thread:&lt;tid&gt;`.
On Windows, lldb-server halts the inferior by injecting a thread called 
`DbgUiRemoteBreakin` whose only job is to execute an int 3. After an interrupt, 
the process has `N+1` threads and the new one is what caused the stop. The 
server reports that thread as primary, but the client ignored it and stayed on 
whichever thread was selected before. In `TestExpressionInSyscall` that thread 
is main, paused just past `NtDelayExecution`'s syscall with a garbage value in 
the RSI register. Evaluating an expression there crashes the JIT trampoline.

This patch makes `ProcessGDBRemote::RefreshStateAfterStop` record the primary 
tid from the most recent T-packet's `thread:&lt;tid&gt;` and select it after 
applying per thread stop infos.

Fixes `TestBreakpointSetRestart` and `TestExpressionInSyscall` with 
LLDB_USE_LLDB_SERVER=1.

---
Full diff: https://github.com/llvm/llvm-project/pull/203525.diff


2 Files Affected:

- (modified) lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp (+8) 
- (modified) lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h (+3) 


``````````diff
diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp 
b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index 2fc6dbb546f79..754666665ae07 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -2621,6 +2621,8 @@ StateType 
ProcessGDBRemote::SetThreadStopInfo(StringExtractor &stop_packet) {
 
     SetAddressableBitMasks(addressable_bits);
 
+    m_last_stop_primary_tid = tid;
+
     ThreadSP thread_sp = SetThreadStopInfo(
         tid, expedited_register_map, signo, thread_name, reason, description,
         exc_type, exc_data, thread_dispatch_qaddr, queue_vars_valid,
@@ -2669,7 +2671,13 @@ void ProcessGDBRemote::RefreshStateAfterStop() {
   if (m_initial_tid != LLDB_INVALID_THREAD_ID) {
     m_thread_list.SetSelectedThreadByID(m_initial_tid);
     m_initial_tid = LLDB_INVALID_THREAD_ID;
+  } else if (m_last_stop_primary_tid != LLDB_INVALID_THREAD_ID) {
+    if (ThreadSP primary_thread_sp =
+            m_thread_list.FindThreadByProtocolID(m_last_stop_primary_tid,
+                                                 /*can_update=*/false))
+      m_thread_list.SetSelectedThreadByID(primary_thread_sp->GetID());
   }
+  m_last_stop_primary_tid = LLDB_INVALID_THREAD_ID;
 
   // Let all threads recover from stopping and do any clean up based on the
   // previous thread state (if any).
diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h 
b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
index 0a3386082c388..7a030cd966a18 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
@@ -322,6 +322,9 @@ class ProcessGDBRemote : public Process,
   lldb::CommandObjectSP m_command_sp;
   int64_t m_breakpoint_pc_offset;
   lldb::tid_t m_initial_tid; // The initial thread ID, given by stub on attach
+  lldb::tid_t m_last_stop_primary_tid =
+      LLDB_INVALID_THREAD_ID; // Thread ID extracted from the most recent
+                              // T-packet's "thread:<tid>" key.
   bool m_use_g_packet_for_reading;
 
   bool m_allow_flash_writes;

``````````

</details>


https://github.com/llvm/llvm-project/pull/203525
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to