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