159ec512cSGreg Clayton //===-- ProcessKDP.cpp ------------------------------------------*- C++ -*-===//
2f9765acdSGreg Clayton //
3f9765acdSGreg Clayton //                     The LLVM Compiler Infrastructure
4f9765acdSGreg Clayton //
5f9765acdSGreg Clayton // This file is distributed under the University of Illinois Open Source
6f9765acdSGreg Clayton // License. See LICENSE.TXT for details.
7f9765acdSGreg Clayton //
8f9765acdSGreg Clayton //===----------------------------------------------------------------------===//
9f9765acdSGreg Clayton 
10f9765acdSGreg Clayton // C Includes
11f9765acdSGreg Clayton #include <errno.h>
12f9765acdSGreg Clayton #include <stdlib.h>
13f9765acdSGreg Clayton 
14f9765acdSGreg Clayton // C++ Includes
15f9765acdSGreg Clayton // Other libraries and framework includes
16*3a29bdbeSGreg Clayton #include "lldb/Core/ConnectionFileDescriptor.h"
17f9765acdSGreg Clayton #include "lldb/Core/PluginManager.h"
18f9765acdSGreg Clayton #include "lldb/Core/State.h"
19f9765acdSGreg Clayton #include "lldb/Host/Host.h"
2057508026SGreg Clayton #include "lldb/Target/Target.h"
21f9765acdSGreg Clayton 
22f9765acdSGreg Clayton // Project includes
23f9765acdSGreg Clayton #include "ProcessKDP.h"
24f9765acdSGreg Clayton #include "ProcessKDPLog.h"
25f9765acdSGreg Clayton //#include "ThreadKDP.h"
26f9765acdSGreg Clayton #include "StopInfoMachException.h"
27f9765acdSGreg Clayton 
28f9765acdSGreg Clayton using namespace lldb;
29f9765acdSGreg Clayton using namespace lldb_private;
30f9765acdSGreg Clayton 
31f9765acdSGreg Clayton const char *
32f9765acdSGreg Clayton ProcessKDP::GetPluginNameStatic()
33f9765acdSGreg Clayton {
34f9765acdSGreg Clayton     return "kdp-remote";
35f9765acdSGreg Clayton }
36f9765acdSGreg Clayton 
37f9765acdSGreg Clayton const char *
38f9765acdSGreg Clayton ProcessKDP::GetPluginDescriptionStatic()
39f9765acdSGreg Clayton {
40f9765acdSGreg Clayton     return "KDP Remote protocol based debugging plug-in for darwin kernel debugging.";
41f9765acdSGreg Clayton }
42f9765acdSGreg Clayton 
43f9765acdSGreg Clayton void
44f9765acdSGreg Clayton ProcessKDP::Terminate()
45f9765acdSGreg Clayton {
46f9765acdSGreg Clayton     PluginManager::UnregisterPlugin (ProcessKDP::CreateInstance);
47f9765acdSGreg Clayton }
48f9765acdSGreg Clayton 
49f9765acdSGreg Clayton 
50f9765acdSGreg Clayton Process*
51f9765acdSGreg Clayton ProcessKDP::CreateInstance (Target &target, Listener &listener)
52f9765acdSGreg Clayton {
53f9765acdSGreg Clayton     return new ProcessKDP (target, listener);
54f9765acdSGreg Clayton }
55f9765acdSGreg Clayton 
56f9765acdSGreg Clayton bool
57*3a29bdbeSGreg Clayton ProcessKDP::CanDebug(Target &target, bool plugin_specified_by_name)
58f9765acdSGreg Clayton {
59f9765acdSGreg Clayton     // For now we are just making sure the file exists for a given module
60f9765acdSGreg Clayton     ModuleSP exe_module_sp(target.GetExecutableModule());
61f9765acdSGreg Clayton     if (exe_module_sp.get())
62f9765acdSGreg Clayton     {
63f9765acdSGreg Clayton         const llvm::Triple &triple_ref = target.GetArchitecture().GetTriple();
64f9765acdSGreg Clayton         if (triple_ref.getOS() == llvm::Triple::Darwin &&
65f9765acdSGreg Clayton             triple_ref.getVendor() == llvm::Triple::Apple)
66f9765acdSGreg Clayton         {
67f9765acdSGreg Clayton             ObjectFile *exe_objfile = exe_module_sp->GetObjectFile();
68f9765acdSGreg Clayton             if (exe_objfile->GetType() == ObjectFile::eTypeExecutable &&
69f9765acdSGreg Clayton                 exe_objfile->GetStrata() == ObjectFile::eStrataKernel)
70f9765acdSGreg Clayton                 return true;
71f9765acdSGreg Clayton         }
72f9765acdSGreg Clayton         return false;
73f9765acdSGreg Clayton     }
74*3a29bdbeSGreg Clayton     // No target executable, assume we can debug if our plug-in was specified by name
75*3a29bdbeSGreg Clayton     return plugin_specified_by_name;
76*3a29bdbeSGreg Clayton }
77f9765acdSGreg Clayton 
78f9765acdSGreg Clayton //----------------------------------------------------------------------
79f9765acdSGreg Clayton // ProcessKDP constructor
80f9765acdSGreg Clayton //----------------------------------------------------------------------
81f9765acdSGreg Clayton ProcessKDP::ProcessKDP(Target& target, Listener &listener) :
82f9765acdSGreg Clayton     Process (target, listener),
83f9765acdSGreg Clayton     m_comm("lldb.process.kdp-remote.communication"),
84f9765acdSGreg Clayton     m_async_broadcaster ("lldb.process.kdp-remote.async-broadcaster"),
85f9765acdSGreg Clayton     m_async_thread (LLDB_INVALID_HOST_THREAD)
86f9765acdSGreg Clayton {
87f9765acdSGreg Clayton //    m_async_broadcaster.SetEventName (eBroadcastBitAsyncThreadShouldExit,   "async thread should exit");
88f9765acdSGreg Clayton //    m_async_broadcaster.SetEventName (eBroadcastBitAsyncContinue,           "async thread continue");
89f9765acdSGreg Clayton }
90f9765acdSGreg Clayton 
91f9765acdSGreg Clayton //----------------------------------------------------------------------
92f9765acdSGreg Clayton // Destructor
93f9765acdSGreg Clayton //----------------------------------------------------------------------
94f9765acdSGreg Clayton ProcessKDP::~ProcessKDP()
95f9765acdSGreg Clayton {
96f9765acdSGreg Clayton     Clear();
97f9765acdSGreg Clayton }
98f9765acdSGreg Clayton 
99f9765acdSGreg Clayton //----------------------------------------------------------------------
100f9765acdSGreg Clayton // PluginInterface
101f9765acdSGreg Clayton //----------------------------------------------------------------------
102f9765acdSGreg Clayton const char *
103f9765acdSGreg Clayton ProcessKDP::GetPluginName()
104f9765acdSGreg Clayton {
105f9765acdSGreg Clayton     return "Process debugging plug-in that uses the Darwin KDP remote protocol";
106f9765acdSGreg Clayton }
107f9765acdSGreg Clayton 
108f9765acdSGreg Clayton const char *
109f9765acdSGreg Clayton ProcessKDP::GetShortPluginName()
110f9765acdSGreg Clayton {
111f9765acdSGreg Clayton     return GetPluginNameStatic();
112f9765acdSGreg Clayton }
113f9765acdSGreg Clayton 
114f9765acdSGreg Clayton uint32_t
115f9765acdSGreg Clayton ProcessKDP::GetPluginVersion()
116f9765acdSGreg Clayton {
117f9765acdSGreg Clayton     return 1;
118f9765acdSGreg Clayton }
119f9765acdSGreg Clayton 
120f9765acdSGreg Clayton Error
121f9765acdSGreg Clayton ProcessKDP::WillLaunch (Module* module)
122f9765acdSGreg Clayton {
123f9765acdSGreg Clayton     Error error;
124f9765acdSGreg Clayton     error.SetErrorString ("launching not supported in kdp-remote plug-in");
125f9765acdSGreg Clayton     return error;
126f9765acdSGreg Clayton }
127f9765acdSGreg Clayton 
128f9765acdSGreg Clayton Error
129f9765acdSGreg Clayton ProcessKDP::WillAttachToProcessWithID (lldb::pid_t pid)
130f9765acdSGreg Clayton {
131f9765acdSGreg Clayton     Error error;
132f9765acdSGreg Clayton     error.SetErrorString ("attaching to a by process ID not supported in kdp-remote plug-in");
133f9765acdSGreg Clayton     return error;
134f9765acdSGreg Clayton }
135f9765acdSGreg Clayton 
136f9765acdSGreg Clayton Error
137f9765acdSGreg Clayton ProcessKDP::WillAttachToProcessWithName (const char *process_name, bool wait_for_launch)
138f9765acdSGreg Clayton {
139f9765acdSGreg Clayton     Error error;
140f9765acdSGreg Clayton     error.SetErrorString ("attaching to a by process name not supported in kdp-remote plug-in");
141f9765acdSGreg Clayton     return error;
142f9765acdSGreg Clayton }
143f9765acdSGreg Clayton 
144f9765acdSGreg Clayton Error
145f9765acdSGreg Clayton ProcessKDP::DoConnectRemote (const char *remote_url)
146f9765acdSGreg Clayton {
147f9765acdSGreg Clayton     // TODO: fill in the remote connection to the remote KDP here!
148f9765acdSGreg Clayton     Error error;
149*3a29bdbeSGreg Clayton 
150*3a29bdbeSGreg Clayton     if (remote_url == NULL || remote_url[0] == '\0')
151*3a29bdbeSGreg Clayton         remote_url = "udp://localhost:41139";
152*3a29bdbeSGreg Clayton 
153*3a29bdbeSGreg Clayton     std::auto_ptr<ConnectionFileDescriptor> conn_ap(new ConnectionFileDescriptor());
154*3a29bdbeSGreg Clayton     if (conn_ap.get())
155*3a29bdbeSGreg Clayton     {
156*3a29bdbeSGreg Clayton         // Only try once for now.
157*3a29bdbeSGreg Clayton         // TODO: check if we should be retrying?
158*3a29bdbeSGreg Clayton         const uint32_t max_retry_count = 1;
159*3a29bdbeSGreg Clayton         for (uint32_t retry_count = 0; retry_count < max_retry_count; ++retry_count)
160*3a29bdbeSGreg Clayton         {
161*3a29bdbeSGreg Clayton             if (conn_ap->Connect(remote_url, &error) == eConnectionStatusSuccess)
162*3a29bdbeSGreg Clayton                 break;
163*3a29bdbeSGreg Clayton             usleep (100000);
164*3a29bdbeSGreg Clayton         }
165*3a29bdbeSGreg Clayton     }
166*3a29bdbeSGreg Clayton 
167*3a29bdbeSGreg Clayton     if (conn_ap->IsConnected())
168*3a29bdbeSGreg Clayton     {
169*3a29bdbeSGreg Clayton         const uint16_t reply_port = conn_ap->GetReadPort ();
170*3a29bdbeSGreg Clayton 
171*3a29bdbeSGreg Clayton         if (reply_port != 0)
172*3a29bdbeSGreg Clayton         {
173*3a29bdbeSGreg Clayton             m_comm.SetConnection(conn_ap.release());
174*3a29bdbeSGreg Clayton 
175*3a29bdbeSGreg Clayton             if (m_comm.SendRequestReattach(reply_port))
176*3a29bdbeSGreg Clayton             {
177*3a29bdbeSGreg Clayton                 if (m_comm.SendRequestConnect(reply_port, reply_port, "Greetings from LLDB..."))
178*3a29bdbeSGreg Clayton                 {
179*3a29bdbeSGreg Clayton                     m_comm.GetVersion();
180*3a29bdbeSGreg Clayton                     uint32_t cpu = m_comm.GetCPUType();
181*3a29bdbeSGreg Clayton                     uint32_t sub = m_comm.GetCPUSubtype();
182*3a29bdbeSGreg Clayton                     ArchSpec kernel_arch;
183*3a29bdbeSGreg Clayton                     kernel_arch.SetArchitecture(eArchTypeMachO, cpu, sub);
184*3a29bdbeSGreg Clayton                     m_target.SetArchitecture(kernel_arch);
185*3a29bdbeSGreg Clayton                     // TODO: thread registers based off of architecture...
186*3a29bdbeSGreg Clayton                 }
187*3a29bdbeSGreg Clayton             }
188*3a29bdbeSGreg Clayton             else
189*3a29bdbeSGreg Clayton             {
190*3a29bdbeSGreg Clayton                 error.SetErrorString("KDP reattach failed");
191*3a29bdbeSGreg Clayton             }
192*3a29bdbeSGreg Clayton         }
193*3a29bdbeSGreg Clayton         else
194*3a29bdbeSGreg Clayton         {
195*3a29bdbeSGreg Clayton             error.SetErrorString("invalid reply port from UDP connection");
196*3a29bdbeSGreg Clayton         }
197*3a29bdbeSGreg Clayton     }
198*3a29bdbeSGreg Clayton     else
199*3a29bdbeSGreg Clayton     {
200*3a29bdbeSGreg Clayton         if (error.Success())
201*3a29bdbeSGreg Clayton             error.SetErrorStringWithFormat ("failed to connect to '%s'", remote_url);
202*3a29bdbeSGreg Clayton     }
203*3a29bdbeSGreg Clayton     if (error.Fail())
204*3a29bdbeSGreg Clayton         m_comm.Disconnect();
205*3a29bdbeSGreg Clayton 
206f9765acdSGreg Clayton     return error;
207f9765acdSGreg Clayton }
208f9765acdSGreg Clayton 
209f9765acdSGreg Clayton //----------------------------------------------------------------------
210f9765acdSGreg Clayton // Process Control
211f9765acdSGreg Clayton //----------------------------------------------------------------------
212f9765acdSGreg Clayton Error
213f9765acdSGreg Clayton ProcessKDP::DoLaunch (Module* module,
214f9765acdSGreg Clayton                       char const *argv[],
215f9765acdSGreg Clayton                       char const *envp[],
216f9765acdSGreg Clayton                       uint32_t launch_flags,
217f9765acdSGreg Clayton                       const char *stdin_path,
218f9765acdSGreg Clayton                       const char *stdout_path,
219f9765acdSGreg Clayton                       const char *stderr_path,
220f9765acdSGreg Clayton                       const char *working_dir)
221f9765acdSGreg Clayton {
222f9765acdSGreg Clayton     Error error;
223f9765acdSGreg Clayton     error.SetErrorString ("launching not supported in kdp-remote plug-in");
224f9765acdSGreg Clayton     return error;
225f9765acdSGreg Clayton }
226f9765acdSGreg Clayton 
227f9765acdSGreg Clayton 
228f9765acdSGreg Clayton Error
229f9765acdSGreg Clayton ProcessKDP::DoAttachToProcessWithID (lldb::pid_t attach_pid)
230f9765acdSGreg Clayton {
231f9765acdSGreg Clayton     Error error;
232f9765acdSGreg Clayton     error.SetErrorString ("attach to process by ID is not suppported in kdp remote debugging");
233f9765acdSGreg Clayton     return error;
234f9765acdSGreg Clayton }
235f9765acdSGreg Clayton 
236f9765acdSGreg Clayton size_t
237f9765acdSGreg Clayton ProcessKDP::AttachInputReaderCallback (void *baton,
238f9765acdSGreg Clayton                                        InputReader *reader,
239f9765acdSGreg Clayton                                        lldb::InputReaderAction notification,
240f9765acdSGreg Clayton                                        const char *bytes,
241f9765acdSGreg Clayton                                        size_t bytes_len)
242f9765acdSGreg Clayton {
243f9765acdSGreg Clayton     if (notification == eInputReaderGotToken)
244f9765acdSGreg Clayton     {
245f9765acdSGreg Clayton //        ProcessKDP *process = (ProcessKDP *)baton;
246f9765acdSGreg Clayton //        if (process->m_waiting_for_attach)
247f9765acdSGreg Clayton //            process->m_waiting_for_attach = false;
248f9765acdSGreg Clayton         reader->SetIsDone(true);
249f9765acdSGreg Clayton         return 1;
250f9765acdSGreg Clayton     }
251f9765acdSGreg Clayton     return 0;
252f9765acdSGreg Clayton }
253f9765acdSGreg Clayton 
254f9765acdSGreg Clayton Error
255f9765acdSGreg Clayton ProcessKDP::DoAttachToProcessWithName (const char *process_name, bool wait_for_launch)
256f9765acdSGreg Clayton {
257f9765acdSGreg Clayton     Error error;
258f9765acdSGreg Clayton     error.SetErrorString ("attach to process by name is not suppported in kdp remote debugging");
259f9765acdSGreg Clayton     return error;
260f9765acdSGreg Clayton }
261f9765acdSGreg Clayton 
262f9765acdSGreg Clayton 
263f9765acdSGreg Clayton void
264f9765acdSGreg Clayton ProcessKDP::DidAttach ()
265f9765acdSGreg Clayton {
266f9765acdSGreg Clayton     LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_PROCESS));
267f9765acdSGreg Clayton     if (log)
268f9765acdSGreg Clayton         log->Printf ("ProcessKDP::DidLaunch()");
269f9765acdSGreg Clayton     if (GetID() != LLDB_INVALID_PROCESS_ID)
270f9765acdSGreg Clayton     {
271f9765acdSGreg Clayton         // TODO: figure out the register context that we will use
272f9765acdSGreg Clayton     }
273f9765acdSGreg Clayton }
274f9765acdSGreg Clayton 
275f9765acdSGreg Clayton Error
276f9765acdSGreg Clayton ProcessKDP::WillResume ()
277f9765acdSGreg Clayton {
278f9765acdSGreg Clayton     return Error();
279f9765acdSGreg Clayton }
280f9765acdSGreg Clayton 
281f9765acdSGreg Clayton Error
282f9765acdSGreg Clayton ProcessKDP::DoResume ()
283f9765acdSGreg Clayton {
284f9765acdSGreg Clayton     Error error;
285f9765acdSGreg Clayton     error.SetErrorString ("ProcessKDP::DoResume () is not implemented yet");
286f9765acdSGreg Clayton     return error;
287f9765acdSGreg Clayton }
288f9765acdSGreg Clayton 
289f9765acdSGreg Clayton uint32_t
290f9765acdSGreg Clayton ProcessKDP::UpdateThreadListIfNeeded ()
291f9765acdSGreg Clayton {
292f9765acdSGreg Clayton     // locker will keep a mutex locked until it goes out of scope
293f9765acdSGreg Clayton     LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_THREAD));
294f9765acdSGreg Clayton     if (log && log->GetMask().Test(KDP_LOG_VERBOSE))
295f9765acdSGreg Clayton         log->Printf ("ProcessKDP::%s (pid = %i)", __FUNCTION__, GetID());
296f9765acdSGreg Clayton 
297f9765acdSGreg Clayton     Mutex::Locker locker (m_thread_list.GetMutex ());
298f9765acdSGreg Clayton     // TODO: get the thread list here!
299f9765acdSGreg Clayton     const uint32_t stop_id = GetStopID();
300f9765acdSGreg Clayton     if (m_thread_list.GetSize(false) == 0 || stop_id != m_thread_list.GetStopID())
301f9765acdSGreg Clayton     {
302f9765acdSGreg Clayton         // Update the thread list's stop id immediately so we don't recurse into this function.
303f9765acdSGreg Clayton //        ThreadList curr_thread_list (this);
304f9765acdSGreg Clayton //        curr_thread_list.SetStopID(stop_id);
305f9765acdSGreg Clayton //
306f9765acdSGreg Clayton //        std::vector<lldb::tid_t> thread_ids;
307f9765acdSGreg Clayton //        bool sequence_mutex_unavailable = false;
308f9765acdSGreg Clayton //        const size_t num_thread_ids = m_comm.GetCurrentThreadIDs (thread_ids, sequence_mutex_unavailable);
309f9765acdSGreg Clayton //        if (num_thread_ids > 0)
310f9765acdSGreg Clayton //        {
311f9765acdSGreg Clayton //            for (size_t i=0; i<num_thread_ids; ++i)
312f9765acdSGreg Clayton //            {
313f9765acdSGreg Clayton //                tid_t tid = thread_ids[i];
314f9765acdSGreg Clayton //                ThreadSP thread_sp (GetThreadList().FindThreadByID (tid, false));
315f9765acdSGreg Clayton //                if (!thread_sp)
316f9765acdSGreg Clayton //                    thread_sp.reset (new ThreadGDBRemote (*this, tid));
317f9765acdSGreg Clayton //                curr_thread_list.AddThread(thread_sp);
318f9765acdSGreg Clayton //            }
319f9765acdSGreg Clayton //        }
320f9765acdSGreg Clayton //
321f9765acdSGreg Clayton //        if (sequence_mutex_unavailable == false)
322f9765acdSGreg Clayton //        {
323f9765acdSGreg Clayton //            m_thread_list = curr_thread_list;
324f9765acdSGreg Clayton //            SetThreadStopInfo (m_last_stop_packet);
325f9765acdSGreg Clayton //        }
326f9765acdSGreg Clayton     }
327f9765acdSGreg Clayton     return GetThreadList().GetSize(false);
328f9765acdSGreg Clayton }
329f9765acdSGreg Clayton 
330f9765acdSGreg Clayton 
331f9765acdSGreg Clayton StateType
332f9765acdSGreg Clayton ProcessKDP::SetThreadStopInfo (StringExtractor& stop_packet)
333f9765acdSGreg Clayton {
334f9765acdSGreg Clayton     // TODO: figure out why we stopped given the packet that tells us we stopped...
335f9765acdSGreg Clayton     return eStateStopped;
336f9765acdSGreg Clayton }
337f9765acdSGreg Clayton 
338f9765acdSGreg Clayton void
339f9765acdSGreg Clayton ProcessKDP::RefreshStateAfterStop ()
340f9765acdSGreg Clayton {
341f9765acdSGreg Clayton     // Let all threads recover from stopping and do any clean up based
342f9765acdSGreg Clayton     // on the previous thread state (if any).
343f9765acdSGreg Clayton     m_thread_list.RefreshStateAfterStop();
344f9765acdSGreg Clayton     //SetThreadStopInfo (m_last_stop_packet);
345f9765acdSGreg Clayton }
346f9765acdSGreg Clayton 
347f9765acdSGreg Clayton Error
348f9765acdSGreg Clayton ProcessKDP::DoHalt (bool &caused_stop)
349f9765acdSGreg Clayton {
350f9765acdSGreg Clayton     Error error;
351f9765acdSGreg Clayton 
352f9765acdSGreg Clayton //    bool timed_out = false;
353f9765acdSGreg Clayton     Mutex::Locker locker;
354f9765acdSGreg Clayton 
355f9765acdSGreg Clayton     if (m_public_state.GetValue() == eStateAttaching)
356f9765acdSGreg Clayton     {
357f9765acdSGreg Clayton         // We are being asked to halt during an attach. We need to just close
358f9765acdSGreg Clayton         // our file handle and debugserver will go away, and we can be done...
359f9765acdSGreg Clayton         m_comm.Disconnect();
360f9765acdSGreg Clayton     }
361f9765acdSGreg Clayton     else
362f9765acdSGreg Clayton     {
363f9765acdSGreg Clayton         // TODO: add the ability to halt a running kernel
364f9765acdSGreg Clayton         error.SetErrorString ("halt not supported in kdp-remote plug-in");
365f9765acdSGreg Clayton //        if (!m_comm.SendInterrupt (locker, 2, caused_stop, timed_out))
366f9765acdSGreg Clayton //        {
367f9765acdSGreg Clayton //            if (timed_out)
368f9765acdSGreg Clayton //                error.SetErrorString("timed out sending interrupt packet");
369f9765acdSGreg Clayton //            else
370f9765acdSGreg Clayton //                error.SetErrorString("unknown error sending interrupt packet");
371f9765acdSGreg Clayton //        }
372f9765acdSGreg Clayton     }
373f9765acdSGreg Clayton     return error;
374f9765acdSGreg Clayton }
375f9765acdSGreg Clayton 
376f9765acdSGreg Clayton Error
377f9765acdSGreg Clayton ProcessKDP::InterruptIfRunning (bool discard_thread_plans,
378f9765acdSGreg Clayton                                 bool catch_stop_event,
379f9765acdSGreg Clayton                                 EventSP &stop_event_sp)
380f9765acdSGreg Clayton {
381f9765acdSGreg Clayton     Error error;
382f9765acdSGreg Clayton 
383f9765acdSGreg Clayton     LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS));
384f9765acdSGreg Clayton 
385f9765acdSGreg Clayton     bool paused_private_state_thread = false;
386f9765acdSGreg Clayton     const bool is_running = m_comm.IsRunning();
387f9765acdSGreg Clayton     if (log)
388f9765acdSGreg Clayton         log->Printf ("ProcessKDP::InterruptIfRunning(discard_thread_plans=%i, catch_stop_event=%i) is_running=%i",
389f9765acdSGreg Clayton                      discard_thread_plans,
390f9765acdSGreg Clayton                      catch_stop_event,
391f9765acdSGreg Clayton                      is_running);
392f9765acdSGreg Clayton 
393f9765acdSGreg Clayton     if (discard_thread_plans)
394f9765acdSGreg Clayton     {
395f9765acdSGreg Clayton         if (log)
396f9765acdSGreg Clayton             log->Printf ("ProcessKDP::InterruptIfRunning() discarding all thread plans");
397f9765acdSGreg Clayton         m_thread_list.DiscardThreadPlans();
398f9765acdSGreg Clayton     }
399f9765acdSGreg Clayton     if (is_running)
400f9765acdSGreg Clayton     {
401f9765acdSGreg Clayton         if (catch_stop_event)
402f9765acdSGreg Clayton         {
403f9765acdSGreg Clayton             if (log)
404f9765acdSGreg Clayton                 log->Printf ("ProcessKDP::InterruptIfRunning() pausing private state thread");
405f9765acdSGreg Clayton             PausePrivateStateThread();
406f9765acdSGreg Clayton             paused_private_state_thread = true;
407f9765acdSGreg Clayton         }
408f9765acdSGreg Clayton 
409f9765acdSGreg Clayton         bool timed_out = false;
410f9765acdSGreg Clayton //        bool sent_interrupt = false;
411f9765acdSGreg Clayton         Mutex::Locker locker;
412f9765acdSGreg Clayton 
413f9765acdSGreg Clayton         // TODO: implement halt in CommunicationKDP
414f9765acdSGreg Clayton //        if (!m_comm.SendInterrupt (locker, 1, sent_interrupt, timed_out))
415f9765acdSGreg Clayton //        {
416f9765acdSGreg Clayton //            if (timed_out)
417f9765acdSGreg Clayton //                error.SetErrorString("timed out sending interrupt packet");
418f9765acdSGreg Clayton //            else
419f9765acdSGreg Clayton //                error.SetErrorString("unknown error sending interrupt packet");
420f9765acdSGreg Clayton //            if (paused_private_state_thread)
421f9765acdSGreg Clayton //                ResumePrivateStateThread();
422f9765acdSGreg Clayton //            return error;
423f9765acdSGreg Clayton //        }
424f9765acdSGreg Clayton 
425f9765acdSGreg Clayton         if (catch_stop_event)
426f9765acdSGreg Clayton         {
427f9765acdSGreg Clayton             // LISTEN HERE
428f9765acdSGreg Clayton             TimeValue timeout_time;
429f9765acdSGreg Clayton             timeout_time = TimeValue::Now();
430f9765acdSGreg Clayton             timeout_time.OffsetWithSeconds(5);
431f9765acdSGreg Clayton             StateType state = WaitForStateChangedEventsPrivate (&timeout_time, stop_event_sp);
432f9765acdSGreg Clayton 
433f9765acdSGreg Clayton             timed_out = state == eStateInvalid;
434f9765acdSGreg Clayton             if (log)
435f9765acdSGreg Clayton                 log->Printf ("ProcessKDP::InterruptIfRunning() catch stop event: state = %s, timed-out=%i", StateAsCString(state), timed_out);
436f9765acdSGreg Clayton 
437f9765acdSGreg Clayton             if (timed_out)
438f9765acdSGreg Clayton                 error.SetErrorString("unable to verify target stopped");
439f9765acdSGreg Clayton         }
440f9765acdSGreg Clayton 
441f9765acdSGreg Clayton         if (paused_private_state_thread)
442f9765acdSGreg Clayton         {
443f9765acdSGreg Clayton             if (log)
444f9765acdSGreg Clayton                 log->Printf ("ProcessKDP::InterruptIfRunning() resuming private state thread");
445f9765acdSGreg Clayton             ResumePrivateStateThread();
446f9765acdSGreg Clayton         }
447f9765acdSGreg Clayton     }
448f9765acdSGreg Clayton     return error;
449f9765acdSGreg Clayton }
450f9765acdSGreg Clayton 
451f9765acdSGreg Clayton Error
452f9765acdSGreg Clayton ProcessKDP::WillDetach ()
453f9765acdSGreg Clayton {
454f9765acdSGreg Clayton     LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS));
455f9765acdSGreg Clayton     if (log)
456f9765acdSGreg Clayton         log->Printf ("ProcessKDP::WillDetach()");
457f9765acdSGreg Clayton 
458f9765acdSGreg Clayton     bool discard_thread_plans = true;
459f9765acdSGreg Clayton     bool catch_stop_event = true;
460f9765acdSGreg Clayton     EventSP event_sp;
461f9765acdSGreg Clayton     return InterruptIfRunning (discard_thread_plans, catch_stop_event, event_sp);
462f9765acdSGreg Clayton }
463f9765acdSGreg Clayton 
464f9765acdSGreg Clayton Error
465f9765acdSGreg Clayton ProcessKDP::DoDetach()
466f9765acdSGreg Clayton {
467f9765acdSGreg Clayton     Error error;
468f9765acdSGreg Clayton     LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS));
469f9765acdSGreg Clayton     if (log)
470f9765acdSGreg Clayton         log->Printf ("ProcessKDP::DoDetach()");
471f9765acdSGreg Clayton 
472f9765acdSGreg Clayton     DisableAllBreakpointSites ();
473f9765acdSGreg Clayton 
474f9765acdSGreg Clayton     m_thread_list.DiscardThreadPlans();
475f9765acdSGreg Clayton 
476*3a29bdbeSGreg Clayton     if (m_comm.IsConnected())
477*3a29bdbeSGreg Clayton     {
478*3a29bdbeSGreg Clayton 
479*3a29bdbeSGreg Clayton         m_comm.SendRequestDisconnect();
480*3a29bdbeSGreg Clayton 
48157508026SGreg Clayton         size_t response_size = m_comm.Disconnect ();
482f9765acdSGreg Clayton         if (log)
483f9765acdSGreg Clayton         {
484f9765acdSGreg Clayton             if (response_size)
485f9765acdSGreg Clayton                 log->PutCString ("ProcessKDP::DoDetach() detach packet sent successfully");
486f9765acdSGreg Clayton             else
487f9765acdSGreg Clayton                 log->PutCString ("ProcessKDP::DoDetach() detach packet send failed");
488f9765acdSGreg Clayton         }
489*3a29bdbeSGreg Clayton     }
490f9765acdSGreg Clayton     // Sleep for one second to let the process get all detached...
491f9765acdSGreg Clayton     StopAsyncThread ();
492f9765acdSGreg Clayton 
493f9765acdSGreg Clayton     m_comm.StopReadThread();
494f9765acdSGreg Clayton     m_comm.Disconnect();    // Disconnect from the debug server.
495f9765acdSGreg Clayton 
496f9765acdSGreg Clayton     SetPrivateState (eStateDetached);
497f9765acdSGreg Clayton     ResumePrivateStateThread();
498f9765acdSGreg Clayton 
499f9765acdSGreg Clayton     //KillDebugserverProcess ();
500f9765acdSGreg Clayton     return error;
501f9765acdSGreg Clayton }
502f9765acdSGreg Clayton 
503f9765acdSGreg Clayton Error
504f9765acdSGreg Clayton ProcessKDP::DoDestroy ()
505f9765acdSGreg Clayton {
506f9765acdSGreg Clayton     Error error;
507f9765acdSGreg Clayton     LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS));
508f9765acdSGreg Clayton     if (log)
509f9765acdSGreg Clayton         log->Printf ("ProcessKDP::DoDestroy()");
510f9765acdSGreg Clayton 
511f9765acdSGreg Clayton     // Interrupt if our inferior is running...
512f9765acdSGreg Clayton     if (m_comm.IsConnected())
513f9765acdSGreg Clayton     {
514*3a29bdbeSGreg Clayton         m_comm.SendRequestDisconnect();
515*3a29bdbeSGreg Clayton 
516f9765acdSGreg Clayton         if (m_public_state.GetValue() == eStateAttaching)
517f9765acdSGreg Clayton         {
518f9765acdSGreg Clayton             // We are being asked to halt during an attach. We need to just close
519f9765acdSGreg Clayton             // our file handle and debugserver will go away, and we can be done...
520f9765acdSGreg Clayton             m_comm.Disconnect();
521f9765acdSGreg Clayton         }
522f9765acdSGreg Clayton         else
523f9765acdSGreg Clayton         {
524f9765acdSGreg Clayton 
525f9765acdSGreg Clayton             StringExtractor response;
526f9765acdSGreg Clayton             // TODO: Send kill packet?
527f9765acdSGreg Clayton             SetExitStatus(SIGABRT, NULL);
528f9765acdSGreg Clayton         }
529f9765acdSGreg Clayton     }
530f9765acdSGreg Clayton     StopAsyncThread ();
531f9765acdSGreg Clayton     m_comm.StopReadThread();
532f9765acdSGreg Clayton     m_comm.Disconnect();    // Disconnect from the debug server.
533f9765acdSGreg Clayton     return error;
534f9765acdSGreg Clayton }
535f9765acdSGreg Clayton 
536f9765acdSGreg Clayton //------------------------------------------------------------------
537f9765acdSGreg Clayton // Process Queries
538f9765acdSGreg Clayton //------------------------------------------------------------------
539f9765acdSGreg Clayton 
540f9765acdSGreg Clayton bool
541f9765acdSGreg Clayton ProcessKDP::IsAlive ()
542f9765acdSGreg Clayton {
543f9765acdSGreg Clayton     return m_comm.IsConnected() && m_private_state.GetValue() != eStateExited;
544f9765acdSGreg Clayton }
545f9765acdSGreg Clayton 
546f9765acdSGreg Clayton //------------------------------------------------------------------
547f9765acdSGreg Clayton // Process Memory
548f9765acdSGreg Clayton //------------------------------------------------------------------
549f9765acdSGreg Clayton size_t
550f9765acdSGreg Clayton ProcessKDP::DoReadMemory (addr_t addr, void *buf, size_t size, Error &error)
551f9765acdSGreg Clayton {
552f9765acdSGreg Clayton     error.SetErrorString ("ProcessKDP::DoReadMemory not implemented");
553f9765acdSGreg Clayton     return 0;
554f9765acdSGreg Clayton }
555f9765acdSGreg Clayton 
556f9765acdSGreg Clayton size_t
557f9765acdSGreg Clayton ProcessKDP::DoWriteMemory (addr_t addr, const void *buf, size_t size, Error &error)
558f9765acdSGreg Clayton {
559f9765acdSGreg Clayton     error.SetErrorString ("ProcessKDP::DoReadMemory not implemented");
560f9765acdSGreg Clayton     return 0;
561f9765acdSGreg Clayton }
562f9765acdSGreg Clayton 
563f9765acdSGreg Clayton lldb::addr_t
564f9765acdSGreg Clayton ProcessKDP::DoAllocateMemory (size_t size, uint32_t permissions, Error &error)
565f9765acdSGreg Clayton {
566f9765acdSGreg Clayton     error.SetErrorString ("memory allocation not suppported in kdp remote debugging");
567f9765acdSGreg Clayton     return LLDB_INVALID_ADDRESS;
568f9765acdSGreg Clayton }
569f9765acdSGreg Clayton 
570f9765acdSGreg Clayton Error
571f9765acdSGreg Clayton ProcessKDP::DoDeallocateMemory (lldb::addr_t addr)
572f9765acdSGreg Clayton {
573f9765acdSGreg Clayton     Error error;
574f9765acdSGreg Clayton     error.SetErrorString ("memory deallocation not suppported in kdp remote debugging");
575f9765acdSGreg Clayton     return error;
576f9765acdSGreg Clayton }
577f9765acdSGreg Clayton 
578f9765acdSGreg Clayton Error
579f9765acdSGreg Clayton ProcessKDP::EnableBreakpoint (BreakpointSite *bp_site)
580f9765acdSGreg Clayton {
581f9765acdSGreg Clayton     return EnableSoftwareBreakpoint (bp_site);
582f9765acdSGreg Clayton }
583f9765acdSGreg Clayton 
584f9765acdSGreg Clayton Error
585f9765acdSGreg Clayton ProcessKDP::DisableBreakpoint (BreakpointSite *bp_site)
586f9765acdSGreg Clayton {
587f9765acdSGreg Clayton     return DisableSoftwareBreakpoint (bp_site);
588f9765acdSGreg Clayton }
589f9765acdSGreg Clayton 
590f9765acdSGreg Clayton Error
591f9765acdSGreg Clayton ProcessKDP::EnableWatchpoint (WatchpointLocation *wp)
592f9765acdSGreg Clayton {
593f9765acdSGreg Clayton     Error error;
594f9765acdSGreg Clayton     error.SetErrorString ("watchpoints are not suppported in kdp remote debugging");
595f9765acdSGreg Clayton     return error;
596f9765acdSGreg Clayton }
597f9765acdSGreg Clayton 
598f9765acdSGreg Clayton Error
599f9765acdSGreg Clayton ProcessKDP::DisableWatchpoint (WatchpointLocation *wp)
600f9765acdSGreg Clayton {
601f9765acdSGreg Clayton     Error error;
602f9765acdSGreg Clayton     error.SetErrorString ("watchpoints are not suppported in kdp remote debugging");
603f9765acdSGreg Clayton     return error;
604f9765acdSGreg Clayton }
605f9765acdSGreg Clayton 
606f9765acdSGreg Clayton void
607f9765acdSGreg Clayton ProcessKDP::Clear()
608f9765acdSGreg Clayton {
609f9765acdSGreg Clayton     Mutex::Locker locker (m_thread_list.GetMutex ());
610f9765acdSGreg Clayton     m_thread_list.Clear();
611f9765acdSGreg Clayton }
612f9765acdSGreg Clayton 
613f9765acdSGreg Clayton Error
614f9765acdSGreg Clayton ProcessKDP::DoSignal (int signo)
615f9765acdSGreg Clayton {
616f9765acdSGreg Clayton     Error error;
617f9765acdSGreg Clayton     error.SetErrorString ("sending signals is not suppported in kdp remote debugging");
618f9765acdSGreg Clayton     return error;
619f9765acdSGreg Clayton }
620f9765acdSGreg Clayton 
621f9765acdSGreg Clayton void
622f9765acdSGreg Clayton ProcessKDP::Initialize()
623f9765acdSGreg Clayton {
624f9765acdSGreg Clayton     static bool g_initialized = false;
625f9765acdSGreg Clayton 
626f9765acdSGreg Clayton     if (g_initialized == false)
627f9765acdSGreg Clayton     {
628f9765acdSGreg Clayton         g_initialized = true;
629f9765acdSGreg Clayton         PluginManager::RegisterPlugin (GetPluginNameStatic(),
630f9765acdSGreg Clayton                                        GetPluginDescriptionStatic(),
631f9765acdSGreg Clayton                                        CreateInstance);
632f9765acdSGreg Clayton 
633f9765acdSGreg Clayton         Log::Callbacks log_callbacks = {
634f9765acdSGreg Clayton             ProcessKDPLog::DisableLog,
635f9765acdSGreg Clayton             ProcessKDPLog::EnableLog,
636f9765acdSGreg Clayton             ProcessKDPLog::ListLogCategories
637f9765acdSGreg Clayton         };
638f9765acdSGreg Clayton 
639f9765acdSGreg Clayton         Log::RegisterLogChannel (ProcessKDP::GetPluginNameStatic(), log_callbacks);
640f9765acdSGreg Clayton     }
641f9765acdSGreg Clayton }
642f9765acdSGreg Clayton 
643f9765acdSGreg Clayton bool
644f9765acdSGreg Clayton ProcessKDP::StartAsyncThread ()
645f9765acdSGreg Clayton {
646f9765acdSGreg Clayton     LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS));
647f9765acdSGreg Clayton 
648f9765acdSGreg Clayton     if (log)
649f9765acdSGreg Clayton         log->Printf ("ProcessKDP::%s ()", __FUNCTION__);
650f9765acdSGreg Clayton 
651f9765acdSGreg Clayton     // Create a thread that watches our internal state and controls which
652f9765acdSGreg Clayton     // events make it to clients (into the DCProcess event queue).
653f9765acdSGreg Clayton     m_async_thread = Host::ThreadCreate ("<lldb.process.kdp-remote.async>", ProcessKDP::AsyncThread, this, NULL);
654f9765acdSGreg Clayton     return IS_VALID_LLDB_HOST_THREAD(m_async_thread);
655f9765acdSGreg Clayton }
656f9765acdSGreg Clayton 
657f9765acdSGreg Clayton void
658f9765acdSGreg Clayton ProcessKDP::StopAsyncThread ()
659f9765acdSGreg Clayton {
660f9765acdSGreg Clayton     LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS));
661f9765acdSGreg Clayton 
662f9765acdSGreg Clayton     if (log)
663f9765acdSGreg Clayton         log->Printf ("ProcessKDP::%s ()", __FUNCTION__);
664f9765acdSGreg Clayton 
665f9765acdSGreg Clayton     m_async_broadcaster.BroadcastEvent (eBroadcastBitAsyncThreadShouldExit);
666f9765acdSGreg Clayton 
667f9765acdSGreg Clayton     // Stop the stdio thread
668f9765acdSGreg Clayton     if (IS_VALID_LLDB_HOST_THREAD(m_async_thread))
669f9765acdSGreg Clayton     {
670f9765acdSGreg Clayton         Host::ThreadJoin (m_async_thread, NULL, NULL);
671f9765acdSGreg Clayton     }
672f9765acdSGreg Clayton }
673f9765acdSGreg Clayton 
674f9765acdSGreg Clayton 
675f9765acdSGreg Clayton void *
676f9765acdSGreg Clayton ProcessKDP::AsyncThread (void *arg)
677f9765acdSGreg Clayton {
678f9765acdSGreg Clayton     ProcessKDP *process = (ProcessKDP*) arg;
679f9765acdSGreg Clayton 
680f9765acdSGreg Clayton     LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_PROCESS));
681f9765acdSGreg Clayton     if (log)
682f9765acdSGreg Clayton         log->Printf ("ProcessKDP::%s (arg = %p, pid = %i) thread starting...", __FUNCTION__, arg, process->GetID());
683f9765acdSGreg Clayton 
684f9765acdSGreg Clayton     Listener listener ("ProcessKDP::AsyncThread");
685f9765acdSGreg Clayton     EventSP event_sp;
686f9765acdSGreg Clayton     const uint32_t desired_event_mask = eBroadcastBitAsyncContinue |
687f9765acdSGreg Clayton                                         eBroadcastBitAsyncThreadShouldExit;
688f9765acdSGreg Clayton 
689f9765acdSGreg Clayton     if (listener.StartListeningForEvents (&process->m_async_broadcaster, desired_event_mask) == desired_event_mask)
690f9765acdSGreg Clayton     {
691f9765acdSGreg Clayton         listener.StartListeningForEvents (&process->m_comm, Communication::eBroadcastBitReadThreadDidExit);
692f9765acdSGreg Clayton 
693f9765acdSGreg Clayton         bool done = false;
694f9765acdSGreg Clayton         while (!done)
695f9765acdSGreg Clayton         {
696f9765acdSGreg Clayton             if (log)
697f9765acdSGreg Clayton                 log->Printf ("ProcessKDP::%s (arg = %p, pid = %i) listener.WaitForEvent (NULL, event_sp)...", __FUNCTION__, arg, process->GetID());
698f9765acdSGreg Clayton             if (listener.WaitForEvent (NULL, event_sp))
699f9765acdSGreg Clayton             {
700f9765acdSGreg Clayton                 const uint32_t event_type = event_sp->GetType();
701f9765acdSGreg Clayton                 if (event_sp->BroadcasterIs (&process->m_async_broadcaster))
702f9765acdSGreg Clayton                 {
703f9765acdSGreg Clayton                     if (log)
704f9765acdSGreg Clayton                         log->Printf ("ProcessKDP::%s (arg = %p, pid = %i) Got an event of type: %d...", __FUNCTION__, arg, process->GetID(), event_type);
705f9765acdSGreg Clayton 
706f9765acdSGreg Clayton                     switch (event_type)
707f9765acdSGreg Clayton                     {
708f9765acdSGreg Clayton                         case eBroadcastBitAsyncContinue:
709f9765acdSGreg Clayton                         {
710f9765acdSGreg Clayton                             const EventDataBytes *continue_packet = EventDataBytes::GetEventDataFromEvent(event_sp.get());
711f9765acdSGreg Clayton 
712f9765acdSGreg Clayton                             if (continue_packet)
713f9765acdSGreg Clayton                             {
714f9765acdSGreg Clayton                                 // TODO: do continue support here
715f9765acdSGreg Clayton 
716f9765acdSGreg Clayton //                                const char *continue_cstr = (const char *)continue_packet->GetBytes ();
717f9765acdSGreg Clayton //                                const size_t continue_cstr_len = continue_packet->GetByteSize ();
718f9765acdSGreg Clayton //                                if (log)
719f9765acdSGreg Clayton //                                    log->Printf ("ProcessKDP::%s (arg = %p, pid = %i) got eBroadcastBitAsyncContinue: %s", __FUNCTION__, arg, process->GetID(), continue_cstr);
720f9765acdSGreg Clayton //
721f9765acdSGreg Clayton //                                if (::strstr (continue_cstr, "vAttach") == NULL)
722f9765acdSGreg Clayton //                                    process->SetPrivateState(eStateRunning);
723f9765acdSGreg Clayton //                                StringExtractor response;
724f9765acdSGreg Clayton //                                StateType stop_state = process->GetCommunication().SendContinuePacketAndWaitForResponse (process, continue_cstr, continue_cstr_len, response);
725f9765acdSGreg Clayton //
726f9765acdSGreg Clayton //                                switch (stop_state)
727f9765acdSGreg Clayton //                                {
728f9765acdSGreg Clayton //                                    case eStateStopped:
729f9765acdSGreg Clayton //                                    case eStateCrashed:
730f9765acdSGreg Clayton //                                    case eStateSuspended:
731f9765acdSGreg Clayton //                                        process->m_last_stop_packet = response;
732f9765acdSGreg Clayton //                                        process->SetPrivateState (stop_state);
733f9765acdSGreg Clayton //                                        break;
734f9765acdSGreg Clayton //
735f9765acdSGreg Clayton //                                    case eStateExited:
736f9765acdSGreg Clayton //                                        process->m_last_stop_packet = response;
737f9765acdSGreg Clayton //                                        response.SetFilePos(1);
738f9765acdSGreg Clayton //                                        process->SetExitStatus(response.GetHexU8(), NULL);
739f9765acdSGreg Clayton //                                        done = true;
740f9765acdSGreg Clayton //                                        break;
741f9765acdSGreg Clayton //
742f9765acdSGreg Clayton //                                    case eStateInvalid:
743f9765acdSGreg Clayton //                                        process->SetExitStatus(-1, "lost connection");
744f9765acdSGreg Clayton //                                        break;
745f9765acdSGreg Clayton //
746f9765acdSGreg Clayton //                                    default:
747f9765acdSGreg Clayton //                                        process->SetPrivateState (stop_state);
748f9765acdSGreg Clayton //                                        break;
749f9765acdSGreg Clayton //                                }
750f9765acdSGreg Clayton                             }
751f9765acdSGreg Clayton                         }
752f9765acdSGreg Clayton                             break;
753f9765acdSGreg Clayton 
754f9765acdSGreg Clayton                         case eBroadcastBitAsyncThreadShouldExit:
755f9765acdSGreg Clayton                             if (log)
756f9765acdSGreg Clayton                                 log->Printf ("ProcessKDP::%s (arg = %p, pid = %i) got eBroadcastBitAsyncThreadShouldExit...", __FUNCTION__, arg, process->GetID());
757f9765acdSGreg Clayton                             done = true;
758f9765acdSGreg Clayton                             break;
759f9765acdSGreg Clayton 
760f9765acdSGreg Clayton                         default:
761f9765acdSGreg Clayton                             if (log)
762f9765acdSGreg Clayton                                 log->Printf ("ProcessKDP::%s (arg = %p, pid = %i) got unknown event 0x%8.8x", __FUNCTION__, arg, process->GetID(), event_type);
763f9765acdSGreg Clayton                             done = true;
764f9765acdSGreg Clayton                             break;
765f9765acdSGreg Clayton                     }
766f9765acdSGreg Clayton                 }
767f9765acdSGreg Clayton                 else if (event_sp->BroadcasterIs (&process->m_comm))
768f9765acdSGreg Clayton                 {
769f9765acdSGreg Clayton                     if (event_type & Communication::eBroadcastBitReadThreadDidExit)
770f9765acdSGreg Clayton                     {
771f9765acdSGreg Clayton                         process->SetExitStatus (-1, "lost connection");
772f9765acdSGreg Clayton                         done = true;
773f9765acdSGreg Clayton                     }
774f9765acdSGreg Clayton                 }
775f9765acdSGreg Clayton             }
776f9765acdSGreg Clayton             else
777f9765acdSGreg Clayton             {
778f9765acdSGreg Clayton                 if (log)
779f9765acdSGreg Clayton                     log->Printf ("ProcessKDP::%s (arg = %p, pid = %i) listener.WaitForEvent (NULL, event_sp) => false", __FUNCTION__, arg, process->GetID());
780f9765acdSGreg Clayton                 done = true;
781f9765acdSGreg Clayton             }
782f9765acdSGreg Clayton         }
783f9765acdSGreg Clayton     }
784f9765acdSGreg Clayton 
785f9765acdSGreg Clayton     if (log)
786f9765acdSGreg Clayton         log->Printf ("ProcessKDP::%s (arg = %p, pid = %i) thread exiting...", __FUNCTION__, arg, process->GetID());
787f9765acdSGreg Clayton 
788f9765acdSGreg Clayton     process->m_async_thread = LLDB_INVALID_HOST_THREAD;
789f9765acdSGreg Clayton     return NULL;
790f9765acdSGreg Clayton }
791f9765acdSGreg Clayton 
792f9765acdSGreg Clayton 
793