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 
52c3776bf2SGreg Clayton lldb::ProcessSP
53c3776bf2SGreg Clayton ProcessKDP::CreateInstance (Target &target,
54c3776bf2SGreg Clayton                             Listener &listener,
55c3776bf2SGreg Clayton                             const FileSpec *crash_file_path)
56f9765acdSGreg Clayton {
57c3776bf2SGreg Clayton     lldb::ProcessSP process_sp;
58c3776bf2SGreg Clayton     if (crash_file_path == NULL)
59c3776bf2SGreg Clayton         process_sp.reset(new ProcessKDP (target, listener));
60c3776bf2SGreg Clayton     return process_sp;
61f9765acdSGreg Clayton }
62f9765acdSGreg Clayton 
63f9765acdSGreg Clayton bool
643a29bdbeSGreg Clayton ProcessKDP::CanDebug(Target &target, bool plugin_specified_by_name)
65f9765acdSGreg Clayton {
66596ed24eSGreg Clayton     if (plugin_specified_by_name)
67596ed24eSGreg Clayton         return true;
68596ed24eSGreg Clayton 
69f9765acdSGreg Clayton     // For now we are just making sure the file exists for a given module
70aa149cbdSGreg Clayton     Module *exe_module = target.GetExecutableModulePointer();
71aa149cbdSGreg Clayton     if (exe_module)
72f9765acdSGreg Clayton     {
73f9765acdSGreg Clayton         const llvm::Triple &triple_ref = target.GetArchitecture().GetTriple();
74f9765acdSGreg Clayton         if (triple_ref.getOS() == llvm::Triple::Darwin &&
75f9765acdSGreg Clayton             triple_ref.getVendor() == llvm::Triple::Apple)
76f9765acdSGreg Clayton         {
77aa149cbdSGreg Clayton             ObjectFile *exe_objfile = exe_module->GetObjectFile();
78f9765acdSGreg Clayton             if (exe_objfile->GetType() == ObjectFile::eTypeExecutable &&
79f9765acdSGreg Clayton                 exe_objfile->GetStrata() == ObjectFile::eStrataKernel)
80f9765acdSGreg Clayton                 return true;
81f9765acdSGreg Clayton         }
82f9765acdSGreg Clayton     }
83596ed24eSGreg Clayton     return false;
843a29bdbeSGreg Clayton }
85f9765acdSGreg Clayton 
86f9765acdSGreg Clayton //----------------------------------------------------------------------
87f9765acdSGreg Clayton // ProcessKDP constructor
88f9765acdSGreg Clayton //----------------------------------------------------------------------
89f9765acdSGreg Clayton ProcessKDP::ProcessKDP(Target& target, Listener &listener) :
90f9765acdSGreg Clayton     Process (target, listener),
91f9765acdSGreg Clayton     m_comm("lldb.process.kdp-remote.communication"),
92*4bddaeb5SJim Ingham     m_async_broadcaster (NULL, "lldb.process.kdp-remote.async-broadcaster"),
93f9765acdSGreg Clayton     m_async_thread (LLDB_INVALID_HOST_THREAD)
94f9765acdSGreg Clayton {
95f9765acdSGreg Clayton //    m_async_broadcaster.SetEventName (eBroadcastBitAsyncThreadShouldExit,   "async thread should exit");
96f9765acdSGreg Clayton //    m_async_broadcaster.SetEventName (eBroadcastBitAsyncContinue,           "async thread continue");
97f9765acdSGreg Clayton }
98f9765acdSGreg Clayton 
99f9765acdSGreg Clayton //----------------------------------------------------------------------
100f9765acdSGreg Clayton // Destructor
101f9765acdSGreg Clayton //----------------------------------------------------------------------
102f9765acdSGreg Clayton ProcessKDP::~ProcessKDP()
103f9765acdSGreg Clayton {
104f9765acdSGreg Clayton     Clear();
105e24c4acfSGreg Clayton     // We need to call finalize on the process before destroying ourselves
106e24c4acfSGreg Clayton     // to make sure all of the broadcaster cleanup goes as planned. If we
107e24c4acfSGreg Clayton     // destruct this class, then Process::~Process() might have problems
108e24c4acfSGreg Clayton     // trying to fully destroy the broadcaster.
109e24c4acfSGreg Clayton     Finalize();
110f9765acdSGreg Clayton }
111f9765acdSGreg Clayton 
112f9765acdSGreg Clayton //----------------------------------------------------------------------
113f9765acdSGreg Clayton // PluginInterface
114f9765acdSGreg Clayton //----------------------------------------------------------------------
115f9765acdSGreg Clayton const char *
116f9765acdSGreg Clayton ProcessKDP::GetPluginName()
117f9765acdSGreg Clayton {
118f9765acdSGreg Clayton     return "Process debugging plug-in that uses the Darwin KDP remote protocol";
119f9765acdSGreg Clayton }
120f9765acdSGreg Clayton 
121f9765acdSGreg Clayton const char *
122f9765acdSGreg Clayton ProcessKDP::GetShortPluginName()
123f9765acdSGreg Clayton {
124f9765acdSGreg Clayton     return GetPluginNameStatic();
125f9765acdSGreg Clayton }
126f9765acdSGreg Clayton 
127f9765acdSGreg Clayton uint32_t
128f9765acdSGreg Clayton ProcessKDP::GetPluginVersion()
129f9765acdSGreg Clayton {
130f9765acdSGreg Clayton     return 1;
131f9765acdSGreg Clayton }
132f9765acdSGreg Clayton 
133f9765acdSGreg Clayton Error
134f9765acdSGreg Clayton ProcessKDP::WillLaunch (Module* module)
135f9765acdSGreg Clayton {
136f9765acdSGreg Clayton     Error error;
137f9765acdSGreg Clayton     error.SetErrorString ("launching not supported in kdp-remote plug-in");
138f9765acdSGreg Clayton     return error;
139f9765acdSGreg Clayton }
140f9765acdSGreg Clayton 
141f9765acdSGreg Clayton Error
142f9765acdSGreg Clayton ProcessKDP::WillAttachToProcessWithID (lldb::pid_t pid)
143f9765acdSGreg Clayton {
144f9765acdSGreg Clayton     Error error;
145f9765acdSGreg Clayton     error.SetErrorString ("attaching to a by process ID not supported in kdp-remote plug-in");
146f9765acdSGreg Clayton     return error;
147f9765acdSGreg Clayton }
148f9765acdSGreg Clayton 
149f9765acdSGreg Clayton Error
150f9765acdSGreg Clayton ProcessKDP::WillAttachToProcessWithName (const char *process_name, bool wait_for_launch)
151f9765acdSGreg Clayton {
152f9765acdSGreg Clayton     Error error;
153f9765acdSGreg Clayton     error.SetErrorString ("attaching to a by process name not supported in kdp-remote plug-in");
154f9765acdSGreg Clayton     return error;
155f9765acdSGreg Clayton }
156f9765acdSGreg Clayton 
157f9765acdSGreg Clayton Error
158f9765acdSGreg Clayton ProcessKDP::DoConnectRemote (const char *remote_url)
159f9765acdSGreg Clayton {
160f9765acdSGreg Clayton     // TODO: fill in the remote connection to the remote KDP here!
161f9765acdSGreg Clayton     Error error;
1623a29bdbeSGreg Clayton 
1633a29bdbeSGreg Clayton     if (remote_url == NULL || remote_url[0] == '\0')
1643a29bdbeSGreg Clayton         remote_url = "udp://localhost:41139";
1653a29bdbeSGreg Clayton 
1663a29bdbeSGreg Clayton     std::auto_ptr<ConnectionFileDescriptor> conn_ap(new ConnectionFileDescriptor());
1673a29bdbeSGreg Clayton     if (conn_ap.get())
1683a29bdbeSGreg Clayton     {
1693a29bdbeSGreg Clayton         // Only try once for now.
1703a29bdbeSGreg Clayton         // TODO: check if we should be retrying?
1713a29bdbeSGreg Clayton         const uint32_t max_retry_count = 1;
1723a29bdbeSGreg Clayton         for (uint32_t retry_count = 0; retry_count < max_retry_count; ++retry_count)
1733a29bdbeSGreg Clayton         {
1743a29bdbeSGreg Clayton             if (conn_ap->Connect(remote_url, &error) == eConnectionStatusSuccess)
1753a29bdbeSGreg Clayton                 break;
1763a29bdbeSGreg Clayton             usleep (100000);
1773a29bdbeSGreg Clayton         }
1783a29bdbeSGreg Clayton     }
1793a29bdbeSGreg Clayton 
1803a29bdbeSGreg Clayton     if (conn_ap->IsConnected())
1813a29bdbeSGreg Clayton     {
1823a29bdbeSGreg Clayton         const uint16_t reply_port = conn_ap->GetReadPort ();
1833a29bdbeSGreg Clayton 
1843a29bdbeSGreg Clayton         if (reply_port != 0)
1853a29bdbeSGreg Clayton         {
1863a29bdbeSGreg Clayton             m_comm.SetConnection(conn_ap.release());
1873a29bdbeSGreg Clayton 
1883a29bdbeSGreg Clayton             if (m_comm.SendRequestReattach(reply_port))
1893a29bdbeSGreg Clayton             {
1903a29bdbeSGreg Clayton                 if (m_comm.SendRequestConnect(reply_port, reply_port, "Greetings from LLDB..."))
1913a29bdbeSGreg Clayton                 {
1923a29bdbeSGreg Clayton                     m_comm.GetVersion();
1933a29bdbeSGreg Clayton                     uint32_t cpu = m_comm.GetCPUType();
1943a29bdbeSGreg Clayton                     uint32_t sub = m_comm.GetCPUSubtype();
1953a29bdbeSGreg Clayton                     ArchSpec kernel_arch;
1963a29bdbeSGreg Clayton                     kernel_arch.SetArchitecture(eArchTypeMachO, cpu, sub);
1973a29bdbeSGreg Clayton                     m_target.SetArchitecture(kernel_arch);
198a63d08c9SGreg Clayton                     SetID (1);
19956d9a1b3SGreg Clayton                     GetThreadList ();
200a63d08c9SGreg Clayton                     SetPrivateState (eStateStopped);
20107e66e3eSGreg Clayton                     StreamSP async_strm_sp(m_target.GetDebugger().GetAsyncOutputStream());
20207e66e3eSGreg Clayton                     if (async_strm_sp)
20307e66e3eSGreg Clayton                     {
2045b88216dSGreg Clayton                         const char *cstr;
2055b88216dSGreg Clayton                         if ((cstr = m_comm.GetKernelVersion ()) != NULL)
20607e66e3eSGreg Clayton                         {
2075b88216dSGreg Clayton                             async_strm_sp->Printf ("Version: %s\n", cstr);
20807e66e3eSGreg Clayton                             async_strm_sp->Flush();
20907e66e3eSGreg Clayton                         }
2105b88216dSGreg Clayton //                      if ((cstr = m_comm.GetImagePath ()) != NULL)
2115b88216dSGreg Clayton //                      {
2125b88216dSGreg Clayton //                          async_strm_sp->Printf ("Image Path: %s\n", cstr);
2135b88216dSGreg Clayton //                          async_strm_sp->Flush();
2145b88216dSGreg Clayton //                      }
21507e66e3eSGreg Clayton                     }
2163a29bdbeSGreg Clayton                 }
2173a29bdbeSGreg Clayton             }
2183a29bdbeSGreg Clayton             else
2193a29bdbeSGreg Clayton             {
2203a29bdbeSGreg Clayton                 error.SetErrorString("KDP reattach failed");
2213a29bdbeSGreg Clayton             }
2223a29bdbeSGreg Clayton         }
2233a29bdbeSGreg Clayton         else
2243a29bdbeSGreg Clayton         {
2253a29bdbeSGreg Clayton             error.SetErrorString("invalid reply port from UDP connection");
2263a29bdbeSGreg Clayton         }
2273a29bdbeSGreg Clayton     }
2283a29bdbeSGreg Clayton     else
2293a29bdbeSGreg Clayton     {
2303a29bdbeSGreg Clayton         if (error.Success())
2313a29bdbeSGreg Clayton             error.SetErrorStringWithFormat ("failed to connect to '%s'", remote_url);
2323a29bdbeSGreg Clayton     }
2333a29bdbeSGreg Clayton     if (error.Fail())
2343a29bdbeSGreg Clayton         m_comm.Disconnect();
2353a29bdbeSGreg Clayton 
236f9765acdSGreg Clayton     return error;
237f9765acdSGreg Clayton }
238f9765acdSGreg Clayton 
239f9765acdSGreg Clayton //----------------------------------------------------------------------
240f9765acdSGreg Clayton // Process Control
241f9765acdSGreg Clayton //----------------------------------------------------------------------
242f9765acdSGreg Clayton Error
243982c9762SGreg Clayton ProcessKDP::DoLaunch (Module *exe_module,
244982c9762SGreg Clayton                       const ProcessLaunchInfo &launch_info)
245f9765acdSGreg Clayton {
246f9765acdSGreg Clayton     Error error;
247f9765acdSGreg Clayton     error.SetErrorString ("launching not supported in kdp-remote plug-in");
248f9765acdSGreg Clayton     return error;
249f9765acdSGreg Clayton }
250f9765acdSGreg Clayton 
251f9765acdSGreg Clayton 
252f9765acdSGreg Clayton Error
253f9765acdSGreg Clayton ProcessKDP::DoAttachToProcessWithID (lldb::pid_t attach_pid)
254f9765acdSGreg Clayton {
255f9765acdSGreg Clayton     Error error;
256f9765acdSGreg Clayton     error.SetErrorString ("attach to process by ID is not suppported in kdp remote debugging");
257f9765acdSGreg Clayton     return error;
258f9765acdSGreg Clayton }
259f9765acdSGreg Clayton 
260f9765acdSGreg Clayton Error
261f9765acdSGreg Clayton ProcessKDP::DoAttachToProcessWithName (const char *process_name, bool wait_for_launch)
262f9765acdSGreg Clayton {
263f9765acdSGreg Clayton     Error error;
264f9765acdSGreg Clayton     error.SetErrorString ("attach to process by name is not suppported in kdp remote debugging");
265f9765acdSGreg Clayton     return error;
266f9765acdSGreg Clayton }
267f9765acdSGreg Clayton 
268f9765acdSGreg Clayton 
269f9765acdSGreg Clayton void
270f9765acdSGreg Clayton ProcessKDP::DidAttach ()
271f9765acdSGreg Clayton {
272f9765acdSGreg Clayton     LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_PROCESS));
273f9765acdSGreg Clayton     if (log)
27454cb8f83SJohnny Chen         log->Printf ("ProcessKDP::DidAttach()");
275f9765acdSGreg Clayton     if (GetID() != LLDB_INVALID_PROCESS_ID)
276f9765acdSGreg Clayton     {
277f9765acdSGreg Clayton         // TODO: figure out the register context that we will use
278f9765acdSGreg Clayton     }
279f9765acdSGreg Clayton }
280f9765acdSGreg Clayton 
281f9765acdSGreg Clayton Error
282f9765acdSGreg Clayton ProcessKDP::WillResume ()
283f9765acdSGreg Clayton {
284f9765acdSGreg Clayton     return Error();
285f9765acdSGreg Clayton }
286f9765acdSGreg Clayton 
287f9765acdSGreg Clayton Error
288f9765acdSGreg Clayton ProcessKDP::DoResume ()
289f9765acdSGreg Clayton {
290f9765acdSGreg Clayton     Error error;
29107e66e3eSGreg Clayton     if (!m_comm.SendRequestResume ())
29207e66e3eSGreg Clayton         error.SetErrorString ("KDP resume failed");
293f9765acdSGreg Clayton     return error;
294f9765acdSGreg Clayton }
295f9765acdSGreg Clayton 
296f9765acdSGreg Clayton uint32_t
29756d9a1b3SGreg Clayton ProcessKDP::UpdateThreadList (ThreadList &old_thread_list, ThreadList &new_thread_list)
298f9765acdSGreg Clayton {
299f9765acdSGreg Clayton     // locker will keep a mutex locked until it goes out of scope
300f9765acdSGreg Clayton     LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_THREAD));
301f9765acdSGreg Clayton     if (log && log->GetMask().Test(KDP_LOG_VERBOSE))
30281c22f61SGreg Clayton         log->Printf ("ProcessKDP::%s (pid = %llu)", __FUNCTION__, GetID());
303f9765acdSGreg Clayton 
304a63d08c9SGreg Clayton     // We currently are making only one thread per core and we
305a63d08c9SGreg Clayton     // actually don't know about actual threads. Eventually we
306a63d08c9SGreg Clayton     // want to get the thread list from memory and note which
307a63d08c9SGreg Clayton     // threads are on CPU as those are the only ones that we
308a63d08c9SGreg Clayton     // will be able to resume.
309a63d08c9SGreg Clayton     const uint32_t cpu_mask = m_comm.GetCPUMask();
310a63d08c9SGreg Clayton     for (uint32_t cpu_mask_bit = 1; cpu_mask_bit & cpu_mask; cpu_mask_bit <<= 1)
311a63d08c9SGreg Clayton     {
31256d9a1b3SGreg Clayton         lldb::tid_t tid = cpu_mask_bit;
31356d9a1b3SGreg Clayton         ThreadSP thread_sp (old_thread_list.FindThreadByID (tid, false));
31456d9a1b3SGreg Clayton         if (!thread_sp)
31556d9a1b3SGreg Clayton             thread_sp.reset(new ThreadKDP (*this, tid));
31656d9a1b3SGreg Clayton         new_thread_list.AddThread(thread_sp);
317a63d08c9SGreg Clayton     }
31856d9a1b3SGreg Clayton     return new_thread_list.GetSize(false);
319f9765acdSGreg Clayton }
320f9765acdSGreg Clayton 
321f9765acdSGreg Clayton 
322f9765acdSGreg Clayton StateType
323f9765acdSGreg Clayton ProcessKDP::SetThreadStopInfo (StringExtractor& stop_packet)
324f9765acdSGreg Clayton {
325f9765acdSGreg Clayton     // TODO: figure out why we stopped given the packet that tells us we stopped...
326f9765acdSGreg Clayton     return eStateStopped;
327f9765acdSGreg Clayton }
328f9765acdSGreg Clayton 
329f9765acdSGreg Clayton void
330f9765acdSGreg Clayton ProcessKDP::RefreshStateAfterStop ()
331f9765acdSGreg Clayton {
332f9765acdSGreg Clayton     // Let all threads recover from stopping and do any clean up based
333f9765acdSGreg Clayton     // on the previous thread state (if any).
334f9765acdSGreg Clayton     m_thread_list.RefreshStateAfterStop();
335f9765acdSGreg Clayton     //SetThreadStopInfo (m_last_stop_packet);
336f9765acdSGreg Clayton }
337f9765acdSGreg Clayton 
338f9765acdSGreg Clayton Error
339f9765acdSGreg Clayton ProcessKDP::DoHalt (bool &caused_stop)
340f9765acdSGreg Clayton {
341f9765acdSGreg Clayton     Error error;
342f9765acdSGreg Clayton 
343f9765acdSGreg Clayton //    bool timed_out = false;
344f9765acdSGreg Clayton     Mutex::Locker locker;
345f9765acdSGreg Clayton 
346f9765acdSGreg Clayton     if (m_public_state.GetValue() == eStateAttaching)
347f9765acdSGreg Clayton     {
348f9765acdSGreg Clayton         // We are being asked to halt during an attach. We need to just close
349f9765acdSGreg Clayton         // our file handle and debugserver will go away, and we can be done...
350f9765acdSGreg Clayton         m_comm.Disconnect();
351f9765acdSGreg Clayton     }
352f9765acdSGreg Clayton     else
353f9765acdSGreg Clayton     {
35407e66e3eSGreg Clayton         if (!m_comm.SendRequestSuspend ())
35507e66e3eSGreg Clayton             error.SetErrorString ("KDP halt failed");
356f9765acdSGreg Clayton     }
357f9765acdSGreg Clayton     return error;
358f9765acdSGreg Clayton }
359f9765acdSGreg Clayton 
360f9765acdSGreg Clayton Error
361f9765acdSGreg Clayton ProcessKDP::InterruptIfRunning (bool discard_thread_plans,
362f9765acdSGreg Clayton                                 bool catch_stop_event,
363f9765acdSGreg Clayton                                 EventSP &stop_event_sp)
364f9765acdSGreg Clayton {
365f9765acdSGreg Clayton     Error error;
366f9765acdSGreg Clayton 
367f9765acdSGreg Clayton     LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS));
368f9765acdSGreg Clayton 
369f9765acdSGreg Clayton     bool paused_private_state_thread = false;
370f9765acdSGreg Clayton     const bool is_running = m_comm.IsRunning();
371f9765acdSGreg Clayton     if (log)
372f9765acdSGreg Clayton         log->Printf ("ProcessKDP::InterruptIfRunning(discard_thread_plans=%i, catch_stop_event=%i) is_running=%i",
373f9765acdSGreg Clayton                      discard_thread_plans,
374f9765acdSGreg Clayton                      catch_stop_event,
375f9765acdSGreg Clayton                      is_running);
376f9765acdSGreg Clayton 
377f9765acdSGreg Clayton     if (discard_thread_plans)
378f9765acdSGreg Clayton     {
379f9765acdSGreg Clayton         if (log)
380f9765acdSGreg Clayton             log->Printf ("ProcessKDP::InterruptIfRunning() discarding all thread plans");
381f9765acdSGreg Clayton         m_thread_list.DiscardThreadPlans();
382f9765acdSGreg Clayton     }
383f9765acdSGreg Clayton     if (is_running)
384f9765acdSGreg Clayton     {
385f9765acdSGreg Clayton         if (catch_stop_event)
386f9765acdSGreg Clayton         {
387f9765acdSGreg Clayton             if (log)
388f9765acdSGreg Clayton                 log->Printf ("ProcessKDP::InterruptIfRunning() pausing private state thread");
389f9765acdSGreg Clayton             PausePrivateStateThread();
390f9765acdSGreg Clayton             paused_private_state_thread = true;
391f9765acdSGreg Clayton         }
392f9765acdSGreg Clayton 
393f9765acdSGreg Clayton         bool timed_out = false;
394f9765acdSGreg Clayton //        bool sent_interrupt = false;
395f9765acdSGreg Clayton         Mutex::Locker locker;
396f9765acdSGreg Clayton 
397f9765acdSGreg Clayton         // TODO: implement halt in CommunicationKDP
398f9765acdSGreg Clayton //        if (!m_comm.SendInterrupt (locker, 1, sent_interrupt, timed_out))
399f9765acdSGreg Clayton //        {
400f9765acdSGreg Clayton //            if (timed_out)
401f9765acdSGreg Clayton //                error.SetErrorString("timed out sending interrupt packet");
402f9765acdSGreg Clayton //            else
403f9765acdSGreg Clayton //                error.SetErrorString("unknown error sending interrupt packet");
404f9765acdSGreg Clayton //            if (paused_private_state_thread)
405f9765acdSGreg Clayton //                ResumePrivateStateThread();
406f9765acdSGreg Clayton //            return error;
407f9765acdSGreg Clayton //        }
408f9765acdSGreg Clayton 
409f9765acdSGreg Clayton         if (catch_stop_event)
410f9765acdSGreg Clayton         {
411f9765acdSGreg Clayton             // LISTEN HERE
412f9765acdSGreg Clayton             TimeValue timeout_time;
413f9765acdSGreg Clayton             timeout_time = TimeValue::Now();
414f9765acdSGreg Clayton             timeout_time.OffsetWithSeconds(5);
415f9765acdSGreg Clayton             StateType state = WaitForStateChangedEventsPrivate (&timeout_time, stop_event_sp);
416f9765acdSGreg Clayton 
417f9765acdSGreg Clayton             timed_out = state == eStateInvalid;
418f9765acdSGreg Clayton             if (log)
419f9765acdSGreg Clayton                 log->Printf ("ProcessKDP::InterruptIfRunning() catch stop event: state = %s, timed-out=%i", StateAsCString(state), timed_out);
420f9765acdSGreg Clayton 
421f9765acdSGreg Clayton             if (timed_out)
422f9765acdSGreg Clayton                 error.SetErrorString("unable to verify target stopped");
423f9765acdSGreg Clayton         }
424f9765acdSGreg Clayton 
425f9765acdSGreg Clayton         if (paused_private_state_thread)
426f9765acdSGreg Clayton         {
427f9765acdSGreg Clayton             if (log)
428f9765acdSGreg Clayton                 log->Printf ("ProcessKDP::InterruptIfRunning() resuming private state thread");
429f9765acdSGreg Clayton             ResumePrivateStateThread();
430f9765acdSGreg Clayton         }
431f9765acdSGreg Clayton     }
432f9765acdSGreg Clayton     return error;
433f9765acdSGreg Clayton }
434f9765acdSGreg Clayton 
435f9765acdSGreg Clayton Error
436f9765acdSGreg Clayton ProcessKDP::WillDetach ()
437f9765acdSGreg Clayton {
438f9765acdSGreg Clayton     LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS));
439f9765acdSGreg Clayton     if (log)
440f9765acdSGreg Clayton         log->Printf ("ProcessKDP::WillDetach()");
441f9765acdSGreg Clayton 
442f9765acdSGreg Clayton     bool discard_thread_plans = true;
443f9765acdSGreg Clayton     bool catch_stop_event = true;
444f9765acdSGreg Clayton     EventSP event_sp;
445f9765acdSGreg Clayton     return InterruptIfRunning (discard_thread_plans, catch_stop_event, event_sp);
446f9765acdSGreg Clayton }
447f9765acdSGreg Clayton 
448f9765acdSGreg Clayton Error
449f9765acdSGreg Clayton ProcessKDP::DoDetach()
450f9765acdSGreg Clayton {
451f9765acdSGreg Clayton     Error error;
452f9765acdSGreg Clayton     LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS));
453f9765acdSGreg Clayton     if (log)
454f9765acdSGreg Clayton         log->Printf ("ProcessKDP::DoDetach()");
455f9765acdSGreg Clayton 
456f9765acdSGreg Clayton     DisableAllBreakpointSites ();
457f9765acdSGreg Clayton 
458f9765acdSGreg Clayton     m_thread_list.DiscardThreadPlans();
459f9765acdSGreg Clayton 
4603a29bdbeSGreg Clayton     if (m_comm.IsConnected())
4613a29bdbeSGreg Clayton     {
4623a29bdbeSGreg Clayton 
4633a29bdbeSGreg Clayton         m_comm.SendRequestDisconnect();
4643a29bdbeSGreg Clayton 
46557508026SGreg Clayton         size_t response_size = m_comm.Disconnect ();
466f9765acdSGreg Clayton         if (log)
467f9765acdSGreg Clayton         {
468f9765acdSGreg Clayton             if (response_size)
469f9765acdSGreg Clayton                 log->PutCString ("ProcessKDP::DoDetach() detach packet sent successfully");
470f9765acdSGreg Clayton             else
471f9765acdSGreg Clayton                 log->PutCString ("ProcessKDP::DoDetach() detach packet send failed");
472f9765acdSGreg Clayton         }
4733a29bdbeSGreg Clayton     }
474f9765acdSGreg Clayton     // Sleep for one second to let the process get all detached...
475f9765acdSGreg Clayton     StopAsyncThread ();
476f9765acdSGreg Clayton 
47774d4193eSGreg Clayton     m_comm.Clear();
478f9765acdSGreg Clayton 
479f9765acdSGreg Clayton     SetPrivateState (eStateDetached);
480f9765acdSGreg Clayton     ResumePrivateStateThread();
481f9765acdSGreg Clayton 
482f9765acdSGreg Clayton     //KillDebugserverProcess ();
483f9765acdSGreg Clayton     return error;
484f9765acdSGreg Clayton }
485f9765acdSGreg Clayton 
486f9765acdSGreg Clayton Error
487f9765acdSGreg Clayton ProcessKDP::DoDestroy ()
488f9765acdSGreg Clayton {
489f9765acdSGreg Clayton     Error error;
490f9765acdSGreg Clayton     LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS));
491f9765acdSGreg Clayton     if (log)
492f9765acdSGreg Clayton         log->Printf ("ProcessKDP::DoDestroy()");
493f9765acdSGreg Clayton 
494f9765acdSGreg Clayton     // Interrupt if our inferior is running...
495f9765acdSGreg Clayton     if (m_comm.IsConnected())
496f9765acdSGreg Clayton     {
497f9765acdSGreg Clayton         if (m_public_state.GetValue() == eStateAttaching)
498f9765acdSGreg Clayton         {
499f9765acdSGreg Clayton             // We are being asked to halt during an attach. We need to just close
500f9765acdSGreg Clayton             // our file handle and debugserver will go away, and we can be done...
501f9765acdSGreg Clayton             m_comm.Disconnect();
502f9765acdSGreg Clayton         }
503f9765acdSGreg Clayton         else
504f9765acdSGreg Clayton         {
5055b88216dSGreg Clayton             DisableAllBreakpointSites ();
5065b88216dSGreg Clayton 
5075b88216dSGreg Clayton             m_comm.SendRequestDisconnect();
508f9765acdSGreg Clayton 
509f9765acdSGreg Clayton             StringExtractor response;
510f9765acdSGreg Clayton             // TODO: Send kill packet?
511f9765acdSGreg Clayton             SetExitStatus(SIGABRT, NULL);
512f9765acdSGreg Clayton         }
513f9765acdSGreg Clayton     }
514f9765acdSGreg Clayton     StopAsyncThread ();
51574d4193eSGreg Clayton     m_comm.Clear();
516f9765acdSGreg Clayton     return error;
517f9765acdSGreg Clayton }
518f9765acdSGreg Clayton 
519f9765acdSGreg Clayton //------------------------------------------------------------------
520f9765acdSGreg Clayton // Process Queries
521f9765acdSGreg Clayton //------------------------------------------------------------------
522f9765acdSGreg Clayton 
523f9765acdSGreg Clayton bool
524f9765acdSGreg Clayton ProcessKDP::IsAlive ()
525f9765acdSGreg Clayton {
526f9765acdSGreg Clayton     return m_comm.IsConnected() && m_private_state.GetValue() != eStateExited;
527f9765acdSGreg Clayton }
528f9765acdSGreg Clayton 
529f9765acdSGreg Clayton //------------------------------------------------------------------
530f9765acdSGreg Clayton // Process Memory
531f9765acdSGreg Clayton //------------------------------------------------------------------
532f9765acdSGreg Clayton size_t
533f9765acdSGreg Clayton ProcessKDP::DoReadMemory (addr_t addr, void *buf, size_t size, Error &error)
534f9765acdSGreg Clayton {
535a63d08c9SGreg Clayton     if (m_comm.IsConnected())
536a63d08c9SGreg Clayton         return m_comm.SendRequestReadMemory (addr, buf, size, error);
537a63d08c9SGreg Clayton     error.SetErrorString ("not connected");
538f9765acdSGreg Clayton     return 0;
539f9765acdSGreg Clayton }
540f9765acdSGreg Clayton 
541f9765acdSGreg Clayton size_t
542f9765acdSGreg Clayton ProcessKDP::DoWriteMemory (addr_t addr, const void *buf, size_t size, Error &error)
543f9765acdSGreg Clayton {
544f9765acdSGreg Clayton     error.SetErrorString ("ProcessKDP::DoReadMemory not implemented");
545f9765acdSGreg Clayton     return 0;
546f9765acdSGreg Clayton }
547f9765acdSGreg Clayton 
548f9765acdSGreg Clayton lldb::addr_t
549f9765acdSGreg Clayton ProcessKDP::DoAllocateMemory (size_t size, uint32_t permissions, Error &error)
550f9765acdSGreg Clayton {
551f9765acdSGreg Clayton     error.SetErrorString ("memory allocation not suppported in kdp remote debugging");
552f9765acdSGreg Clayton     return LLDB_INVALID_ADDRESS;
553f9765acdSGreg Clayton }
554f9765acdSGreg Clayton 
555f9765acdSGreg Clayton Error
556f9765acdSGreg Clayton ProcessKDP::DoDeallocateMemory (lldb::addr_t addr)
557f9765acdSGreg Clayton {
558f9765acdSGreg Clayton     Error error;
559f9765acdSGreg Clayton     error.SetErrorString ("memory deallocation not suppported in kdp remote debugging");
560f9765acdSGreg Clayton     return error;
561f9765acdSGreg Clayton }
562f9765acdSGreg Clayton 
563f9765acdSGreg Clayton Error
564f9765acdSGreg Clayton ProcessKDP::EnableBreakpoint (BreakpointSite *bp_site)
565f9765acdSGreg Clayton {
56607e66e3eSGreg Clayton     if (m_comm.LocalBreakpointsAreSupported ())
56707e66e3eSGreg Clayton     {
56807e66e3eSGreg Clayton         Error error;
5695b88216dSGreg Clayton         if (!bp_site->IsEnabled())
5705b88216dSGreg Clayton         {
5715b88216dSGreg Clayton             if (m_comm.SendRequestBreakpoint(true, bp_site->GetLoadAddress()))
5725b88216dSGreg Clayton             {
5735b88216dSGreg Clayton                 bp_site->SetEnabled(true);
5745b88216dSGreg Clayton                 bp_site->SetType (BreakpointSite::eExternal);
5755b88216dSGreg Clayton             }
5765b88216dSGreg Clayton             else
5775b88216dSGreg Clayton             {
57807e66e3eSGreg Clayton                 error.SetErrorString ("KDP set breakpoint failed");
5795b88216dSGreg Clayton             }
5805b88216dSGreg Clayton         }
58107e66e3eSGreg Clayton         return error;
58207e66e3eSGreg Clayton     }
583f9765acdSGreg Clayton     return EnableSoftwareBreakpoint (bp_site);
584f9765acdSGreg Clayton }
585f9765acdSGreg Clayton 
586f9765acdSGreg Clayton Error
587f9765acdSGreg Clayton ProcessKDP::DisableBreakpoint (BreakpointSite *bp_site)
588f9765acdSGreg Clayton {
58907e66e3eSGreg Clayton     if (m_comm.LocalBreakpointsAreSupported ())
59007e66e3eSGreg Clayton     {
59107e66e3eSGreg Clayton         Error error;
5925b88216dSGreg Clayton         if (bp_site->IsEnabled())
5935b88216dSGreg Clayton         {
5945b88216dSGreg Clayton             BreakpointSite::Type bp_type = bp_site->GetType();
5955b88216dSGreg Clayton             if (bp_type == BreakpointSite::eExternal)
5965b88216dSGreg Clayton             {
5975b88216dSGreg Clayton                 if (m_comm.SendRequestBreakpoint(false, bp_site->GetLoadAddress()))
5985b88216dSGreg Clayton                     bp_site->SetEnabled(false);
5995b88216dSGreg Clayton                 else
60007e66e3eSGreg Clayton                     error.SetErrorString ("KDP remove breakpoint failed");
6015b88216dSGreg Clayton             }
6025b88216dSGreg Clayton             else
6035b88216dSGreg Clayton             {
6045b88216dSGreg Clayton                 error = DisableSoftwareBreakpoint (bp_site);
6055b88216dSGreg Clayton             }
6065b88216dSGreg Clayton         }
60707e66e3eSGreg Clayton         return error;
60807e66e3eSGreg Clayton     }
609f9765acdSGreg Clayton     return DisableSoftwareBreakpoint (bp_site);
610f9765acdSGreg Clayton }
611f9765acdSGreg Clayton 
612f9765acdSGreg Clayton Error
61301a67860SJohnny Chen ProcessKDP::EnableWatchpoint (Watchpoint *wp)
614f9765acdSGreg Clayton {
615f9765acdSGreg Clayton     Error error;
616f9765acdSGreg Clayton     error.SetErrorString ("watchpoints are not suppported in kdp remote debugging");
617f9765acdSGreg Clayton     return error;
618f9765acdSGreg Clayton }
619f9765acdSGreg Clayton 
620f9765acdSGreg Clayton Error
62101a67860SJohnny Chen ProcessKDP::DisableWatchpoint (Watchpoint *wp)
622f9765acdSGreg Clayton {
623f9765acdSGreg Clayton     Error error;
624f9765acdSGreg Clayton     error.SetErrorString ("watchpoints are not suppported in kdp remote debugging");
625f9765acdSGreg Clayton     return error;
626f9765acdSGreg Clayton }
627f9765acdSGreg Clayton 
628f9765acdSGreg Clayton void
629f9765acdSGreg Clayton ProcessKDP::Clear()
630f9765acdSGreg Clayton {
631f9765acdSGreg Clayton     m_thread_list.Clear();
632f9765acdSGreg Clayton }
633f9765acdSGreg Clayton 
634f9765acdSGreg Clayton Error
635f9765acdSGreg Clayton ProcessKDP::DoSignal (int signo)
636f9765acdSGreg Clayton {
637f9765acdSGreg Clayton     Error error;
638f9765acdSGreg Clayton     error.SetErrorString ("sending signals is not suppported in kdp remote debugging");
639f9765acdSGreg Clayton     return error;
640f9765acdSGreg Clayton }
641f9765acdSGreg Clayton 
642f9765acdSGreg Clayton void
643f9765acdSGreg Clayton ProcessKDP::Initialize()
644f9765acdSGreg Clayton {
645f9765acdSGreg Clayton     static bool g_initialized = false;
646f9765acdSGreg Clayton 
647f9765acdSGreg Clayton     if (g_initialized == false)
648f9765acdSGreg Clayton     {
649f9765acdSGreg Clayton         g_initialized = true;
650f9765acdSGreg Clayton         PluginManager::RegisterPlugin (GetPluginNameStatic(),
651f9765acdSGreg Clayton                                        GetPluginDescriptionStatic(),
652f9765acdSGreg Clayton                                        CreateInstance);
653f9765acdSGreg Clayton 
654f9765acdSGreg Clayton         Log::Callbacks log_callbacks = {
655f9765acdSGreg Clayton             ProcessKDPLog::DisableLog,
656f9765acdSGreg Clayton             ProcessKDPLog::EnableLog,
657f9765acdSGreg Clayton             ProcessKDPLog::ListLogCategories
658f9765acdSGreg Clayton         };
659f9765acdSGreg Clayton 
660f9765acdSGreg Clayton         Log::RegisterLogChannel (ProcessKDP::GetPluginNameStatic(), log_callbacks);
661f9765acdSGreg Clayton     }
662f9765acdSGreg Clayton }
663f9765acdSGreg Clayton 
664f9765acdSGreg Clayton bool
665f9765acdSGreg Clayton ProcessKDP::StartAsyncThread ()
666f9765acdSGreg Clayton {
667f9765acdSGreg Clayton     LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS));
668f9765acdSGreg Clayton 
669f9765acdSGreg Clayton     if (log)
670f9765acdSGreg Clayton         log->Printf ("ProcessKDP::%s ()", __FUNCTION__);
671f9765acdSGreg Clayton 
672f9765acdSGreg Clayton     // Create a thread that watches our internal state and controls which
673f9765acdSGreg Clayton     // events make it to clients (into the DCProcess event queue).
674f9765acdSGreg Clayton     m_async_thread = Host::ThreadCreate ("<lldb.process.kdp-remote.async>", ProcessKDP::AsyncThread, this, NULL);
675f9765acdSGreg Clayton     return IS_VALID_LLDB_HOST_THREAD(m_async_thread);
676f9765acdSGreg Clayton }
677f9765acdSGreg Clayton 
678f9765acdSGreg Clayton void
679f9765acdSGreg Clayton ProcessKDP::StopAsyncThread ()
680f9765acdSGreg Clayton {
681f9765acdSGreg Clayton     LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS));
682f9765acdSGreg Clayton 
683f9765acdSGreg Clayton     if (log)
684f9765acdSGreg Clayton         log->Printf ("ProcessKDP::%s ()", __FUNCTION__);
685f9765acdSGreg Clayton 
686f9765acdSGreg Clayton     m_async_broadcaster.BroadcastEvent (eBroadcastBitAsyncThreadShouldExit);
687f9765acdSGreg Clayton 
688f9765acdSGreg Clayton     // Stop the stdio thread
689f9765acdSGreg Clayton     if (IS_VALID_LLDB_HOST_THREAD(m_async_thread))
690f9765acdSGreg Clayton     {
691f9765acdSGreg Clayton         Host::ThreadJoin (m_async_thread, NULL, NULL);
692f9765acdSGreg Clayton     }
693f9765acdSGreg Clayton }
694f9765acdSGreg Clayton 
695f9765acdSGreg Clayton 
696f9765acdSGreg Clayton void *
697f9765acdSGreg Clayton ProcessKDP::AsyncThread (void *arg)
698f9765acdSGreg Clayton {
699f9765acdSGreg Clayton     ProcessKDP *process = (ProcessKDP*) arg;
700f9765acdSGreg Clayton 
701f9765acdSGreg Clayton     LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_PROCESS));
702f9765acdSGreg Clayton     if (log)
70381c22f61SGreg Clayton         log->Printf ("ProcessKDP::%s (arg = %p, pid = %llu) thread starting...", __FUNCTION__, arg, process->GetID());
704f9765acdSGreg Clayton 
705f9765acdSGreg Clayton     Listener listener ("ProcessKDP::AsyncThread");
706f9765acdSGreg Clayton     EventSP event_sp;
707f9765acdSGreg Clayton     const uint32_t desired_event_mask = eBroadcastBitAsyncContinue |
708f9765acdSGreg Clayton                                         eBroadcastBitAsyncThreadShouldExit;
709f9765acdSGreg Clayton 
710f9765acdSGreg Clayton     if (listener.StartListeningForEvents (&process->m_async_broadcaster, desired_event_mask) == desired_event_mask)
711f9765acdSGreg Clayton     {
712f9765acdSGreg Clayton         listener.StartListeningForEvents (&process->m_comm, Communication::eBroadcastBitReadThreadDidExit);
713f9765acdSGreg Clayton 
714f9765acdSGreg Clayton         bool done = false;
715f9765acdSGreg Clayton         while (!done)
716f9765acdSGreg Clayton         {
717f9765acdSGreg Clayton             if (log)
71881c22f61SGreg Clayton                 log->Printf ("ProcessKDP::%s (arg = %p, pid = %llu) listener.WaitForEvent (NULL, event_sp)...", __FUNCTION__, arg, process->GetID());
719f9765acdSGreg Clayton             if (listener.WaitForEvent (NULL, event_sp))
720f9765acdSGreg Clayton             {
721f9765acdSGreg Clayton                 const uint32_t event_type = event_sp->GetType();
722f9765acdSGreg Clayton                 if (event_sp->BroadcasterIs (&process->m_async_broadcaster))
723f9765acdSGreg Clayton                 {
724f9765acdSGreg Clayton                     if (log)
72581c22f61SGreg Clayton                         log->Printf ("ProcessKDP::%s (arg = %p, pid = %llu) Got an event of type: %d...", __FUNCTION__, arg, process->GetID(), event_type);
726f9765acdSGreg Clayton 
727f9765acdSGreg Clayton                     switch (event_type)
728f9765acdSGreg Clayton                     {
729f9765acdSGreg Clayton                         case eBroadcastBitAsyncContinue:
730f9765acdSGreg Clayton                         {
731f9765acdSGreg Clayton                             const EventDataBytes *continue_packet = EventDataBytes::GetEventDataFromEvent(event_sp.get());
732f9765acdSGreg Clayton 
733f9765acdSGreg Clayton                             if (continue_packet)
734f9765acdSGreg Clayton                             {
735f9765acdSGreg Clayton                                 // TODO: do continue support here
736f9765acdSGreg Clayton 
737f9765acdSGreg Clayton //                                const char *continue_cstr = (const char *)continue_packet->GetBytes ();
738f9765acdSGreg Clayton //                                const size_t continue_cstr_len = continue_packet->GetByteSize ();
739f9765acdSGreg Clayton //                                if (log)
740f9765acdSGreg Clayton //                                    log->Printf ("ProcessKDP::%s (arg = %p, pid = %i) got eBroadcastBitAsyncContinue: %s", __FUNCTION__, arg, process->GetID(), continue_cstr);
741f9765acdSGreg Clayton //
742f9765acdSGreg Clayton //                                if (::strstr (continue_cstr, "vAttach") == NULL)
743f9765acdSGreg Clayton //                                    process->SetPrivateState(eStateRunning);
744f9765acdSGreg Clayton //                                StringExtractor response;
745f9765acdSGreg Clayton //                                StateType stop_state = process->GetCommunication().SendContinuePacketAndWaitForResponse (process, continue_cstr, continue_cstr_len, response);
746f9765acdSGreg Clayton //
747f9765acdSGreg Clayton //                                switch (stop_state)
748f9765acdSGreg Clayton //                                {
749f9765acdSGreg Clayton //                                    case eStateStopped:
750f9765acdSGreg Clayton //                                    case eStateCrashed:
751f9765acdSGreg Clayton //                                    case eStateSuspended:
752f9765acdSGreg Clayton //                                        process->m_last_stop_packet = response;
753f9765acdSGreg Clayton //                                        process->SetPrivateState (stop_state);
754f9765acdSGreg Clayton //                                        break;
755f9765acdSGreg Clayton //
756f9765acdSGreg Clayton //                                    case eStateExited:
757f9765acdSGreg Clayton //                                        process->m_last_stop_packet = response;
758f9765acdSGreg Clayton //                                        response.SetFilePos(1);
759f9765acdSGreg Clayton //                                        process->SetExitStatus(response.GetHexU8(), NULL);
760f9765acdSGreg Clayton //                                        done = true;
761f9765acdSGreg Clayton //                                        break;
762f9765acdSGreg Clayton //
763f9765acdSGreg Clayton //                                    case eStateInvalid:
764f9765acdSGreg Clayton //                                        process->SetExitStatus(-1, "lost connection");
765f9765acdSGreg Clayton //                                        break;
766f9765acdSGreg Clayton //
767f9765acdSGreg Clayton //                                    default:
768f9765acdSGreg Clayton //                                        process->SetPrivateState (stop_state);
769f9765acdSGreg Clayton //                                        break;
770f9765acdSGreg Clayton //                                }
771f9765acdSGreg Clayton                             }
772f9765acdSGreg Clayton                         }
773f9765acdSGreg Clayton                             break;
774f9765acdSGreg Clayton 
775f9765acdSGreg Clayton                         case eBroadcastBitAsyncThreadShouldExit:
776f9765acdSGreg Clayton                             if (log)
77781c22f61SGreg Clayton                                 log->Printf ("ProcessKDP::%s (arg = %p, pid = %llu) got eBroadcastBitAsyncThreadShouldExit...", __FUNCTION__, arg, process->GetID());
778f9765acdSGreg Clayton                             done = true;
779f9765acdSGreg Clayton                             break;
780f9765acdSGreg Clayton 
781f9765acdSGreg Clayton                         default:
782f9765acdSGreg Clayton                             if (log)
78381c22f61SGreg Clayton                                 log->Printf ("ProcessKDP::%s (arg = %p, pid = %llu) got unknown event 0x%8.8x", __FUNCTION__, arg, process->GetID(), event_type);
784f9765acdSGreg Clayton                             done = true;
785f9765acdSGreg Clayton                             break;
786f9765acdSGreg Clayton                     }
787f9765acdSGreg Clayton                 }
788f9765acdSGreg Clayton                 else if (event_sp->BroadcasterIs (&process->m_comm))
789f9765acdSGreg Clayton                 {
790f9765acdSGreg Clayton                     if (event_type & Communication::eBroadcastBitReadThreadDidExit)
791f9765acdSGreg Clayton                     {
792f9765acdSGreg Clayton                         process->SetExitStatus (-1, "lost connection");
793f9765acdSGreg Clayton                         done = true;
794f9765acdSGreg Clayton                     }
795f9765acdSGreg Clayton                 }
796f9765acdSGreg Clayton             }
797f9765acdSGreg Clayton             else
798f9765acdSGreg Clayton             {
799f9765acdSGreg Clayton                 if (log)
80081c22f61SGreg Clayton                     log->Printf ("ProcessKDP::%s (arg = %p, pid = %llu) listener.WaitForEvent (NULL, event_sp) => false", __FUNCTION__, arg, process->GetID());
801f9765acdSGreg Clayton                 done = true;
802f9765acdSGreg Clayton             }
803f9765acdSGreg Clayton         }
804f9765acdSGreg Clayton     }
805f9765acdSGreg Clayton 
806f9765acdSGreg Clayton     if (log)
80781c22f61SGreg Clayton         log->Printf ("ProcessKDP::%s (arg = %p, pid = %llu) thread exiting...", __FUNCTION__, arg, process->GetID());
808f9765acdSGreg Clayton 
809f9765acdSGreg Clayton     process->m_async_thread = LLDB_INVALID_HOST_THREAD;
810f9765acdSGreg Clayton     return NULL;
811f9765acdSGreg Clayton }
812f9765acdSGreg Clayton 
813f9765acdSGreg Clayton 
814