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
163a29bdbeSGreg Clayton #include "lldb/Core/ConnectionFileDescriptor.h"
1707e66e3eSGreg Clayton #include "lldb/Core/Debugger.h"
18f9765acdSGreg Clayton #include "lldb/Core/PluginManager.h"
19f9765acdSGreg Clayton #include "lldb/Core/State.h"
20f9765acdSGreg Clayton #include "lldb/Host/Host.h"
2157508026SGreg Clayton #include "lldb/Target/Target.h"
22a63d08c9SGreg Clayton #include "lldb/Target/Thread.h"
23f9765acdSGreg Clayton 
24f9765acdSGreg Clayton // Project includes
25f9765acdSGreg Clayton #include "ProcessKDP.h"
26f9765acdSGreg Clayton #include "ProcessKDPLog.h"
27a63d08c9SGreg Clayton #include "ThreadKDP.h"
28f9765acdSGreg Clayton #include "StopInfoMachException.h"
29f9765acdSGreg Clayton 
30f9765acdSGreg Clayton using namespace lldb;
31f9765acdSGreg Clayton using namespace lldb_private;
32f9765acdSGreg Clayton 
33f9765acdSGreg Clayton const char *
34f9765acdSGreg Clayton ProcessKDP::GetPluginNameStatic()
35f9765acdSGreg Clayton {
36f9765acdSGreg Clayton     return "kdp-remote";
37f9765acdSGreg Clayton }
38f9765acdSGreg Clayton 
39f9765acdSGreg Clayton const char *
40f9765acdSGreg Clayton ProcessKDP::GetPluginDescriptionStatic()
41f9765acdSGreg Clayton {
42f9765acdSGreg Clayton     return "KDP Remote protocol based debugging plug-in for darwin kernel debugging.";
43f9765acdSGreg Clayton }
44f9765acdSGreg Clayton 
45f9765acdSGreg Clayton void
46f9765acdSGreg Clayton ProcessKDP::Terminate()
47f9765acdSGreg Clayton {
48f9765acdSGreg Clayton     PluginManager::UnregisterPlugin (ProcessKDP::CreateInstance);
49f9765acdSGreg Clayton }
50f9765acdSGreg Clayton 
51f9765acdSGreg Clayton 
52f9765acdSGreg Clayton Process*
53f9765acdSGreg Clayton ProcessKDP::CreateInstance (Target &target, Listener &listener)
54f9765acdSGreg Clayton {
55f9765acdSGreg Clayton     return new ProcessKDP (target, listener);
56f9765acdSGreg Clayton }
57f9765acdSGreg Clayton 
58f9765acdSGreg Clayton bool
593a29bdbeSGreg Clayton ProcessKDP::CanDebug(Target &target, bool plugin_specified_by_name)
60f9765acdSGreg Clayton {
61f9765acdSGreg Clayton     // For now we are just making sure the file exists for a given module
62aa149cbdSGreg Clayton     Module *exe_module = target.GetExecutableModulePointer();
63aa149cbdSGreg Clayton     if (exe_module)
64f9765acdSGreg Clayton     {
65f9765acdSGreg Clayton         const llvm::Triple &triple_ref = target.GetArchitecture().GetTriple();
66f9765acdSGreg Clayton         if (triple_ref.getOS() == llvm::Triple::Darwin &&
67f9765acdSGreg Clayton             triple_ref.getVendor() == llvm::Triple::Apple)
68f9765acdSGreg Clayton         {
69aa149cbdSGreg Clayton             ObjectFile *exe_objfile = exe_module->GetObjectFile();
70f9765acdSGreg Clayton             if (exe_objfile->GetType() == ObjectFile::eTypeExecutable &&
71f9765acdSGreg Clayton                 exe_objfile->GetStrata() == ObjectFile::eStrataKernel)
72f9765acdSGreg Clayton                 return true;
73f9765acdSGreg Clayton         }
74f9765acdSGreg Clayton         return false;
75f9765acdSGreg Clayton     }
763a29bdbeSGreg Clayton     // No target executable, assume we can debug if our plug-in was specified by name
773a29bdbeSGreg Clayton     return plugin_specified_by_name;
783a29bdbeSGreg Clayton }
79f9765acdSGreg Clayton 
80f9765acdSGreg Clayton //----------------------------------------------------------------------
81f9765acdSGreg Clayton // ProcessKDP constructor
82f9765acdSGreg Clayton //----------------------------------------------------------------------
83f9765acdSGreg Clayton ProcessKDP::ProcessKDP(Target& target, Listener &listener) :
84f9765acdSGreg Clayton     Process (target, listener),
85f9765acdSGreg Clayton     m_comm("lldb.process.kdp-remote.communication"),
86f9765acdSGreg Clayton     m_async_broadcaster ("lldb.process.kdp-remote.async-broadcaster"),
87f9765acdSGreg Clayton     m_async_thread (LLDB_INVALID_HOST_THREAD)
88f9765acdSGreg Clayton {
89f9765acdSGreg Clayton //    m_async_broadcaster.SetEventName (eBroadcastBitAsyncThreadShouldExit,   "async thread should exit");
90f9765acdSGreg Clayton //    m_async_broadcaster.SetEventName (eBroadcastBitAsyncContinue,           "async thread continue");
91f9765acdSGreg Clayton }
92f9765acdSGreg Clayton 
93f9765acdSGreg Clayton //----------------------------------------------------------------------
94f9765acdSGreg Clayton // Destructor
95f9765acdSGreg Clayton //----------------------------------------------------------------------
96f9765acdSGreg Clayton ProcessKDP::~ProcessKDP()
97f9765acdSGreg Clayton {
98f9765acdSGreg Clayton     Clear();
99f9765acdSGreg Clayton }
100f9765acdSGreg Clayton 
101f9765acdSGreg Clayton //----------------------------------------------------------------------
102f9765acdSGreg Clayton // PluginInterface
103f9765acdSGreg Clayton //----------------------------------------------------------------------
104f9765acdSGreg Clayton const char *
105f9765acdSGreg Clayton ProcessKDP::GetPluginName()
106f9765acdSGreg Clayton {
107f9765acdSGreg Clayton     return "Process debugging plug-in that uses the Darwin KDP remote protocol";
108f9765acdSGreg Clayton }
109f9765acdSGreg Clayton 
110f9765acdSGreg Clayton const char *
111f9765acdSGreg Clayton ProcessKDP::GetShortPluginName()
112f9765acdSGreg Clayton {
113f9765acdSGreg Clayton     return GetPluginNameStatic();
114f9765acdSGreg Clayton }
115f9765acdSGreg Clayton 
116f9765acdSGreg Clayton uint32_t
117f9765acdSGreg Clayton ProcessKDP::GetPluginVersion()
118f9765acdSGreg Clayton {
119f9765acdSGreg Clayton     return 1;
120f9765acdSGreg Clayton }
121f9765acdSGreg Clayton 
122f9765acdSGreg Clayton Error
123f9765acdSGreg Clayton ProcessKDP::WillLaunch (Module* module)
124f9765acdSGreg Clayton {
125f9765acdSGreg Clayton     Error error;
126f9765acdSGreg Clayton     error.SetErrorString ("launching not supported in kdp-remote plug-in");
127f9765acdSGreg Clayton     return error;
128f9765acdSGreg Clayton }
129f9765acdSGreg Clayton 
130f9765acdSGreg Clayton Error
131f9765acdSGreg Clayton ProcessKDP::WillAttachToProcessWithID (lldb::pid_t pid)
132f9765acdSGreg Clayton {
133f9765acdSGreg Clayton     Error error;
134f9765acdSGreg Clayton     error.SetErrorString ("attaching to a by process ID not supported in kdp-remote plug-in");
135f9765acdSGreg Clayton     return error;
136f9765acdSGreg Clayton }
137f9765acdSGreg Clayton 
138f9765acdSGreg Clayton Error
139f9765acdSGreg Clayton ProcessKDP::WillAttachToProcessWithName (const char *process_name, bool wait_for_launch)
140f9765acdSGreg Clayton {
141f9765acdSGreg Clayton     Error error;
142f9765acdSGreg Clayton     error.SetErrorString ("attaching to a by process name not supported in kdp-remote plug-in");
143f9765acdSGreg Clayton     return error;
144f9765acdSGreg Clayton }
145f9765acdSGreg Clayton 
146f9765acdSGreg Clayton Error
147f9765acdSGreg Clayton ProcessKDP::DoConnectRemote (const char *remote_url)
148f9765acdSGreg Clayton {
149f9765acdSGreg Clayton     // TODO: fill in the remote connection to the remote KDP here!
150f9765acdSGreg Clayton     Error error;
1513a29bdbeSGreg Clayton 
1523a29bdbeSGreg Clayton     if (remote_url == NULL || remote_url[0] == '\0')
1533a29bdbeSGreg Clayton         remote_url = "udp://localhost:41139";
1543a29bdbeSGreg Clayton 
1553a29bdbeSGreg Clayton     std::auto_ptr<ConnectionFileDescriptor> conn_ap(new ConnectionFileDescriptor());
1563a29bdbeSGreg Clayton     if (conn_ap.get())
1573a29bdbeSGreg Clayton     {
1583a29bdbeSGreg Clayton         // Only try once for now.
1593a29bdbeSGreg Clayton         // TODO: check if we should be retrying?
1603a29bdbeSGreg Clayton         const uint32_t max_retry_count = 1;
1613a29bdbeSGreg Clayton         for (uint32_t retry_count = 0; retry_count < max_retry_count; ++retry_count)
1623a29bdbeSGreg Clayton         {
1633a29bdbeSGreg Clayton             if (conn_ap->Connect(remote_url, &error) == eConnectionStatusSuccess)
1643a29bdbeSGreg Clayton                 break;
1653a29bdbeSGreg Clayton             usleep (100000);
1663a29bdbeSGreg Clayton         }
1673a29bdbeSGreg Clayton     }
1683a29bdbeSGreg Clayton 
1693a29bdbeSGreg Clayton     if (conn_ap->IsConnected())
1703a29bdbeSGreg Clayton     {
1713a29bdbeSGreg Clayton         const uint16_t reply_port = conn_ap->GetReadPort ();
1723a29bdbeSGreg Clayton 
1733a29bdbeSGreg Clayton         if (reply_port != 0)
1743a29bdbeSGreg Clayton         {
1753a29bdbeSGreg Clayton             m_comm.SetConnection(conn_ap.release());
1763a29bdbeSGreg Clayton 
1773a29bdbeSGreg Clayton             if (m_comm.SendRequestReattach(reply_port))
1783a29bdbeSGreg Clayton             {
1793a29bdbeSGreg Clayton                 if (m_comm.SendRequestConnect(reply_port, reply_port, "Greetings from LLDB..."))
1803a29bdbeSGreg Clayton                 {
1813a29bdbeSGreg Clayton                     m_comm.GetVersion();
1823a29bdbeSGreg Clayton                     uint32_t cpu = m_comm.GetCPUType();
1833a29bdbeSGreg Clayton                     uint32_t sub = m_comm.GetCPUSubtype();
1843a29bdbeSGreg Clayton                     ArchSpec kernel_arch;
1853a29bdbeSGreg Clayton                     kernel_arch.SetArchitecture(eArchTypeMachO, cpu, sub);
1863a29bdbeSGreg Clayton                     m_target.SetArchitecture(kernel_arch);
187a63d08c9SGreg Clayton                     SetID (1);
18856d9a1b3SGreg Clayton                     GetThreadList ();
189a63d08c9SGreg Clayton                     SetPrivateState (eStateStopped);
19007e66e3eSGreg Clayton                     StreamSP async_strm_sp(m_target.GetDebugger().GetAsyncOutputStream());
19107e66e3eSGreg Clayton                     if (async_strm_sp)
19207e66e3eSGreg Clayton                     {
1935b88216dSGreg Clayton                         const char *cstr;
1945b88216dSGreg Clayton                         if ((cstr = m_comm.GetKernelVersion ()) != NULL)
19507e66e3eSGreg Clayton                         {
1965b88216dSGreg Clayton                             async_strm_sp->Printf ("Version: %s\n", cstr);
19707e66e3eSGreg Clayton                             async_strm_sp->Flush();
19807e66e3eSGreg Clayton                         }
1995b88216dSGreg Clayton //                      if ((cstr = m_comm.GetImagePath ()) != NULL)
2005b88216dSGreg Clayton //                      {
2015b88216dSGreg Clayton //                          async_strm_sp->Printf ("Image Path: %s\n", cstr);
2025b88216dSGreg Clayton //                          async_strm_sp->Flush();
2035b88216dSGreg Clayton //                      }
20407e66e3eSGreg Clayton                     }
2053a29bdbeSGreg Clayton                 }
2063a29bdbeSGreg Clayton             }
2073a29bdbeSGreg Clayton             else
2083a29bdbeSGreg Clayton             {
2093a29bdbeSGreg Clayton                 error.SetErrorString("KDP reattach failed");
2103a29bdbeSGreg Clayton             }
2113a29bdbeSGreg Clayton         }
2123a29bdbeSGreg Clayton         else
2133a29bdbeSGreg Clayton         {
2143a29bdbeSGreg Clayton             error.SetErrorString("invalid reply port from UDP connection");
2153a29bdbeSGreg Clayton         }
2163a29bdbeSGreg Clayton     }
2173a29bdbeSGreg Clayton     else
2183a29bdbeSGreg Clayton     {
2193a29bdbeSGreg Clayton         if (error.Success())
2203a29bdbeSGreg Clayton             error.SetErrorStringWithFormat ("failed to connect to '%s'", remote_url);
2213a29bdbeSGreg Clayton     }
2223a29bdbeSGreg Clayton     if (error.Fail())
2233a29bdbeSGreg Clayton         m_comm.Disconnect();
2243a29bdbeSGreg Clayton 
225f9765acdSGreg Clayton     return error;
226f9765acdSGreg Clayton }
227f9765acdSGreg Clayton 
228f9765acdSGreg Clayton //----------------------------------------------------------------------
229f9765acdSGreg Clayton // Process Control
230f9765acdSGreg Clayton //----------------------------------------------------------------------
231f9765acdSGreg Clayton Error
232f9765acdSGreg Clayton ProcessKDP::DoLaunch (Module* module,
233f9765acdSGreg Clayton                       char const *argv[],
234f9765acdSGreg Clayton                       char const *envp[],
235f9765acdSGreg Clayton                       uint32_t launch_flags,
236f9765acdSGreg Clayton                       const char *stdin_path,
237f9765acdSGreg Clayton                       const char *stdout_path,
238f9765acdSGreg Clayton                       const char *stderr_path,
239f9765acdSGreg Clayton                       const char *working_dir)
240f9765acdSGreg Clayton {
241f9765acdSGreg Clayton     Error error;
242f9765acdSGreg Clayton     error.SetErrorString ("launching not supported in kdp-remote plug-in");
243f9765acdSGreg Clayton     return error;
244f9765acdSGreg Clayton }
245f9765acdSGreg Clayton 
246f9765acdSGreg Clayton 
247f9765acdSGreg Clayton Error
248f9765acdSGreg Clayton ProcessKDP::DoAttachToProcessWithID (lldb::pid_t attach_pid)
249f9765acdSGreg Clayton {
250f9765acdSGreg Clayton     Error error;
251f9765acdSGreg Clayton     error.SetErrorString ("attach to process by ID is not suppported in kdp remote debugging");
252f9765acdSGreg Clayton     return error;
253f9765acdSGreg Clayton }
254f9765acdSGreg Clayton 
255f9765acdSGreg Clayton Error
256f9765acdSGreg Clayton ProcessKDP::DoAttachToProcessWithName (const char *process_name, bool wait_for_launch)
257f9765acdSGreg Clayton {
258f9765acdSGreg Clayton     Error error;
259f9765acdSGreg Clayton     error.SetErrorString ("attach to process by name is not suppported in kdp remote debugging");
260f9765acdSGreg Clayton     return error;
261f9765acdSGreg Clayton }
262f9765acdSGreg Clayton 
263f9765acdSGreg Clayton 
264f9765acdSGreg Clayton void
265f9765acdSGreg Clayton ProcessKDP::DidAttach ()
266f9765acdSGreg Clayton {
267f9765acdSGreg Clayton     LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_PROCESS));
268f9765acdSGreg Clayton     if (log)
269*54cb8f83SJohnny Chen         log->Printf ("ProcessKDP::DidAttach()");
270f9765acdSGreg Clayton     if (GetID() != LLDB_INVALID_PROCESS_ID)
271f9765acdSGreg Clayton     {
272f9765acdSGreg Clayton         // TODO: figure out the register context that we will use
273f9765acdSGreg Clayton     }
274f9765acdSGreg Clayton }
275f9765acdSGreg Clayton 
276f9765acdSGreg Clayton Error
277f9765acdSGreg Clayton ProcessKDP::WillResume ()
278f9765acdSGreg Clayton {
279f9765acdSGreg Clayton     return Error();
280f9765acdSGreg Clayton }
281f9765acdSGreg Clayton 
282f9765acdSGreg Clayton Error
283f9765acdSGreg Clayton ProcessKDP::DoResume ()
284f9765acdSGreg Clayton {
285f9765acdSGreg Clayton     Error error;
28607e66e3eSGreg Clayton     if (!m_comm.SendRequestResume ())
28707e66e3eSGreg Clayton         error.SetErrorString ("KDP resume failed");
288f9765acdSGreg Clayton     return error;
289f9765acdSGreg Clayton }
290f9765acdSGreg Clayton 
291f9765acdSGreg Clayton uint32_t
29256d9a1b3SGreg Clayton ProcessKDP::UpdateThreadList (ThreadList &old_thread_list, ThreadList &new_thread_list)
293f9765acdSGreg Clayton {
294f9765acdSGreg Clayton     // locker will keep a mutex locked until it goes out of scope
295f9765acdSGreg Clayton     LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_THREAD));
296f9765acdSGreg Clayton     if (log && log->GetMask().Test(KDP_LOG_VERBOSE))
297f9765acdSGreg Clayton         log->Printf ("ProcessKDP::%s (pid = %i)", __FUNCTION__, GetID());
298f9765acdSGreg Clayton 
299a63d08c9SGreg Clayton     // We currently are making only one thread per core and we
300a63d08c9SGreg Clayton     // actually don't know about actual threads. Eventually we
301a63d08c9SGreg Clayton     // want to get the thread list from memory and note which
302a63d08c9SGreg Clayton     // threads are on CPU as those are the only ones that we
303a63d08c9SGreg Clayton     // will be able to resume.
304a63d08c9SGreg Clayton     const uint32_t cpu_mask = m_comm.GetCPUMask();
305a63d08c9SGreg Clayton     for (uint32_t cpu_mask_bit = 1; cpu_mask_bit & cpu_mask; cpu_mask_bit <<= 1)
306a63d08c9SGreg Clayton     {
30756d9a1b3SGreg Clayton         lldb::tid_t tid = cpu_mask_bit;
30856d9a1b3SGreg Clayton         ThreadSP thread_sp (old_thread_list.FindThreadByID (tid, false));
30956d9a1b3SGreg Clayton         if (!thread_sp)
31056d9a1b3SGreg Clayton             thread_sp.reset(new ThreadKDP (*this, tid));
31156d9a1b3SGreg Clayton         new_thread_list.AddThread(thread_sp);
312a63d08c9SGreg Clayton     }
31356d9a1b3SGreg Clayton     return new_thread_list.GetSize(false);
314f9765acdSGreg Clayton }
315f9765acdSGreg Clayton 
316f9765acdSGreg Clayton 
317f9765acdSGreg Clayton StateType
318f9765acdSGreg Clayton ProcessKDP::SetThreadStopInfo (StringExtractor& stop_packet)
319f9765acdSGreg Clayton {
320f9765acdSGreg Clayton     // TODO: figure out why we stopped given the packet that tells us we stopped...
321f9765acdSGreg Clayton     return eStateStopped;
322f9765acdSGreg Clayton }
323f9765acdSGreg Clayton 
324f9765acdSGreg Clayton void
325f9765acdSGreg Clayton ProcessKDP::RefreshStateAfterStop ()
326f9765acdSGreg Clayton {
327f9765acdSGreg Clayton     // Let all threads recover from stopping and do any clean up based
328f9765acdSGreg Clayton     // on the previous thread state (if any).
329f9765acdSGreg Clayton     m_thread_list.RefreshStateAfterStop();
330f9765acdSGreg Clayton     //SetThreadStopInfo (m_last_stop_packet);
331f9765acdSGreg Clayton }
332f9765acdSGreg Clayton 
333f9765acdSGreg Clayton Error
334f9765acdSGreg Clayton ProcessKDP::DoHalt (bool &caused_stop)
335f9765acdSGreg Clayton {
336f9765acdSGreg Clayton     Error error;
337f9765acdSGreg Clayton 
338f9765acdSGreg Clayton //    bool timed_out = false;
339f9765acdSGreg Clayton     Mutex::Locker locker;
340f9765acdSGreg Clayton 
341f9765acdSGreg Clayton     if (m_public_state.GetValue() == eStateAttaching)
342f9765acdSGreg Clayton     {
343f9765acdSGreg Clayton         // We are being asked to halt during an attach. We need to just close
344f9765acdSGreg Clayton         // our file handle and debugserver will go away, and we can be done...
345f9765acdSGreg Clayton         m_comm.Disconnect();
346f9765acdSGreg Clayton     }
347f9765acdSGreg Clayton     else
348f9765acdSGreg Clayton     {
34907e66e3eSGreg Clayton         if (!m_comm.SendRequestSuspend ())
35007e66e3eSGreg Clayton             error.SetErrorString ("KDP halt failed");
351f9765acdSGreg Clayton     }
352f9765acdSGreg Clayton     return error;
353f9765acdSGreg Clayton }
354f9765acdSGreg Clayton 
355f9765acdSGreg Clayton Error
356f9765acdSGreg Clayton ProcessKDP::InterruptIfRunning (bool discard_thread_plans,
357f9765acdSGreg Clayton                                 bool catch_stop_event,
358f9765acdSGreg Clayton                                 EventSP &stop_event_sp)
359f9765acdSGreg Clayton {
360f9765acdSGreg Clayton     Error error;
361f9765acdSGreg Clayton 
362f9765acdSGreg Clayton     LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS));
363f9765acdSGreg Clayton 
364f9765acdSGreg Clayton     bool paused_private_state_thread = false;
365f9765acdSGreg Clayton     const bool is_running = m_comm.IsRunning();
366f9765acdSGreg Clayton     if (log)
367f9765acdSGreg Clayton         log->Printf ("ProcessKDP::InterruptIfRunning(discard_thread_plans=%i, catch_stop_event=%i) is_running=%i",
368f9765acdSGreg Clayton                      discard_thread_plans,
369f9765acdSGreg Clayton                      catch_stop_event,
370f9765acdSGreg Clayton                      is_running);
371f9765acdSGreg Clayton 
372f9765acdSGreg Clayton     if (discard_thread_plans)
373f9765acdSGreg Clayton     {
374f9765acdSGreg Clayton         if (log)
375f9765acdSGreg Clayton             log->Printf ("ProcessKDP::InterruptIfRunning() discarding all thread plans");
376f9765acdSGreg Clayton         m_thread_list.DiscardThreadPlans();
377f9765acdSGreg Clayton     }
378f9765acdSGreg Clayton     if (is_running)
379f9765acdSGreg Clayton     {
380f9765acdSGreg Clayton         if (catch_stop_event)
381f9765acdSGreg Clayton         {
382f9765acdSGreg Clayton             if (log)
383f9765acdSGreg Clayton                 log->Printf ("ProcessKDP::InterruptIfRunning() pausing private state thread");
384f9765acdSGreg Clayton             PausePrivateStateThread();
385f9765acdSGreg Clayton             paused_private_state_thread = true;
386f9765acdSGreg Clayton         }
387f9765acdSGreg Clayton 
388f9765acdSGreg Clayton         bool timed_out = false;
389f9765acdSGreg Clayton //        bool sent_interrupt = false;
390f9765acdSGreg Clayton         Mutex::Locker locker;
391f9765acdSGreg Clayton 
392f9765acdSGreg Clayton         // TODO: implement halt in CommunicationKDP
393f9765acdSGreg Clayton //        if (!m_comm.SendInterrupt (locker, 1, sent_interrupt, timed_out))
394f9765acdSGreg Clayton //        {
395f9765acdSGreg Clayton //            if (timed_out)
396f9765acdSGreg Clayton //                error.SetErrorString("timed out sending interrupt packet");
397f9765acdSGreg Clayton //            else
398f9765acdSGreg Clayton //                error.SetErrorString("unknown error sending interrupt packet");
399f9765acdSGreg Clayton //            if (paused_private_state_thread)
400f9765acdSGreg Clayton //                ResumePrivateStateThread();
401f9765acdSGreg Clayton //            return error;
402f9765acdSGreg Clayton //        }
403f9765acdSGreg Clayton 
404f9765acdSGreg Clayton         if (catch_stop_event)
405f9765acdSGreg Clayton         {
406f9765acdSGreg Clayton             // LISTEN HERE
407f9765acdSGreg Clayton             TimeValue timeout_time;
408f9765acdSGreg Clayton             timeout_time = TimeValue::Now();
409f9765acdSGreg Clayton             timeout_time.OffsetWithSeconds(5);
410f9765acdSGreg Clayton             StateType state = WaitForStateChangedEventsPrivate (&timeout_time, stop_event_sp);
411f9765acdSGreg Clayton 
412f9765acdSGreg Clayton             timed_out = state == eStateInvalid;
413f9765acdSGreg Clayton             if (log)
414f9765acdSGreg Clayton                 log->Printf ("ProcessKDP::InterruptIfRunning() catch stop event: state = %s, timed-out=%i", StateAsCString(state), timed_out);
415f9765acdSGreg Clayton 
416f9765acdSGreg Clayton             if (timed_out)
417f9765acdSGreg Clayton                 error.SetErrorString("unable to verify target stopped");
418f9765acdSGreg Clayton         }
419f9765acdSGreg Clayton 
420f9765acdSGreg Clayton         if (paused_private_state_thread)
421f9765acdSGreg Clayton         {
422f9765acdSGreg Clayton             if (log)
423f9765acdSGreg Clayton                 log->Printf ("ProcessKDP::InterruptIfRunning() resuming private state thread");
424f9765acdSGreg Clayton             ResumePrivateStateThread();
425f9765acdSGreg Clayton         }
426f9765acdSGreg Clayton     }
427f9765acdSGreg Clayton     return error;
428f9765acdSGreg Clayton }
429f9765acdSGreg Clayton 
430f9765acdSGreg Clayton Error
431f9765acdSGreg Clayton ProcessKDP::WillDetach ()
432f9765acdSGreg Clayton {
433f9765acdSGreg Clayton     LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS));
434f9765acdSGreg Clayton     if (log)
435f9765acdSGreg Clayton         log->Printf ("ProcessKDP::WillDetach()");
436f9765acdSGreg Clayton 
437f9765acdSGreg Clayton     bool discard_thread_plans = true;
438f9765acdSGreg Clayton     bool catch_stop_event = true;
439f9765acdSGreg Clayton     EventSP event_sp;
440f9765acdSGreg Clayton     return InterruptIfRunning (discard_thread_plans, catch_stop_event, event_sp);
441f9765acdSGreg Clayton }
442f9765acdSGreg Clayton 
443f9765acdSGreg Clayton Error
444f9765acdSGreg Clayton ProcessKDP::DoDetach()
445f9765acdSGreg Clayton {
446f9765acdSGreg Clayton     Error error;
447f9765acdSGreg Clayton     LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS));
448f9765acdSGreg Clayton     if (log)
449f9765acdSGreg Clayton         log->Printf ("ProcessKDP::DoDetach()");
450f9765acdSGreg Clayton 
451f9765acdSGreg Clayton     DisableAllBreakpointSites ();
452f9765acdSGreg Clayton 
453f9765acdSGreg Clayton     m_thread_list.DiscardThreadPlans();
454f9765acdSGreg Clayton 
4553a29bdbeSGreg Clayton     if (m_comm.IsConnected())
4563a29bdbeSGreg Clayton     {
4573a29bdbeSGreg Clayton 
4583a29bdbeSGreg Clayton         m_comm.SendRequestDisconnect();
4593a29bdbeSGreg Clayton 
46057508026SGreg Clayton         size_t response_size = m_comm.Disconnect ();
461f9765acdSGreg Clayton         if (log)
462f9765acdSGreg Clayton         {
463f9765acdSGreg Clayton             if (response_size)
464f9765acdSGreg Clayton                 log->PutCString ("ProcessKDP::DoDetach() detach packet sent successfully");
465f9765acdSGreg Clayton             else
466f9765acdSGreg Clayton                 log->PutCString ("ProcessKDP::DoDetach() detach packet send failed");
467f9765acdSGreg Clayton         }
4683a29bdbeSGreg Clayton     }
469f9765acdSGreg Clayton     // Sleep for one second to let the process get all detached...
470f9765acdSGreg Clayton     StopAsyncThread ();
471f9765acdSGreg Clayton 
472f9765acdSGreg Clayton     m_comm.StopReadThread();
473f9765acdSGreg Clayton     m_comm.Disconnect();    // Disconnect from the debug server.
474f9765acdSGreg Clayton 
475f9765acdSGreg Clayton     SetPrivateState (eStateDetached);
476f9765acdSGreg Clayton     ResumePrivateStateThread();
477f9765acdSGreg Clayton 
478f9765acdSGreg Clayton     //KillDebugserverProcess ();
479f9765acdSGreg Clayton     return error;
480f9765acdSGreg Clayton }
481f9765acdSGreg Clayton 
482f9765acdSGreg Clayton Error
483f9765acdSGreg Clayton ProcessKDP::DoDestroy ()
484f9765acdSGreg Clayton {
485f9765acdSGreg Clayton     Error error;
486f9765acdSGreg Clayton     LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS));
487f9765acdSGreg Clayton     if (log)
488f9765acdSGreg Clayton         log->Printf ("ProcessKDP::DoDestroy()");
489f9765acdSGreg Clayton 
490f9765acdSGreg Clayton     // Interrupt if our inferior is running...
491f9765acdSGreg Clayton     if (m_comm.IsConnected())
492f9765acdSGreg Clayton     {
493f9765acdSGreg Clayton         if (m_public_state.GetValue() == eStateAttaching)
494f9765acdSGreg Clayton         {
495f9765acdSGreg Clayton             // We are being asked to halt during an attach. We need to just close
496f9765acdSGreg Clayton             // our file handle and debugserver will go away, and we can be done...
497f9765acdSGreg Clayton             m_comm.Disconnect();
498f9765acdSGreg Clayton         }
499f9765acdSGreg Clayton         else
500f9765acdSGreg Clayton         {
5015b88216dSGreg Clayton             DisableAllBreakpointSites ();
5025b88216dSGreg Clayton 
5035b88216dSGreg Clayton             m_comm.SendRequestDisconnect();
504f9765acdSGreg Clayton 
505f9765acdSGreg Clayton             StringExtractor response;
506f9765acdSGreg Clayton             // TODO: Send kill packet?
507f9765acdSGreg Clayton             SetExitStatus(SIGABRT, NULL);
508f9765acdSGreg Clayton         }
509f9765acdSGreg Clayton     }
510f9765acdSGreg Clayton     StopAsyncThread ();
511f9765acdSGreg Clayton     m_comm.StopReadThread();
512f9765acdSGreg Clayton     m_comm.Disconnect();    // Disconnect from the debug server.
513f9765acdSGreg Clayton     return error;
514f9765acdSGreg Clayton }
515f9765acdSGreg Clayton 
516f9765acdSGreg Clayton //------------------------------------------------------------------
517f9765acdSGreg Clayton // Process Queries
518f9765acdSGreg Clayton //------------------------------------------------------------------
519f9765acdSGreg Clayton 
520f9765acdSGreg Clayton bool
521f9765acdSGreg Clayton ProcessKDP::IsAlive ()
522f9765acdSGreg Clayton {
523f9765acdSGreg Clayton     return m_comm.IsConnected() && m_private_state.GetValue() != eStateExited;
524f9765acdSGreg Clayton }
525f9765acdSGreg Clayton 
526f9765acdSGreg Clayton //------------------------------------------------------------------
527f9765acdSGreg Clayton // Process Memory
528f9765acdSGreg Clayton //------------------------------------------------------------------
529f9765acdSGreg Clayton size_t
530f9765acdSGreg Clayton ProcessKDP::DoReadMemory (addr_t addr, void *buf, size_t size, Error &error)
531f9765acdSGreg Clayton {
532a63d08c9SGreg Clayton     if (m_comm.IsConnected())
533a63d08c9SGreg Clayton         return m_comm.SendRequestReadMemory (addr, buf, size, error);
534a63d08c9SGreg Clayton     error.SetErrorString ("not connected");
535f9765acdSGreg Clayton     return 0;
536f9765acdSGreg Clayton }
537f9765acdSGreg Clayton 
538f9765acdSGreg Clayton size_t
539f9765acdSGreg Clayton ProcessKDP::DoWriteMemory (addr_t addr, const void *buf, size_t size, Error &error)
540f9765acdSGreg Clayton {
541f9765acdSGreg Clayton     error.SetErrorString ("ProcessKDP::DoReadMemory not implemented");
542f9765acdSGreg Clayton     return 0;
543f9765acdSGreg Clayton }
544f9765acdSGreg Clayton 
545f9765acdSGreg Clayton lldb::addr_t
546f9765acdSGreg Clayton ProcessKDP::DoAllocateMemory (size_t size, uint32_t permissions, Error &error)
547f9765acdSGreg Clayton {
548f9765acdSGreg Clayton     error.SetErrorString ("memory allocation not suppported in kdp remote debugging");
549f9765acdSGreg Clayton     return LLDB_INVALID_ADDRESS;
550f9765acdSGreg Clayton }
551f9765acdSGreg Clayton 
552f9765acdSGreg Clayton Error
553f9765acdSGreg Clayton ProcessKDP::DoDeallocateMemory (lldb::addr_t addr)
554f9765acdSGreg Clayton {
555f9765acdSGreg Clayton     Error error;
556f9765acdSGreg Clayton     error.SetErrorString ("memory deallocation not suppported in kdp remote debugging");
557f9765acdSGreg Clayton     return error;
558f9765acdSGreg Clayton }
559f9765acdSGreg Clayton 
560f9765acdSGreg Clayton Error
561f9765acdSGreg Clayton ProcessKDP::EnableBreakpoint (BreakpointSite *bp_site)
562f9765acdSGreg Clayton {
56307e66e3eSGreg Clayton     if (m_comm.LocalBreakpointsAreSupported ())
56407e66e3eSGreg Clayton     {
56507e66e3eSGreg Clayton         Error error;
5665b88216dSGreg Clayton         if (!bp_site->IsEnabled())
5675b88216dSGreg Clayton         {
5685b88216dSGreg Clayton             if (m_comm.SendRequestBreakpoint(true, bp_site->GetLoadAddress()))
5695b88216dSGreg Clayton             {
5705b88216dSGreg Clayton                 bp_site->SetEnabled(true);
5715b88216dSGreg Clayton                 bp_site->SetType (BreakpointSite::eExternal);
5725b88216dSGreg Clayton             }
5735b88216dSGreg Clayton             else
5745b88216dSGreg Clayton             {
57507e66e3eSGreg Clayton                 error.SetErrorString ("KDP set breakpoint failed");
5765b88216dSGreg Clayton             }
5775b88216dSGreg Clayton         }
57807e66e3eSGreg Clayton         return error;
57907e66e3eSGreg Clayton     }
580f9765acdSGreg Clayton     return EnableSoftwareBreakpoint (bp_site);
581f9765acdSGreg Clayton }
582f9765acdSGreg Clayton 
583f9765acdSGreg Clayton Error
584f9765acdSGreg Clayton ProcessKDP::DisableBreakpoint (BreakpointSite *bp_site)
585f9765acdSGreg Clayton {
58607e66e3eSGreg Clayton     if (m_comm.LocalBreakpointsAreSupported ())
58707e66e3eSGreg Clayton     {
58807e66e3eSGreg Clayton         Error error;
5895b88216dSGreg Clayton         if (bp_site->IsEnabled())
5905b88216dSGreg Clayton         {
5915b88216dSGreg Clayton             BreakpointSite::Type bp_type = bp_site->GetType();
5925b88216dSGreg Clayton             if (bp_type == BreakpointSite::eExternal)
5935b88216dSGreg Clayton             {
5945b88216dSGreg Clayton                 if (m_comm.SendRequestBreakpoint(false, bp_site->GetLoadAddress()))
5955b88216dSGreg Clayton                     bp_site->SetEnabled(false);
5965b88216dSGreg Clayton                 else
59707e66e3eSGreg Clayton                     error.SetErrorString ("KDP remove breakpoint failed");
5985b88216dSGreg Clayton             }
5995b88216dSGreg Clayton             else
6005b88216dSGreg Clayton             {
6015b88216dSGreg Clayton                 error = DisableSoftwareBreakpoint (bp_site);
6025b88216dSGreg Clayton             }
6035b88216dSGreg Clayton         }
60407e66e3eSGreg Clayton         return error;
60507e66e3eSGreg Clayton     }
606f9765acdSGreg Clayton     return DisableSoftwareBreakpoint (bp_site);
607f9765acdSGreg Clayton }
608f9765acdSGreg Clayton 
609f9765acdSGreg Clayton Error
610f9765acdSGreg Clayton ProcessKDP::EnableWatchpoint (WatchpointLocation *wp)
611f9765acdSGreg Clayton {
612f9765acdSGreg Clayton     Error error;
613f9765acdSGreg Clayton     error.SetErrorString ("watchpoints are not suppported in kdp remote debugging");
614f9765acdSGreg Clayton     return error;
615f9765acdSGreg Clayton }
616f9765acdSGreg Clayton 
617f9765acdSGreg Clayton Error
618f9765acdSGreg Clayton ProcessKDP::DisableWatchpoint (WatchpointLocation *wp)
619f9765acdSGreg Clayton {
620f9765acdSGreg Clayton     Error error;
621f9765acdSGreg Clayton     error.SetErrorString ("watchpoints are not suppported in kdp remote debugging");
622f9765acdSGreg Clayton     return error;
623f9765acdSGreg Clayton }
624f9765acdSGreg Clayton 
625f9765acdSGreg Clayton void
626f9765acdSGreg Clayton ProcessKDP::Clear()
627f9765acdSGreg Clayton {
628f9765acdSGreg Clayton     Mutex::Locker locker (m_thread_list.GetMutex ());
629f9765acdSGreg Clayton     m_thread_list.Clear();
630f9765acdSGreg Clayton }
631f9765acdSGreg Clayton 
632f9765acdSGreg Clayton Error
633f9765acdSGreg Clayton ProcessKDP::DoSignal (int signo)
634f9765acdSGreg Clayton {
635f9765acdSGreg Clayton     Error error;
636f9765acdSGreg Clayton     error.SetErrorString ("sending signals is not suppported in kdp remote debugging");
637f9765acdSGreg Clayton     return error;
638f9765acdSGreg Clayton }
639f9765acdSGreg Clayton 
640f9765acdSGreg Clayton void
641f9765acdSGreg Clayton ProcessKDP::Initialize()
642f9765acdSGreg Clayton {
643f9765acdSGreg Clayton     static bool g_initialized = false;
644f9765acdSGreg Clayton 
645f9765acdSGreg Clayton     if (g_initialized == false)
646f9765acdSGreg Clayton     {
647f9765acdSGreg Clayton         g_initialized = true;
648f9765acdSGreg Clayton         PluginManager::RegisterPlugin (GetPluginNameStatic(),
649f9765acdSGreg Clayton                                        GetPluginDescriptionStatic(),
650f9765acdSGreg Clayton                                        CreateInstance);
651f9765acdSGreg Clayton 
652f9765acdSGreg Clayton         Log::Callbacks log_callbacks = {
653f9765acdSGreg Clayton             ProcessKDPLog::DisableLog,
654f9765acdSGreg Clayton             ProcessKDPLog::EnableLog,
655f9765acdSGreg Clayton             ProcessKDPLog::ListLogCategories
656f9765acdSGreg Clayton         };
657f9765acdSGreg Clayton 
658f9765acdSGreg Clayton         Log::RegisterLogChannel (ProcessKDP::GetPluginNameStatic(), log_callbacks);
659f9765acdSGreg Clayton     }
660f9765acdSGreg Clayton }
661f9765acdSGreg Clayton 
662f9765acdSGreg Clayton bool
663f9765acdSGreg Clayton ProcessKDP::StartAsyncThread ()
664f9765acdSGreg Clayton {
665f9765acdSGreg Clayton     LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS));
666f9765acdSGreg Clayton 
667f9765acdSGreg Clayton     if (log)
668f9765acdSGreg Clayton         log->Printf ("ProcessKDP::%s ()", __FUNCTION__);
669f9765acdSGreg Clayton 
670f9765acdSGreg Clayton     // Create a thread that watches our internal state and controls which
671f9765acdSGreg Clayton     // events make it to clients (into the DCProcess event queue).
672f9765acdSGreg Clayton     m_async_thread = Host::ThreadCreate ("<lldb.process.kdp-remote.async>", ProcessKDP::AsyncThread, this, NULL);
673f9765acdSGreg Clayton     return IS_VALID_LLDB_HOST_THREAD(m_async_thread);
674f9765acdSGreg Clayton }
675f9765acdSGreg Clayton 
676f9765acdSGreg Clayton void
677f9765acdSGreg Clayton ProcessKDP::StopAsyncThread ()
678f9765acdSGreg Clayton {
679f9765acdSGreg Clayton     LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS));
680f9765acdSGreg Clayton 
681f9765acdSGreg Clayton     if (log)
682f9765acdSGreg Clayton         log->Printf ("ProcessKDP::%s ()", __FUNCTION__);
683f9765acdSGreg Clayton 
684f9765acdSGreg Clayton     m_async_broadcaster.BroadcastEvent (eBroadcastBitAsyncThreadShouldExit);
685f9765acdSGreg Clayton 
686f9765acdSGreg Clayton     // Stop the stdio thread
687f9765acdSGreg Clayton     if (IS_VALID_LLDB_HOST_THREAD(m_async_thread))
688f9765acdSGreg Clayton     {
689f9765acdSGreg Clayton         Host::ThreadJoin (m_async_thread, NULL, NULL);
690f9765acdSGreg Clayton     }
691f9765acdSGreg Clayton }
692f9765acdSGreg Clayton 
693f9765acdSGreg Clayton 
694f9765acdSGreg Clayton void *
695f9765acdSGreg Clayton ProcessKDP::AsyncThread (void *arg)
696f9765acdSGreg Clayton {
697f9765acdSGreg Clayton     ProcessKDP *process = (ProcessKDP*) arg;
698f9765acdSGreg Clayton 
699f9765acdSGreg Clayton     LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_PROCESS));
700f9765acdSGreg Clayton     if (log)
701f9765acdSGreg Clayton         log->Printf ("ProcessKDP::%s (arg = %p, pid = %i) thread starting...", __FUNCTION__, arg, process->GetID());
702f9765acdSGreg Clayton 
703f9765acdSGreg Clayton     Listener listener ("ProcessKDP::AsyncThread");
704f9765acdSGreg Clayton     EventSP event_sp;
705f9765acdSGreg Clayton     const uint32_t desired_event_mask = eBroadcastBitAsyncContinue |
706f9765acdSGreg Clayton                                         eBroadcastBitAsyncThreadShouldExit;
707f9765acdSGreg Clayton 
708f9765acdSGreg Clayton     if (listener.StartListeningForEvents (&process->m_async_broadcaster, desired_event_mask) == desired_event_mask)
709f9765acdSGreg Clayton     {
710f9765acdSGreg Clayton         listener.StartListeningForEvents (&process->m_comm, Communication::eBroadcastBitReadThreadDidExit);
711f9765acdSGreg Clayton 
712f9765acdSGreg Clayton         bool done = false;
713f9765acdSGreg Clayton         while (!done)
714f9765acdSGreg Clayton         {
715f9765acdSGreg Clayton             if (log)
716f9765acdSGreg Clayton                 log->Printf ("ProcessKDP::%s (arg = %p, pid = %i) listener.WaitForEvent (NULL, event_sp)...", __FUNCTION__, arg, process->GetID());
717f9765acdSGreg Clayton             if (listener.WaitForEvent (NULL, event_sp))
718f9765acdSGreg Clayton             {
719f9765acdSGreg Clayton                 const uint32_t event_type = event_sp->GetType();
720f9765acdSGreg Clayton                 if (event_sp->BroadcasterIs (&process->m_async_broadcaster))
721f9765acdSGreg Clayton                 {
722f9765acdSGreg Clayton                     if (log)
723f9765acdSGreg Clayton                         log->Printf ("ProcessKDP::%s (arg = %p, pid = %i) Got an event of type: %d...", __FUNCTION__, arg, process->GetID(), event_type);
724f9765acdSGreg Clayton 
725f9765acdSGreg Clayton                     switch (event_type)
726f9765acdSGreg Clayton                     {
727f9765acdSGreg Clayton                         case eBroadcastBitAsyncContinue:
728f9765acdSGreg Clayton                         {
729f9765acdSGreg Clayton                             const EventDataBytes *continue_packet = EventDataBytes::GetEventDataFromEvent(event_sp.get());
730f9765acdSGreg Clayton 
731f9765acdSGreg Clayton                             if (continue_packet)
732f9765acdSGreg Clayton                             {
733f9765acdSGreg Clayton                                 // TODO: do continue support here
734f9765acdSGreg Clayton 
735f9765acdSGreg Clayton //                                const char *continue_cstr = (const char *)continue_packet->GetBytes ();
736f9765acdSGreg Clayton //                                const size_t continue_cstr_len = continue_packet->GetByteSize ();
737f9765acdSGreg Clayton //                                if (log)
738f9765acdSGreg Clayton //                                    log->Printf ("ProcessKDP::%s (arg = %p, pid = %i) got eBroadcastBitAsyncContinue: %s", __FUNCTION__, arg, process->GetID(), continue_cstr);
739f9765acdSGreg Clayton //
740f9765acdSGreg Clayton //                                if (::strstr (continue_cstr, "vAttach") == NULL)
741f9765acdSGreg Clayton //                                    process->SetPrivateState(eStateRunning);
742f9765acdSGreg Clayton //                                StringExtractor response;
743f9765acdSGreg Clayton //                                StateType stop_state = process->GetCommunication().SendContinuePacketAndWaitForResponse (process, continue_cstr, continue_cstr_len, response);
744f9765acdSGreg Clayton //
745f9765acdSGreg Clayton //                                switch (stop_state)
746f9765acdSGreg Clayton //                                {
747f9765acdSGreg Clayton //                                    case eStateStopped:
748f9765acdSGreg Clayton //                                    case eStateCrashed:
749f9765acdSGreg Clayton //                                    case eStateSuspended:
750f9765acdSGreg Clayton //                                        process->m_last_stop_packet = response;
751f9765acdSGreg Clayton //                                        process->SetPrivateState (stop_state);
752f9765acdSGreg Clayton //                                        break;
753f9765acdSGreg Clayton //
754f9765acdSGreg Clayton //                                    case eStateExited:
755f9765acdSGreg Clayton //                                        process->m_last_stop_packet = response;
756f9765acdSGreg Clayton //                                        response.SetFilePos(1);
757f9765acdSGreg Clayton //                                        process->SetExitStatus(response.GetHexU8(), NULL);
758f9765acdSGreg Clayton //                                        done = true;
759f9765acdSGreg Clayton //                                        break;
760f9765acdSGreg Clayton //
761f9765acdSGreg Clayton //                                    case eStateInvalid:
762f9765acdSGreg Clayton //                                        process->SetExitStatus(-1, "lost connection");
763f9765acdSGreg Clayton //                                        break;
764f9765acdSGreg Clayton //
765f9765acdSGreg Clayton //                                    default:
766f9765acdSGreg Clayton //                                        process->SetPrivateState (stop_state);
767f9765acdSGreg Clayton //                                        break;
768f9765acdSGreg Clayton //                                }
769f9765acdSGreg Clayton                             }
770f9765acdSGreg Clayton                         }
771f9765acdSGreg Clayton                             break;
772f9765acdSGreg Clayton 
773f9765acdSGreg Clayton                         case eBroadcastBitAsyncThreadShouldExit:
774f9765acdSGreg Clayton                             if (log)
775f9765acdSGreg Clayton                                 log->Printf ("ProcessKDP::%s (arg = %p, pid = %i) got eBroadcastBitAsyncThreadShouldExit...", __FUNCTION__, arg, process->GetID());
776f9765acdSGreg Clayton                             done = true;
777f9765acdSGreg Clayton                             break;
778f9765acdSGreg Clayton 
779f9765acdSGreg Clayton                         default:
780f9765acdSGreg Clayton                             if (log)
781f9765acdSGreg Clayton                                 log->Printf ("ProcessKDP::%s (arg = %p, pid = %i) got unknown event 0x%8.8x", __FUNCTION__, arg, process->GetID(), event_type);
782f9765acdSGreg Clayton                             done = true;
783f9765acdSGreg Clayton                             break;
784f9765acdSGreg Clayton                     }
785f9765acdSGreg Clayton                 }
786f9765acdSGreg Clayton                 else if (event_sp->BroadcasterIs (&process->m_comm))
787f9765acdSGreg Clayton                 {
788f9765acdSGreg Clayton                     if (event_type & Communication::eBroadcastBitReadThreadDidExit)
789f9765acdSGreg Clayton                     {
790f9765acdSGreg Clayton                         process->SetExitStatus (-1, "lost connection");
791f9765acdSGreg Clayton                         done = true;
792f9765acdSGreg Clayton                     }
793f9765acdSGreg Clayton                 }
794f9765acdSGreg Clayton             }
795f9765acdSGreg Clayton             else
796f9765acdSGreg Clayton             {
797f9765acdSGreg Clayton                 if (log)
798f9765acdSGreg Clayton                     log->Printf ("ProcessKDP::%s (arg = %p, pid = %i) listener.WaitForEvent (NULL, event_sp) => false", __FUNCTION__, arg, process->GetID());
799f9765acdSGreg Clayton                 done = true;
800f9765acdSGreg Clayton             }
801f9765acdSGreg Clayton         }
802f9765acdSGreg Clayton     }
803f9765acdSGreg Clayton 
804f9765acdSGreg Clayton     if (log)
805f9765acdSGreg Clayton         log->Printf ("ProcessKDP::%s (arg = %p, pid = %i) thread exiting...", __FUNCTION__, arg, process->GetID());
806f9765acdSGreg Clayton 
807f9765acdSGreg Clayton     process->m_async_thread = LLDB_INVALID_HOST_THREAD;
808f9765acdSGreg Clayton     return NULL;
809f9765acdSGreg Clayton }
810f9765acdSGreg Clayton 
811f9765acdSGreg Clayton 
812