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
62*aa149cbdSGreg Clayton     Module *exe_module = target.GetExecutableModulePointer();
63*aa149cbdSGreg 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         {
69*aa149cbdSGreg 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);
188a63d08c9SGreg Clayton                     UpdateThreadListIfNeeded ();
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)
269f9765acdSGreg Clayton         log->Printf ("ProcessKDP::DidLaunch()");
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
292f9765acdSGreg Clayton ProcessKDP::UpdateThreadListIfNeeded ()
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 
299f9765acdSGreg Clayton     Mutex::Locker locker (m_thread_list.GetMutex ());
300f9765acdSGreg Clayton     const uint32_t stop_id = GetStopID();
301a63d08c9SGreg Clayton     if (m_thread_list.GetSize(false) == 0)
302f9765acdSGreg Clayton     {
303a63d08c9SGreg Clayton         // We currently are making only one thread per core and we
304a63d08c9SGreg Clayton         // actually don't know about actual threads. Eventually we
305a63d08c9SGreg Clayton         // want to get the thread list from memory and note which
306a63d08c9SGreg Clayton         // threads are on CPU as those are the only ones that we
307a63d08c9SGreg Clayton         // will be able to resume.
308a63d08c9SGreg Clayton         ThreadList curr_thread_list (this);
309a63d08c9SGreg Clayton         curr_thread_list.SetStopID(stop_id);
310a63d08c9SGreg Clayton         const uint32_t cpu_mask = m_comm.GetCPUMask();
311a63d08c9SGreg Clayton         for (uint32_t cpu_mask_bit = 1; cpu_mask_bit & cpu_mask; cpu_mask_bit <<= 1)
312a63d08c9SGreg Clayton         {
313a63d08c9SGreg Clayton             // The thread ID is currently the CPU mask bit
314a63d08c9SGreg Clayton             ThreadSP thread_sp (new ThreadKDP (*this, cpu_mask_bit));
315a63d08c9SGreg Clayton                 curr_thread_list.AddThread(thread_sp);
316a63d08c9SGreg Clayton         }
317a63d08c9SGreg Clayton         m_thread_list = curr_thread_list;
318f9765acdSGreg Clayton     }
319f9765acdSGreg Clayton     return GetThreadList().GetSize(false);
320f9765acdSGreg Clayton }
321f9765acdSGreg Clayton 
322f9765acdSGreg Clayton 
323f9765acdSGreg Clayton StateType
324f9765acdSGreg Clayton ProcessKDP::SetThreadStopInfo (StringExtractor& stop_packet)
325f9765acdSGreg Clayton {
326f9765acdSGreg Clayton     // TODO: figure out why we stopped given the packet that tells us we stopped...
327f9765acdSGreg Clayton     return eStateStopped;
328f9765acdSGreg Clayton }
329f9765acdSGreg Clayton 
330f9765acdSGreg Clayton void
331f9765acdSGreg Clayton ProcessKDP::RefreshStateAfterStop ()
332f9765acdSGreg Clayton {
333f9765acdSGreg Clayton     // Let all threads recover from stopping and do any clean up based
334f9765acdSGreg Clayton     // on the previous thread state (if any).
335f9765acdSGreg Clayton     m_thread_list.RefreshStateAfterStop();
336f9765acdSGreg Clayton     //SetThreadStopInfo (m_last_stop_packet);
337f9765acdSGreg Clayton }
338f9765acdSGreg Clayton 
339f9765acdSGreg Clayton Error
340f9765acdSGreg Clayton ProcessKDP::DoHalt (bool &caused_stop)
341f9765acdSGreg Clayton {
342f9765acdSGreg Clayton     Error error;
343f9765acdSGreg Clayton 
344f9765acdSGreg Clayton //    bool timed_out = false;
345f9765acdSGreg Clayton     Mutex::Locker locker;
346f9765acdSGreg Clayton 
347f9765acdSGreg Clayton     if (m_public_state.GetValue() == eStateAttaching)
348f9765acdSGreg Clayton     {
349f9765acdSGreg Clayton         // We are being asked to halt during an attach. We need to just close
350f9765acdSGreg Clayton         // our file handle and debugserver will go away, and we can be done...
351f9765acdSGreg Clayton         m_comm.Disconnect();
352f9765acdSGreg Clayton     }
353f9765acdSGreg Clayton     else
354f9765acdSGreg Clayton     {
35507e66e3eSGreg Clayton         if (!m_comm.SendRequestSuspend ())
35607e66e3eSGreg Clayton             error.SetErrorString ("KDP halt failed");
357f9765acdSGreg Clayton     }
358f9765acdSGreg Clayton     return error;
359f9765acdSGreg Clayton }
360f9765acdSGreg Clayton 
361f9765acdSGreg Clayton Error
362f9765acdSGreg Clayton ProcessKDP::InterruptIfRunning (bool discard_thread_plans,
363f9765acdSGreg Clayton                                 bool catch_stop_event,
364f9765acdSGreg Clayton                                 EventSP &stop_event_sp)
365f9765acdSGreg Clayton {
366f9765acdSGreg Clayton     Error error;
367f9765acdSGreg Clayton 
368f9765acdSGreg Clayton     LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS));
369f9765acdSGreg Clayton 
370f9765acdSGreg Clayton     bool paused_private_state_thread = false;
371f9765acdSGreg Clayton     const bool is_running = m_comm.IsRunning();
372f9765acdSGreg Clayton     if (log)
373f9765acdSGreg Clayton         log->Printf ("ProcessKDP::InterruptIfRunning(discard_thread_plans=%i, catch_stop_event=%i) is_running=%i",
374f9765acdSGreg Clayton                      discard_thread_plans,
375f9765acdSGreg Clayton                      catch_stop_event,
376f9765acdSGreg Clayton                      is_running);
377f9765acdSGreg Clayton 
378f9765acdSGreg Clayton     if (discard_thread_plans)
379f9765acdSGreg Clayton     {
380f9765acdSGreg Clayton         if (log)
381f9765acdSGreg Clayton             log->Printf ("ProcessKDP::InterruptIfRunning() discarding all thread plans");
382f9765acdSGreg Clayton         m_thread_list.DiscardThreadPlans();
383f9765acdSGreg Clayton     }
384f9765acdSGreg Clayton     if (is_running)
385f9765acdSGreg Clayton     {
386f9765acdSGreg Clayton         if (catch_stop_event)
387f9765acdSGreg Clayton         {
388f9765acdSGreg Clayton             if (log)
389f9765acdSGreg Clayton                 log->Printf ("ProcessKDP::InterruptIfRunning() pausing private state thread");
390f9765acdSGreg Clayton             PausePrivateStateThread();
391f9765acdSGreg Clayton             paused_private_state_thread = true;
392f9765acdSGreg Clayton         }
393f9765acdSGreg Clayton 
394f9765acdSGreg Clayton         bool timed_out = false;
395f9765acdSGreg Clayton //        bool sent_interrupt = false;
396f9765acdSGreg Clayton         Mutex::Locker locker;
397f9765acdSGreg Clayton 
398f9765acdSGreg Clayton         // TODO: implement halt in CommunicationKDP
399f9765acdSGreg Clayton //        if (!m_comm.SendInterrupt (locker, 1, sent_interrupt, timed_out))
400f9765acdSGreg Clayton //        {
401f9765acdSGreg Clayton //            if (timed_out)
402f9765acdSGreg Clayton //                error.SetErrorString("timed out sending interrupt packet");
403f9765acdSGreg Clayton //            else
404f9765acdSGreg Clayton //                error.SetErrorString("unknown error sending interrupt packet");
405f9765acdSGreg Clayton //            if (paused_private_state_thread)
406f9765acdSGreg Clayton //                ResumePrivateStateThread();
407f9765acdSGreg Clayton //            return error;
408f9765acdSGreg Clayton //        }
409f9765acdSGreg Clayton 
410f9765acdSGreg Clayton         if (catch_stop_event)
411f9765acdSGreg Clayton         {
412f9765acdSGreg Clayton             // LISTEN HERE
413f9765acdSGreg Clayton             TimeValue timeout_time;
414f9765acdSGreg Clayton             timeout_time = TimeValue::Now();
415f9765acdSGreg Clayton             timeout_time.OffsetWithSeconds(5);
416f9765acdSGreg Clayton             StateType state = WaitForStateChangedEventsPrivate (&timeout_time, stop_event_sp);
417f9765acdSGreg Clayton 
418f9765acdSGreg Clayton             timed_out = state == eStateInvalid;
419f9765acdSGreg Clayton             if (log)
420f9765acdSGreg Clayton                 log->Printf ("ProcessKDP::InterruptIfRunning() catch stop event: state = %s, timed-out=%i", StateAsCString(state), timed_out);
421f9765acdSGreg Clayton 
422f9765acdSGreg Clayton             if (timed_out)
423f9765acdSGreg Clayton                 error.SetErrorString("unable to verify target stopped");
424f9765acdSGreg Clayton         }
425f9765acdSGreg Clayton 
426f9765acdSGreg Clayton         if (paused_private_state_thread)
427f9765acdSGreg Clayton         {
428f9765acdSGreg Clayton             if (log)
429f9765acdSGreg Clayton                 log->Printf ("ProcessKDP::InterruptIfRunning() resuming private state thread");
430f9765acdSGreg Clayton             ResumePrivateStateThread();
431f9765acdSGreg Clayton         }
432f9765acdSGreg Clayton     }
433f9765acdSGreg Clayton     return error;
434f9765acdSGreg Clayton }
435f9765acdSGreg Clayton 
436f9765acdSGreg Clayton Error
437f9765acdSGreg Clayton ProcessKDP::WillDetach ()
438f9765acdSGreg Clayton {
439f9765acdSGreg Clayton     LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS));
440f9765acdSGreg Clayton     if (log)
441f9765acdSGreg Clayton         log->Printf ("ProcessKDP::WillDetach()");
442f9765acdSGreg Clayton 
443f9765acdSGreg Clayton     bool discard_thread_plans = true;
444f9765acdSGreg Clayton     bool catch_stop_event = true;
445f9765acdSGreg Clayton     EventSP event_sp;
446f9765acdSGreg Clayton     return InterruptIfRunning (discard_thread_plans, catch_stop_event, event_sp);
447f9765acdSGreg Clayton }
448f9765acdSGreg Clayton 
449f9765acdSGreg Clayton Error
450f9765acdSGreg Clayton ProcessKDP::DoDetach()
451f9765acdSGreg Clayton {
452f9765acdSGreg Clayton     Error error;
453f9765acdSGreg Clayton     LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS));
454f9765acdSGreg Clayton     if (log)
455f9765acdSGreg Clayton         log->Printf ("ProcessKDP::DoDetach()");
456f9765acdSGreg Clayton 
457f9765acdSGreg Clayton     DisableAllBreakpointSites ();
458f9765acdSGreg Clayton 
459f9765acdSGreg Clayton     m_thread_list.DiscardThreadPlans();
460f9765acdSGreg Clayton 
4613a29bdbeSGreg Clayton     if (m_comm.IsConnected())
4623a29bdbeSGreg Clayton     {
4633a29bdbeSGreg Clayton 
4643a29bdbeSGreg Clayton         m_comm.SendRequestDisconnect();
4653a29bdbeSGreg Clayton 
46657508026SGreg Clayton         size_t response_size = m_comm.Disconnect ();
467f9765acdSGreg Clayton         if (log)
468f9765acdSGreg Clayton         {
469f9765acdSGreg Clayton             if (response_size)
470f9765acdSGreg Clayton                 log->PutCString ("ProcessKDP::DoDetach() detach packet sent successfully");
471f9765acdSGreg Clayton             else
472f9765acdSGreg Clayton                 log->PutCString ("ProcessKDP::DoDetach() detach packet send failed");
473f9765acdSGreg Clayton         }
4743a29bdbeSGreg Clayton     }
475f9765acdSGreg Clayton     // Sleep for one second to let the process get all detached...
476f9765acdSGreg Clayton     StopAsyncThread ();
477f9765acdSGreg Clayton 
478f9765acdSGreg Clayton     m_comm.StopReadThread();
479f9765acdSGreg Clayton     m_comm.Disconnect();    // Disconnect from the debug server.
480f9765acdSGreg Clayton 
481f9765acdSGreg Clayton     SetPrivateState (eStateDetached);
482f9765acdSGreg Clayton     ResumePrivateStateThread();
483f9765acdSGreg Clayton 
484f9765acdSGreg Clayton     //KillDebugserverProcess ();
485f9765acdSGreg Clayton     return error;
486f9765acdSGreg Clayton }
487f9765acdSGreg Clayton 
488f9765acdSGreg Clayton Error
489f9765acdSGreg Clayton ProcessKDP::DoDestroy ()
490f9765acdSGreg Clayton {
491f9765acdSGreg Clayton     Error error;
492f9765acdSGreg Clayton     LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS));
493f9765acdSGreg Clayton     if (log)
494f9765acdSGreg Clayton         log->Printf ("ProcessKDP::DoDestroy()");
495f9765acdSGreg Clayton 
496f9765acdSGreg Clayton     // Interrupt if our inferior is running...
497f9765acdSGreg Clayton     if (m_comm.IsConnected())
498f9765acdSGreg Clayton     {
499f9765acdSGreg Clayton         if (m_public_state.GetValue() == eStateAttaching)
500f9765acdSGreg Clayton         {
501f9765acdSGreg Clayton             // We are being asked to halt during an attach. We need to just close
502f9765acdSGreg Clayton             // our file handle and debugserver will go away, and we can be done...
503f9765acdSGreg Clayton             m_comm.Disconnect();
504f9765acdSGreg Clayton         }
505f9765acdSGreg Clayton         else
506f9765acdSGreg Clayton         {
5075b88216dSGreg Clayton             DisableAllBreakpointSites ();
5085b88216dSGreg Clayton 
5095b88216dSGreg Clayton             m_comm.SendRequestDisconnect();
510f9765acdSGreg Clayton 
511f9765acdSGreg Clayton             StringExtractor response;
512f9765acdSGreg Clayton             // TODO: Send kill packet?
513f9765acdSGreg Clayton             SetExitStatus(SIGABRT, NULL);
514f9765acdSGreg Clayton         }
515f9765acdSGreg Clayton     }
516f9765acdSGreg Clayton     StopAsyncThread ();
517f9765acdSGreg Clayton     m_comm.StopReadThread();
518f9765acdSGreg Clayton     m_comm.Disconnect();    // Disconnect from the debug server.
519f9765acdSGreg Clayton     return error;
520f9765acdSGreg Clayton }
521f9765acdSGreg Clayton 
522f9765acdSGreg Clayton //------------------------------------------------------------------
523f9765acdSGreg Clayton // Process Queries
524f9765acdSGreg Clayton //------------------------------------------------------------------
525f9765acdSGreg Clayton 
526f9765acdSGreg Clayton bool
527f9765acdSGreg Clayton ProcessKDP::IsAlive ()
528f9765acdSGreg Clayton {
529f9765acdSGreg Clayton     return m_comm.IsConnected() && m_private_state.GetValue() != eStateExited;
530f9765acdSGreg Clayton }
531f9765acdSGreg Clayton 
532f9765acdSGreg Clayton //------------------------------------------------------------------
533f9765acdSGreg Clayton // Process Memory
534f9765acdSGreg Clayton //------------------------------------------------------------------
535f9765acdSGreg Clayton size_t
536f9765acdSGreg Clayton ProcessKDP::DoReadMemory (addr_t addr, void *buf, size_t size, Error &error)
537f9765acdSGreg Clayton {
538a63d08c9SGreg Clayton     if (m_comm.IsConnected())
539a63d08c9SGreg Clayton         return m_comm.SendRequestReadMemory (addr, buf, size, error);
540a63d08c9SGreg Clayton     error.SetErrorString ("not connected");
541f9765acdSGreg Clayton     return 0;
542f9765acdSGreg Clayton }
543f9765acdSGreg Clayton 
544f9765acdSGreg Clayton size_t
545f9765acdSGreg Clayton ProcessKDP::DoWriteMemory (addr_t addr, const void *buf, size_t size, Error &error)
546f9765acdSGreg Clayton {
547f9765acdSGreg Clayton     error.SetErrorString ("ProcessKDP::DoReadMemory not implemented");
548f9765acdSGreg Clayton     return 0;
549f9765acdSGreg Clayton }
550f9765acdSGreg Clayton 
551f9765acdSGreg Clayton lldb::addr_t
552f9765acdSGreg Clayton ProcessKDP::DoAllocateMemory (size_t size, uint32_t permissions, Error &error)
553f9765acdSGreg Clayton {
554f9765acdSGreg Clayton     error.SetErrorString ("memory allocation not suppported in kdp remote debugging");
555f9765acdSGreg Clayton     return LLDB_INVALID_ADDRESS;
556f9765acdSGreg Clayton }
557f9765acdSGreg Clayton 
558f9765acdSGreg Clayton Error
559f9765acdSGreg Clayton ProcessKDP::DoDeallocateMemory (lldb::addr_t addr)
560f9765acdSGreg Clayton {
561f9765acdSGreg Clayton     Error error;
562f9765acdSGreg Clayton     error.SetErrorString ("memory deallocation not suppported in kdp remote debugging");
563f9765acdSGreg Clayton     return error;
564f9765acdSGreg Clayton }
565f9765acdSGreg Clayton 
566f9765acdSGreg Clayton Error
567f9765acdSGreg Clayton ProcessKDP::EnableBreakpoint (BreakpointSite *bp_site)
568f9765acdSGreg Clayton {
56907e66e3eSGreg Clayton     if (m_comm.LocalBreakpointsAreSupported ())
57007e66e3eSGreg Clayton     {
57107e66e3eSGreg Clayton         Error error;
5725b88216dSGreg Clayton         if (!bp_site->IsEnabled())
5735b88216dSGreg Clayton         {
5745b88216dSGreg Clayton             if (m_comm.SendRequestBreakpoint(true, bp_site->GetLoadAddress()))
5755b88216dSGreg Clayton             {
5765b88216dSGreg Clayton                 bp_site->SetEnabled(true);
5775b88216dSGreg Clayton                 bp_site->SetType (BreakpointSite::eExternal);
5785b88216dSGreg Clayton             }
5795b88216dSGreg Clayton             else
5805b88216dSGreg Clayton             {
58107e66e3eSGreg Clayton                 error.SetErrorString ("KDP set breakpoint failed");
5825b88216dSGreg Clayton             }
5835b88216dSGreg Clayton         }
58407e66e3eSGreg Clayton         return error;
58507e66e3eSGreg Clayton     }
586f9765acdSGreg Clayton     return EnableSoftwareBreakpoint (bp_site);
587f9765acdSGreg Clayton }
588f9765acdSGreg Clayton 
589f9765acdSGreg Clayton Error
590f9765acdSGreg Clayton ProcessKDP::DisableBreakpoint (BreakpointSite *bp_site)
591f9765acdSGreg Clayton {
59207e66e3eSGreg Clayton     if (m_comm.LocalBreakpointsAreSupported ())
59307e66e3eSGreg Clayton     {
59407e66e3eSGreg Clayton         Error error;
5955b88216dSGreg Clayton         if (bp_site->IsEnabled())
5965b88216dSGreg Clayton         {
5975b88216dSGreg Clayton             BreakpointSite::Type bp_type = bp_site->GetType();
5985b88216dSGreg Clayton             if (bp_type == BreakpointSite::eExternal)
5995b88216dSGreg Clayton             {
6005b88216dSGreg Clayton                 if (m_comm.SendRequestBreakpoint(false, bp_site->GetLoadAddress()))
6015b88216dSGreg Clayton                     bp_site->SetEnabled(false);
6025b88216dSGreg Clayton                 else
60307e66e3eSGreg Clayton                     error.SetErrorString ("KDP remove breakpoint failed");
6045b88216dSGreg Clayton             }
6055b88216dSGreg Clayton             else
6065b88216dSGreg Clayton             {
6075b88216dSGreg Clayton                 error = DisableSoftwareBreakpoint (bp_site);
6085b88216dSGreg Clayton             }
6095b88216dSGreg Clayton         }
61007e66e3eSGreg Clayton         return error;
61107e66e3eSGreg Clayton     }
612f9765acdSGreg Clayton     return DisableSoftwareBreakpoint (bp_site);
613f9765acdSGreg Clayton }
614f9765acdSGreg Clayton 
615f9765acdSGreg Clayton Error
616f9765acdSGreg Clayton ProcessKDP::EnableWatchpoint (WatchpointLocation *wp)
617f9765acdSGreg Clayton {
618f9765acdSGreg Clayton     Error error;
619f9765acdSGreg Clayton     error.SetErrorString ("watchpoints are not suppported in kdp remote debugging");
620f9765acdSGreg Clayton     return error;
621f9765acdSGreg Clayton }
622f9765acdSGreg Clayton 
623f9765acdSGreg Clayton Error
624f9765acdSGreg Clayton ProcessKDP::DisableWatchpoint (WatchpointLocation *wp)
625f9765acdSGreg Clayton {
626f9765acdSGreg Clayton     Error error;
627f9765acdSGreg Clayton     error.SetErrorString ("watchpoints are not suppported in kdp remote debugging");
628f9765acdSGreg Clayton     return error;
629f9765acdSGreg Clayton }
630f9765acdSGreg Clayton 
631f9765acdSGreg Clayton void
632f9765acdSGreg Clayton ProcessKDP::Clear()
633f9765acdSGreg Clayton {
634f9765acdSGreg Clayton     Mutex::Locker locker (m_thread_list.GetMutex ());
635f9765acdSGreg Clayton     m_thread_list.Clear();
636f9765acdSGreg Clayton }
637f9765acdSGreg Clayton 
638f9765acdSGreg Clayton Error
639f9765acdSGreg Clayton ProcessKDP::DoSignal (int signo)
640f9765acdSGreg Clayton {
641f9765acdSGreg Clayton     Error error;
642f9765acdSGreg Clayton     error.SetErrorString ("sending signals is not suppported in kdp remote debugging");
643f9765acdSGreg Clayton     return error;
644f9765acdSGreg Clayton }
645f9765acdSGreg Clayton 
646f9765acdSGreg Clayton void
647f9765acdSGreg Clayton ProcessKDP::Initialize()
648f9765acdSGreg Clayton {
649f9765acdSGreg Clayton     static bool g_initialized = false;
650f9765acdSGreg Clayton 
651f9765acdSGreg Clayton     if (g_initialized == false)
652f9765acdSGreg Clayton     {
653f9765acdSGreg Clayton         g_initialized = true;
654f9765acdSGreg Clayton         PluginManager::RegisterPlugin (GetPluginNameStatic(),
655f9765acdSGreg Clayton                                        GetPluginDescriptionStatic(),
656f9765acdSGreg Clayton                                        CreateInstance);
657f9765acdSGreg Clayton 
658f9765acdSGreg Clayton         Log::Callbacks log_callbacks = {
659f9765acdSGreg Clayton             ProcessKDPLog::DisableLog,
660f9765acdSGreg Clayton             ProcessKDPLog::EnableLog,
661f9765acdSGreg Clayton             ProcessKDPLog::ListLogCategories
662f9765acdSGreg Clayton         };
663f9765acdSGreg Clayton 
664f9765acdSGreg Clayton         Log::RegisterLogChannel (ProcessKDP::GetPluginNameStatic(), log_callbacks);
665f9765acdSGreg Clayton     }
666f9765acdSGreg Clayton }
667f9765acdSGreg Clayton 
668f9765acdSGreg Clayton bool
669f9765acdSGreg Clayton ProcessKDP::StartAsyncThread ()
670f9765acdSGreg Clayton {
671f9765acdSGreg Clayton     LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS));
672f9765acdSGreg Clayton 
673f9765acdSGreg Clayton     if (log)
674f9765acdSGreg Clayton         log->Printf ("ProcessKDP::%s ()", __FUNCTION__);
675f9765acdSGreg Clayton 
676f9765acdSGreg Clayton     // Create a thread that watches our internal state and controls which
677f9765acdSGreg Clayton     // events make it to clients (into the DCProcess event queue).
678f9765acdSGreg Clayton     m_async_thread = Host::ThreadCreate ("<lldb.process.kdp-remote.async>", ProcessKDP::AsyncThread, this, NULL);
679f9765acdSGreg Clayton     return IS_VALID_LLDB_HOST_THREAD(m_async_thread);
680f9765acdSGreg Clayton }
681f9765acdSGreg Clayton 
682f9765acdSGreg Clayton void
683f9765acdSGreg Clayton ProcessKDP::StopAsyncThread ()
684f9765acdSGreg Clayton {
685f9765acdSGreg Clayton     LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS));
686f9765acdSGreg Clayton 
687f9765acdSGreg Clayton     if (log)
688f9765acdSGreg Clayton         log->Printf ("ProcessKDP::%s ()", __FUNCTION__);
689f9765acdSGreg Clayton 
690f9765acdSGreg Clayton     m_async_broadcaster.BroadcastEvent (eBroadcastBitAsyncThreadShouldExit);
691f9765acdSGreg Clayton 
692f9765acdSGreg Clayton     // Stop the stdio thread
693f9765acdSGreg Clayton     if (IS_VALID_LLDB_HOST_THREAD(m_async_thread))
694f9765acdSGreg Clayton     {
695f9765acdSGreg Clayton         Host::ThreadJoin (m_async_thread, NULL, NULL);
696f9765acdSGreg Clayton     }
697f9765acdSGreg Clayton }
698f9765acdSGreg Clayton 
699f9765acdSGreg Clayton 
700f9765acdSGreg Clayton void *
701f9765acdSGreg Clayton ProcessKDP::AsyncThread (void *arg)
702f9765acdSGreg Clayton {
703f9765acdSGreg Clayton     ProcessKDP *process = (ProcessKDP*) arg;
704f9765acdSGreg Clayton 
705f9765acdSGreg Clayton     LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_PROCESS));
706f9765acdSGreg Clayton     if (log)
707f9765acdSGreg Clayton         log->Printf ("ProcessKDP::%s (arg = %p, pid = %i) thread starting...", __FUNCTION__, arg, process->GetID());
708f9765acdSGreg Clayton 
709f9765acdSGreg Clayton     Listener listener ("ProcessKDP::AsyncThread");
710f9765acdSGreg Clayton     EventSP event_sp;
711f9765acdSGreg Clayton     const uint32_t desired_event_mask = eBroadcastBitAsyncContinue |
712f9765acdSGreg Clayton                                         eBroadcastBitAsyncThreadShouldExit;
713f9765acdSGreg Clayton 
714f9765acdSGreg Clayton     if (listener.StartListeningForEvents (&process->m_async_broadcaster, desired_event_mask) == desired_event_mask)
715f9765acdSGreg Clayton     {
716f9765acdSGreg Clayton         listener.StartListeningForEvents (&process->m_comm, Communication::eBroadcastBitReadThreadDidExit);
717f9765acdSGreg Clayton 
718f9765acdSGreg Clayton         bool done = false;
719f9765acdSGreg Clayton         while (!done)
720f9765acdSGreg Clayton         {
721f9765acdSGreg Clayton             if (log)
722f9765acdSGreg Clayton                 log->Printf ("ProcessKDP::%s (arg = %p, pid = %i) listener.WaitForEvent (NULL, event_sp)...", __FUNCTION__, arg, process->GetID());
723f9765acdSGreg Clayton             if (listener.WaitForEvent (NULL, event_sp))
724f9765acdSGreg Clayton             {
725f9765acdSGreg Clayton                 const uint32_t event_type = event_sp->GetType();
726f9765acdSGreg Clayton                 if (event_sp->BroadcasterIs (&process->m_async_broadcaster))
727f9765acdSGreg Clayton                 {
728f9765acdSGreg Clayton                     if (log)
729f9765acdSGreg Clayton                         log->Printf ("ProcessKDP::%s (arg = %p, pid = %i) Got an event of type: %d...", __FUNCTION__, arg, process->GetID(), event_type);
730f9765acdSGreg Clayton 
731f9765acdSGreg Clayton                     switch (event_type)
732f9765acdSGreg Clayton                     {
733f9765acdSGreg Clayton                         case eBroadcastBitAsyncContinue:
734f9765acdSGreg Clayton                         {
735f9765acdSGreg Clayton                             const EventDataBytes *continue_packet = EventDataBytes::GetEventDataFromEvent(event_sp.get());
736f9765acdSGreg Clayton 
737f9765acdSGreg Clayton                             if (continue_packet)
738f9765acdSGreg Clayton                             {
739f9765acdSGreg Clayton                                 // TODO: do continue support here
740f9765acdSGreg Clayton 
741f9765acdSGreg Clayton //                                const char *continue_cstr = (const char *)continue_packet->GetBytes ();
742f9765acdSGreg Clayton //                                const size_t continue_cstr_len = continue_packet->GetByteSize ();
743f9765acdSGreg Clayton //                                if (log)
744f9765acdSGreg Clayton //                                    log->Printf ("ProcessKDP::%s (arg = %p, pid = %i) got eBroadcastBitAsyncContinue: %s", __FUNCTION__, arg, process->GetID(), continue_cstr);
745f9765acdSGreg Clayton //
746f9765acdSGreg Clayton //                                if (::strstr (continue_cstr, "vAttach") == NULL)
747f9765acdSGreg Clayton //                                    process->SetPrivateState(eStateRunning);
748f9765acdSGreg Clayton //                                StringExtractor response;
749f9765acdSGreg Clayton //                                StateType stop_state = process->GetCommunication().SendContinuePacketAndWaitForResponse (process, continue_cstr, continue_cstr_len, response);
750f9765acdSGreg Clayton //
751f9765acdSGreg Clayton //                                switch (stop_state)
752f9765acdSGreg Clayton //                                {
753f9765acdSGreg Clayton //                                    case eStateStopped:
754f9765acdSGreg Clayton //                                    case eStateCrashed:
755f9765acdSGreg Clayton //                                    case eStateSuspended:
756f9765acdSGreg Clayton //                                        process->m_last_stop_packet = response;
757f9765acdSGreg Clayton //                                        process->SetPrivateState (stop_state);
758f9765acdSGreg Clayton //                                        break;
759f9765acdSGreg Clayton //
760f9765acdSGreg Clayton //                                    case eStateExited:
761f9765acdSGreg Clayton //                                        process->m_last_stop_packet = response;
762f9765acdSGreg Clayton //                                        response.SetFilePos(1);
763f9765acdSGreg Clayton //                                        process->SetExitStatus(response.GetHexU8(), NULL);
764f9765acdSGreg Clayton //                                        done = true;
765f9765acdSGreg Clayton //                                        break;
766f9765acdSGreg Clayton //
767f9765acdSGreg Clayton //                                    case eStateInvalid:
768f9765acdSGreg Clayton //                                        process->SetExitStatus(-1, "lost connection");
769f9765acdSGreg Clayton //                                        break;
770f9765acdSGreg Clayton //
771f9765acdSGreg Clayton //                                    default:
772f9765acdSGreg Clayton //                                        process->SetPrivateState (stop_state);
773f9765acdSGreg Clayton //                                        break;
774f9765acdSGreg Clayton //                                }
775f9765acdSGreg Clayton                             }
776f9765acdSGreg Clayton                         }
777f9765acdSGreg Clayton                             break;
778f9765acdSGreg Clayton 
779f9765acdSGreg Clayton                         case eBroadcastBitAsyncThreadShouldExit:
780f9765acdSGreg Clayton                             if (log)
781f9765acdSGreg Clayton                                 log->Printf ("ProcessKDP::%s (arg = %p, pid = %i) got eBroadcastBitAsyncThreadShouldExit...", __FUNCTION__, arg, process->GetID());
782f9765acdSGreg Clayton                             done = true;
783f9765acdSGreg Clayton                             break;
784f9765acdSGreg Clayton 
785f9765acdSGreg Clayton                         default:
786f9765acdSGreg Clayton                             if (log)
787f9765acdSGreg Clayton                                 log->Printf ("ProcessKDP::%s (arg = %p, pid = %i) got unknown event 0x%8.8x", __FUNCTION__, arg, process->GetID(), event_type);
788f9765acdSGreg Clayton                             done = true;
789f9765acdSGreg Clayton                             break;
790f9765acdSGreg Clayton                     }
791f9765acdSGreg Clayton                 }
792f9765acdSGreg Clayton                 else if (event_sp->BroadcasterIs (&process->m_comm))
793f9765acdSGreg Clayton                 {
794f9765acdSGreg Clayton                     if (event_type & Communication::eBroadcastBitReadThreadDidExit)
795f9765acdSGreg Clayton                     {
796f9765acdSGreg Clayton                         process->SetExitStatus (-1, "lost connection");
797f9765acdSGreg Clayton                         done = true;
798f9765acdSGreg Clayton                     }
799f9765acdSGreg Clayton                 }
800f9765acdSGreg Clayton             }
801f9765acdSGreg Clayton             else
802f9765acdSGreg Clayton             {
803f9765acdSGreg Clayton                 if (log)
804f9765acdSGreg Clayton                     log->Printf ("ProcessKDP::%s (arg = %p, pid = %i) listener.WaitForEvent (NULL, event_sp) => false", __FUNCTION__, arg, process->GetID());
805f9765acdSGreg Clayton                 done = true;
806f9765acdSGreg Clayton             }
807f9765acdSGreg Clayton         }
808f9765acdSGreg Clayton     }
809f9765acdSGreg Clayton 
810f9765acdSGreg Clayton     if (log)
811f9765acdSGreg Clayton         log->Printf ("ProcessKDP::%s (arg = %p, pid = %i) thread exiting...", __FUNCTION__, arg, process->GetID());
812f9765acdSGreg Clayton 
813f9765acdSGreg Clayton     process->m_async_thread = LLDB_INVALID_HOST_THREAD;
814f9765acdSGreg Clayton     return NULL;
815f9765acdSGreg Clayton }
816f9765acdSGreg Clayton 
817f9765acdSGreg Clayton 
818