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