[Lldb-commits] [lldb] r228419 - Add support for SBProcess::PutSTDIN to remote processes

Vince Harron vharron at google.com
Fri Feb 6 10:32:57 PST 2015


Author: vharron
Date: Fri Feb  6 12:32:57 2015
New Revision: 228419

URL: http://llvm.org/viewvc/llvm-project?rev=228419&view=rev
Log:
Add support for SBProcess::PutSTDIN to remote processes

Processes running on a remote target can already send $O messages
to send stdout but there is no way to send stdin to a remote
inferior.

This allows processes using the API to pump stdin into a remote
inferior process.

It fixes a hang in TestProcessIO.py when running against a remote
target.


Modified:
    lldb/trunk/include/lldb/Target/Process.h
    lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
    lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
    lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
    lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h
    lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
    lldb/trunk/source/Target/Process.cpp
    lldb/trunk/source/Utility/StringExtractorGDBRemote.cpp
    lldb/trunk/source/Utility/StringExtractorGDBRemote.h

Modified: lldb/trunk/include/lldb/Target/Process.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Process.h?rev=228419&r1=228418&r2=228419&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/Process.h (original)
+++ lldb/trunk/include/lldb/Target/Process.h Fri Feb  6 12:32:57 2015
@@ -3180,6 +3180,7 @@ protected:
     lldb::IOHandlerSP           m_process_input_reader;
     Communication               m_stdio_communication;
     Mutex                       m_stdio_communication_mutex;
+    bool                        m_stdio_disable;           /// Remember process launch setting
     std::string                 m_stdout_data;
     std::string                 m_stderr_data;
     Mutex                       m_profile_data_comm_mutex;

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp?rev=228419&r1=228418&r2=228419&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp Fri Feb  6 12:32:57 2015
@@ -1866,6 +1866,21 @@ GDBRemoteCommunicationClient::SendAttach
     return -1;
 }
 
+int
+GDBRemoteCommunicationClient::SendStdinNotification (const char* data, size_t data_len)
+{
+    StreamString packet;
+    packet.PutCString("I");
+    packet.PutBytesAsRawHex8(data, data_len);
+    StringExtractorGDBRemote response;
+    if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success)
+    {
+        return 0;
+    }
+    return response.GetError();
+
+}
+
 const lldb_private::ArchSpec &
 GDBRemoteCommunicationClient::GetHostArchitecture ()
 {

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h?rev=228419&r1=228418&r2=228419&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h Fri Feb  6 12:32:57 2015
@@ -175,6 +175,23 @@ public:
 
 
     //------------------------------------------------------------------
+    /// Sends a GDB remote protocol 'I' packet that delivers stdin
+    /// data to the remote process.
+    ///
+    /// @param[in] data
+    ///     A pointer to stdin data.
+    ///
+    /// @param[in] data_len
+    ///     The number of bytes available at \a data.
+    ///
+    /// @return
+    ///     Zero if the attach was successful, or an error indicating
+    ///     an error code.
+    //------------------------------------------------------------------
+    int
+    SendStdinNotification(const char* data, size_t data_len);
+
+    //------------------------------------------------------------------
     /// Sets the path to use for stdin/out/err for a process
     /// that will be launched with the 'A' packet.
     ///

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp?rev=228419&r1=228418&r2=228419&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp Fri Feb  6 12:32:57 2015
@@ -370,6 +370,10 @@ GDBRemoteCommunicationServer::GetPacketA
             packet_result = Handle_H (packet);
             break;
 
+        case StringExtractorGDBRemote::eServerPacketType_I:
+            packet_result = Handle_I (packet);
+            break;
+
         case StringExtractorGDBRemote::eServerPacketType_m:
             packet_result = Handle_m (packet);
             break;
@@ -3427,6 +3431,46 @@ GDBRemoteCommunicationServer::Handle_H (
     }
 
     return SendOKResponse();
+}
+
+GDBRemoteCommunicationServer::PacketResult
+GDBRemoteCommunicationServer::Handle_I (StringExtractorGDBRemote &packet)
+{
+    Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
+
+    // Ensure we're llgs.
+    if (!IsGdbServer())
+        return SendUnimplementedResponse("GDBRemoteCommunicationServer::Handle_I() unimplemented");
+
+    // Fail if we don't have a current process.
+    if (!m_debugged_process_sp || (m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID))
+    {
+        if (log)
+            log->Printf ("GDBRemoteCommunicationServer::%s failed, no process available", __FUNCTION__);
+        return SendErrorResponse (0x15);
+    }
+
+    packet.SetFilePos (::strlen("I"));
+    char tmp[4096];
+    for (;;)
+    {
+        size_t read = packet.GetHexBytesAvail(tmp, sizeof(tmp));
+        if (read == 0)
+        {
+            break;
+        }
+        // write directly to stdin *this might block if stdin buffer is full*
+        // TODO: enqueue this block in circular buffer and send window size to remote host
+        ConnectionStatus status;
+        Error error;
+        m_stdio_communication.Write(tmp, read, status, &error);
+        if (error.Fail())
+        {
+            return SendErrorResponse (0x15);
+        }
+    }
+
+    return SendOKResponse();
 }
 
 GDBRemoteCommunicationServer::PacketResult

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h?rev=228419&r1=228418&r2=228419&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h Fri Feb  6 12:32:57 2015
@@ -415,6 +415,9 @@ protected:
     Handle_H (StringExtractorGDBRemote &packet);
 
     PacketResult
