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