llvmorg-github-actions[bot] wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-lldb

Author: Charles Zablit (charles-zablit)

<details>
<summary>Changes</summary>

https://github.com/llvm/llvm-project/pull/194422 added `drain_stdout` to drain 
the conpty after the process is interrupted. This patch takes this further by 
also draining the stdout when the process exits.

This fixes the stdout not being printed if the process prints between a 
breakpoint hit and its end (or does not hit a breakpoint at all).

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


2 Files Affected:

- (modified) lldb/source/Plugins/Process/Windows/Common/ProcessWindows.cpp 
(+30-29) 
- (modified) lldb/source/Plugins/Process/Windows/Common/ProcessWindows.h (+4) 


``````````diff
diff --git a/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.cpp 
b/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.cpp
index 28b5554069c90..9dd49a9e7a1ba 100644
--- a/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.cpp
+++ b/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.cpp
@@ -655,6 +655,7 @@ void ProcessWindows::OnExitProcess(uint32_t exit_code) {
   LLDB_LOG(log, "Process {0} exited with code {1}", GetID(), exit_code);
 
   if (m_pty) {
+    DrainProcessStdout();
     m_pty->SetStopping(true);
     m_pty->Close();
     m_stdio_communication.InterruptRead();
@@ -675,6 +676,32 @@ void ProcessWindows::OnExitProcess(uint32_t exit_code) {
   ProcessDebugger::OnExitProcess(exit_code);
 }
 
+void ProcessWindows::DrainProcessStdout() {
+  if (!m_stdio_communication.ReadThreadIsRunning())
+    return;
+  m_stdio_communication.SynchronizeWithReadThread();
+  if (!m_pty || m_pty->GetMode() != PseudoConsole::Mode::ConPTY)
+    return;
+
+  HANDLE pipe = m_pty->GetSTDOUTHandle();
+  for (int consec_empty = 0; consec_empty < 3;) {
+    if (!m_stdio_communication.ReadThreadIsRunning())
+      break;
+    DWORD avail = 0;
+    // PeekNamedPipe is thread safe.
+    if (!::PeekNamedPipe(pipe, nullptr, 0, nullptr, &avail, nullptr))
+      break;
+    if (avail > 0) {
+      consec_empty = 0;
+      m_stdio_communication.SynchronizeWithReadThread();
+    } else {
+      ++consec_empty;
+      if (consec_empty < 3)
+        ::SleepEx(1, FALSE);
+    }
+  }
+}
+
 void ProcessWindows::OnDebuggerConnected(lldb::addr_t image_base) {
   DebuggerThreadSP debugger = m_session_data->m_debugger;
   Log *log = GetLog(WindowsLog::Process);
@@ -746,36 +773,10 @@ ProcessWindows::OnDebugException(bool first_chance,
   // synchronization the eBroadcastBitStateChanged(Stopped) event can reach
   // the Debugger event thread before the preceding eBroadcastBitSTDOUT
   // events.
-  auto drain_stdout = [this] {
-    if (!m_stdio_communication.ReadThreadIsRunning())
-      return;
-    m_stdio_communication.SynchronizeWithReadThread();
-    if (!m_pty || m_pty->GetMode() != PseudoConsole::Mode::ConPTY)
-      return;
-
-    HANDLE pipe = m_pty->GetSTDOUTHandle();
-    for (int consec_empty = 0; consec_empty < 3;) {
-      if (!m_stdio_communication.ReadThreadIsRunning())
-        break;
-      DWORD avail = 0;
-      // PeekNamedPipe is thread safe.
-      if (!::PeekNamedPipe(pipe, nullptr, 0, nullptr, &avail, nullptr))
-        break;
-      if (avail > 0) {
-        consec_empty = 0;
-        m_stdio_communication.SynchronizeWithReadThread();
-      } else {
-        ++consec_empty;
-        if (consec_empty < 3)
-          ::SleepEx(1, FALSE);
-      }
-    }
-  };
-
   if (!first_chance) {
     // Not any second chance exception is an application crash by definition.
     // It may be an expression evaluation crash.
-    drain_stdout();
+    DrainProcessStdout();
     SetPrivateState(eStateStopped);
   }
 
@@ -796,12 +797,12 @@ ProcessWindows::OnDebugException(bool first_chance,
       LLDB_LOG(log, "Hit non-loader breakpoint at address {0:x}.",
                record.GetExceptionAddress());
     }
-    drain_stdout();
+    DrainProcessStdout();
     SetPrivateState(eStateStopped);
     break;
   case EXCEPTION_SINGLE_STEP:
     result = ExceptionResult::BreakInDebugger;
-    drain_stdout();
+    DrainProcessStdout();
     SetPrivateState(eStateStopped);
     break;
   default:
diff --git a/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.h 
b/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.h
index 228619d0e3d5e..31cf498a16d50 100644
--- a/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.h
+++ b/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.h
@@ -108,6 +108,10 @@ class ProcessWindows : public Process, public 
ProcessDebugger {
   void SetPseudoConsoleHandle() override;
 
 protected:
+  /// Block until the stdio read thread has surfaced everything currently
+  /// buffered in the ConPTY/pipe to the process's STDOUT cache.
+  void DrainProcessStdout();
+
   ProcessWindows(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp);
 
   Status DoGetMemoryRegionInfo(lldb::addr_t vm_addr,

``````````

</details>


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

Reply via email to