+    Handle_I (StringExtractorGDBRemote &packet);
+
+    PacketResult
     Handle_interrupt (StringExtractorGDBRemote &packet);
 
     PacketResult

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp?rev=228419&r1=228418&r2=228419&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp Fri Feb  6 12:32:57 2015
@@ -942,6 +942,7 @@ ProcessGDBRemote::DoLaunch (Module *exe_
 
                 SetPrivateState (SetThreadStopInfo (m_last_stop_packet));
                 
+                m_stdio_disable = disable_stdio;
                 if (!disable_stdio)
                 {
                     if (pty.GetMasterFileDescriptor() != lldb_utility::PseudoTerminal::invalid_fd)
@@ -2477,6 +2478,10 @@ ProcessGDBRemote::PutSTDIN (const char *
         ConnectionStatus status;
         m_stdio_communication.Write(src, src_len, status, NULL);
     }
+    else if (!m_stdio_disable)
+    {
+        m_gdb_comm.SendStdinNotification(src, src_len);
+    }
     return 0;
 }
 

Modified: lldb/trunk/source/Target/Process.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Process.cpp?rev=228419&r1=228418&r2=228419&view=diff
==============================================================================
--- lldb/trunk/source/Target/Process.cpp (original)
+++ lldb/trunk/source/Target/Process.cpp Fri Feb  6 12:32:57 2015
@@ -720,6 +720,7 @@ Process::Process(Target &target, Listene
     m_process_input_reader (),
     m_stdio_communication ("process.stdio"),
     m_stdio_communication_mutex (Mutex::eMutexTypeRecursive),
+    m_stdio_disable(true),
     m_stdout_data (),
     m_stderr_data (),
     m_profile_data_comm_mutex (Mutex::eMutexTypeRecursive),
@@ -3911,6 +3912,7 @@ Process::Destroy ()
         }
         m_stdio_communication.StopReadThread();
         m_stdio_communication.Disconnect();
+        m_stdio_disable = true;
 
         if (m_process_input_reader)
         {

Modified: lldb/trunk/source/Utility/StringExtractorGDBRemote.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Utility/StringExtractorGDBRemote.cpp?rev=228419&r1=228418&r2=228419&view=diff
==============================================================================
--- lldb/trunk/source/Utility/StringExtractorGDBRemote.cpp (original)
+++ lldb/trunk/source/Utility/StringExtractorGDBRemote.cpp Fri Feb  6 12:32:57 2015
@@ -265,6 +265,9 @@ StringExtractorGDBRemote::GetServerPacke
       case 'H':
         return eServerPacketType_H;
 
+      case 'I':
+        return eServerPacketType_I;
+
       case 'k':
         if (packet_size == 1) return eServerPacketType_k;
         break;

Modified: lldb/trunk/source/Utility/StringExtractorGDBRemote.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Utility/StringExtractorGDBRemote.h?rev=228419&r1=228418&r2=228419&view=diff
==============================================================================
--- lldb/trunk/source/Utility/StringExtractorGDBRemote.h (original)
+++ lldb/trunk/source/Utility/StringExtractorGDBRemote.h Fri Feb  6 12:32:57 2015
@@ -130,6 +130,7 @@ public:
         eServerPacketType_g,
         eServerPacketType_G,
         eServerPacketType_H,
+        eServerPacketType_I, // stdin notification
         eServerPacketType_k,
         eServerPacketType_m,
         eServerPacketType_M,





More information about the lldb-commits mailing list