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