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