summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lldb/include/lldb/Target/Process.h33
-rw-r--r--lldb/source/Core/ConnectionFileDescriptor.cpp2
-rw-r--r--lldb/source/Core/Debugger.cpp18
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp47
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h10
-rw-r--r--lldb/source/Target/Process.cpp126
6 files changed, 182 insertions, 54 deletions
diff --git a/lldb/include/lldb/Target/Process.h b/lldb/include/lldb/Target/Process.h
index 82a87aa4947..f8684abcf6d 100644
--- a/lldb/include/lldb/Target/Process.h
+++ b/lldb/include/lldb/Target/Process.h
@@ -20,6 +20,7 @@
#include "lldb/Interpreter/Args.h"
#include "lldb/Interpreter/Options.h"
#include "lldb/Core/Broadcaster.h"
+#include "lldb/Core/Communication.h"
#include "lldb/Core/Error.h"
#include "lldb/Core/Event.h"
#include "lldb/Core/StringList.h"
@@ -1678,6 +1679,10 @@ protected:
UnixSignals m_unix_signals; /// This is the current signal set for this process.
ConstString m_target_triple;
lldb::ABISP m_abi_sp;
+ lldb::InputReaderSP m_process_input_reader;
+ lldb_private::Communication m_stdio_communication;
+ lldb_private::Mutex m_stdio_comm_mutex;
+ std::string m_stdout_data;
typedef std::map<lldb::LanguageType, lldb::LanguageRuntimeSP> LanguageRuntimeCollection;
LanguageRuntimeCollection m_language_runtimes;
@@ -1738,7 +1743,33 @@ protected:
size_t
WriteMemoryPrivate (lldb::addr_t addr, const void *buf, size_t size, Error &error);
-
+
+ void
+ AppendSTDOUT (const char *s, size_t len);
+
+ static void
+ STDIOReadThreadBytesReceived (void *baton, const void *src, size_t src_len);
+
+ void
+ PushProcessInputReader ();
+
+ void
+ PopProcessInputReader ();
+
+ void
+ ResetProcessInputReader ();
+
+ void
+ SetUpProcessInputReader (int file_descriptor);
+
+ static size_t
+ ProcessInputReaderCallback (void *baton,
+ InputReader &reader,
+ lldb::InputReaderAction notification,
+ const char *bytes,
+ size_t bytes_len);
+
+
private:
//------------------------------------------------------------------
// For Process only
diff --git a/lldb/source/Core/ConnectionFileDescriptor.cpp b/lldb/source/Core/ConnectionFileDescriptor.cpp
index 8029ad3b643..96d70bc1012 100644
--- a/lldb/source/Core/ConnectionFileDescriptor.cpp
+++ b/lldb/source/Core/ConnectionFileDescriptor.cpp
@@ -38,6 +38,7 @@ using namespace lldb_private;
ConnectionFileDescriptor::ConnectionFileDescriptor () :
Connection(),
m_fd (-1),
+ m_is_socket (false),
m_should_close_fd (false)
{
lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION | LIBLLDB_LOG_OBJECT,
@@ -48,6 +49,7 @@ ConnectionFileDescriptor::ConnectionFileDescriptor () :
ConnectionFileDescriptor::ConnectionFileDescriptor (int fd, bool owns_fd) :
Connection(),
m_fd (fd),
+ m_is_socket (false),
m_should_close_fd (owns_fd)
{
lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION | LIBLLDB_LOG_OBJECT,
diff --git a/lldb/source/Core/Debugger.cpp b/lldb/source/Core/Debugger.cpp
index 625969b2847..5e6f93c91d4 100644
--- a/lldb/source/Core/Debugger.cpp
+++ b/lldb/source/Core/Debugger.cpp
@@ -324,22 +324,8 @@ Debugger::DispatchInputCallback (void *baton, const void *bytes, size_t bytes_le
void
Debugger::DispatchInput (const char *bytes, size_t bytes_len)
{
- if (bytes == NULL || bytes_len == 0)
- return;
-
- // TODO: implement the STDIO to the process as an input reader...
- TargetSP target = GetSelectedTarget();
- if (target.get() != NULL)
- {
- ProcessSP process_sp = target->GetProcessSP();
- if (process_sp.get() != NULL
- && StateIsRunningState (process_sp->GetState()))
- {
- Error error;
- if (process_sp->PutSTDIN (bytes, bytes_len, error) == bytes_len)
- return;
- }
- }
+// if (bytes == NULL || bytes_len == 0)
+// return;
WriteToDefaultReader (bytes, bytes_len);
}
diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index 93c67302981..52499ba173a 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -104,9 +104,7 @@ ProcessGDBRemote::ProcessGDBRemote(Target& target, Listener &listener) :
Process (target, listener),
m_dynamic_loader_ap (),
m_flags (0),
- m_stdio_communication ("gdb-remote.stdio"),
m_stdio_mutex (Mutex::eMutexTypeRecursive),
- m_stdout_data (),
m_byte_order (eByteOrderHost),
m_gdb_comm(),
m_debugserver_pid (LLDB_INVALID_PROCESS_ID),
@@ -1634,23 +1632,23 @@ ProcessGDBRemote::DoSignal (int signo)
return error;
}
-void
-ProcessGDBRemote::STDIOReadThreadBytesReceived (void *baton, const void *src, size_t src_len)
-{
- ProcessGDBRemote *process = (ProcessGDBRemote *)baton;
- process->AppendSTDOUT(static_cast<const char *>(src), src_len);
-}
-
-void
-ProcessGDBRemote::AppendSTDOUT (const char* s, size_t len)
-{
- ProcessGDBRemoteLog::LogIf (GDBR_LOG_PROCESS, "ProcessGDBRemote::%s (<%d> %s) ...", __FUNCTION__, len, s);
- Mutex::Locker locker(m_stdio_mutex);
- m_stdout_data.append(s, len);
+//void
+//ProcessGDBRemote::STDIOReadThreadBytesReceived (void *baton, const void *src, size_t src_len)
+//{
+// ProcessGDBRemote *process = (ProcessGDBRemote *)baton;
+// process->AppendSTDOUT(static_cast<const char *>(src), src_len);
+//}
- // FIXME: Make a real data object for this and put it out.
- BroadcastEventIfUnique (eBroadcastBitSTDOUT);
-}
+//void
+//ProcessGDBRemote::AppendSTDOUT (const char* s, size_t len)
+//{
+// ProcessGDBRemoteLog::LogIf (GDBR_LOG_PROCESS, "ProcessGDBRemote::%s (<%d> %s) ...", __FUNCTION__, len, s);
+// Mutex::Locker locker(m_stdio_mutex);
+// m_stdout_data.append(s, len);
+//
+// // FIXME: Make a real data object for this and put it out.
+// BroadcastEventIfUnique (eBroadcastBitSTDOUT);
+//}
Error
@@ -1867,18 +1865,7 @@ ProcessGDBRemote::StartDebugserverProcess
if (m_debugserver_pid != LLDB_INVALID_PROCESS_ID)
{
if (pty.GetMasterFileDescriptor() != lldb_utility::PseudoTerminal::invalid_fd)
- {
- std::auto_ptr<ConnectionFileDescriptor> conn_ap(new ConnectionFileDescriptor (pty.ReleaseMasterFileDescriptor(), true));
- if (conn_ap.get())
- {
- m_stdio_communication.SetConnection(conn_ap.release());
- if (m_stdio_communication.IsConnected())
- {
- m_stdio_communication.SetReadThreadBytesReceivedCallback (STDIOReadThreadBytesReceived, this);
- m_stdio_communication.StartReadThread();
- }
- }
- }
+ SetUpProcessInputReader (pty.ReleaseMasterFileDescriptor());
}
}
else
diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
index 6330c7b0fb2..ae79c5a48bc 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
@@ -261,11 +261,11 @@ protected:
bool
ProcessIDIsValid ( ) const;
- static void
- STDIOReadThreadBytesReceived (void *baton, const void *src, size_t src_len);
+// static void
+// STDIOReadThreadBytesReceived (void *baton, const void *src, size_t src_len);
- void
- AppendSTDOUT (const char* s, size_t len);
+// void
+// AppendSTDOUT (const char* s, size_t len);
void
Clear ( );
@@ -321,9 +321,7 @@ protected:
std::auto_ptr<lldb_private::DynamicLoader> m_dynamic_loader_ap;
lldb_private::Flags m_flags; // Process specific flags (see eFlags enums)
- lldb_private::Communication m_stdio_communication;
lldb_private::Mutex m_stdio_mutex; // Multithreaded protection for stdio
- std::string m_stdout_data;
lldb::ByteOrder m_byte_order;
GDBRemoteCommunication m_gdb_comm;
lldb::pid_t m_debugserver_pid;
diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp
index c9b5579be5d..ea6b200f318 100644
--- a/lldb/source/Target/Process.cpp
+++ b/lldb/source/Target/Process.cpp
@@ -14,7 +14,9 @@
#include "lldb/Breakpoint/StoppointCallbackContext.h"
#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Core/Event.h"
+#include "lldb/Core/ConnectionFileDescriptor.h"
#include "lldb/Core/Debugger.h"
+#include "lldb/Core/InputReader.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/State.h"
@@ -85,7 +87,11 @@ Process::Process(Target &target, Listener &listener) :
m_notifications (),
m_persistent_vars(),
m_listener(listener),
- m_unix_signals ()
+ m_unix_signals (),
+ m_process_input_reader (),
+ m_stdio_communication ("lldb.process.stdio"),
+ m_stdio_comm_mutex (Mutex::eMutexTypeRecursive),
+ m_stdout_data ()
{
UpdateInstanceName();
@@ -1160,6 +1166,7 @@ Process::Launch
Error error;
m_target_triple.Clear();
m_abi_sp.reset();
+ m_process_input_reader.reset();
Module *exe_module = m_target.GetExecutableModule().get();
if (exe_module)
@@ -1305,6 +1312,7 @@ Process::Attach (lldb::pid_t attach_pid)
m_target_triple.Clear();
m_abi_sp.reset();
+ m_process_input_reader.reset();
// Find the process and its architecture. Make sure it matches the architecture
// of the current Target, and if not adjust it.
@@ -1347,6 +1355,7 @@ Process::Attach (const char *process_name, bool wait_for_launch)
{
m_target_triple.Clear();
m_abi_sp.reset();
+ m_process_input_reader.reset();
// Find the process and its architecture. Make sure it matches the architecture
// of the current Target, and if not adjust it.
@@ -1467,6 +1476,12 @@ Process::Destroy ()
DidDestroy();
StopPrivateStateThread();
}
+ m_stdio_communication.StopReadThread();
+ m_stdio_communication.Disconnect();
+ if (m_process_input_reader && m_process_input_reader->IsActive())
+ m_target.GetDebugger().PopInputReader (m_process_input_reader);
+ if (m_process_input_reader)
+ m_process_input_reader.reset();
}
return error;
}
@@ -1714,6 +1729,10 @@ Process::HandlePrivateEvent (EventSP &event_sp)
{
log->Printf ("\tChanging public state from: %s to %s", StateAsCString(GetState ()), StateAsCString (internal_state));
}
+ if (StateIsRunningState (internal_state))
+ PushProcessInputReader ();
+ else
+ PopProcessInputReader ();
Process::ProcessEventData::SetUpdateStateOnRemoval(event_sp.get());
BroadcastEvent (event_sp);
}
@@ -2035,6 +2054,111 @@ Process::GetArchSpecForExistingProcess (const char *process_name)
return Host::GetArchSpecForExistingProcess (process_name);
}
+void
+Process::AppendSTDOUT (const char * s, size_t len)
+{
+ Mutex::Locker locker (m_stdio_comm_mutex);
+ m_stdout_data.append (s, len);
+
+ BroadcastEventIfUnique (eBroadcastBitSTDOUT);
+}
+
+void
+Process::STDIOReadThreadBytesReceived (void *baton, const void *src, size_t src_len)
+{
+ Process *process = (Process *) baton;
+ process->AppendSTDOUT (static_cast<const char *>(src), src_len);
+}
+
+size_t
+Process::ProcessInputReaderCallback (void *baton,
+ InputReader &reader,
+ lldb::InputReaderAction notification,
+ const char *bytes,
+ size_t bytes_len)
+{
+ Process *process = (Process *) baton;
+
+ switch (notification)
+ {
+ case eInputReaderActivate:
+ break;
+
+ case eInputReaderDeactivate:
+ break;
+
+ case eInputReaderReactivate:
+ break;
+
+ case eInputReaderGotToken:
+ {
+ Error error;
+ process->PutSTDIN (bytes, bytes_len, error);
+ }
+ break;
+
+ case eInputReaderDone:
+ break;
+
+ }
+
+ return bytes_len;
+}
+
+void
+Process::ResetProcessInputReader ()
+{
+ m_process_input_reader.reset();
+}
+
+void
+Process::SetUpProcessInputReader (int file_descriptor)
+{
+ // First set up the Read Thread for reading/handling process I/O
+
+ std::auto_ptr<ConnectionFileDescriptor> conn_ap (new ConnectionFileDescriptor (file_descriptor, true));
+
+ if (conn_ap.get())
+ {
+ m_stdio_communication.SetConnection (conn_ap.release());
+ if (m_stdio_communication.IsConnected())
+ {
+ m_stdio_communication.SetReadThreadBytesReceivedCallback (STDIOReadThreadBytesReceived, this);
+ m_stdio_communication.StartReadThread();
+
+ // Now read thread is set up, set up input reader.
+
+ if (!m_process_input_reader.get())
+ {
+ m_process_input_reader.reset (new InputReader(m_target.GetDebugger()));
+ Error err (m_process_input_reader->Initialize (Process::ProcessInputReaderCallback,
+ this,
+ eInputReaderGranularityByte,
+ NULL,
+ NULL,
+ false));
+
+ if (err.Fail())
+ m_process_input_reader.reset();
+ }
+ }
+ }
+}
+
+void
+Process::PushProcessInputReader ()
+{
+ if (m_process_input_reader && !m_process_input_reader->IsActive())
+ m_target.GetDebugger().PushInputReader (m_process_input_reader);
+}
+
+void
+Process::PopProcessInputReader ()
+{
+ if (m_process_input_reader && m_process_input_reader->IsActive())
+ m_target.GetDebugger().PopInputReader (m_process_input_reader);
+}
+
lldb::UserSettingsControllerSP
Process::GetSettingsController (bool finish)
{
OpenPOWER on IntegriCloud