summaryrefslogtreecommitdiffstats
path: root/lldb/source/Target/Process.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Target/Process.cpp')
-rw-r--r--lldb/source/Target/Process.cpp126
1 files changed, 125 insertions, 1 deletions
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