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 16*3a29bdbeSGreg Clayton #include "lldb/Core/ConnectionFileDescriptor.h" 17f9765acdSGreg Clayton #include "lldb/Core/PluginManager.h" 18f9765acdSGreg Clayton #include "lldb/Core/State.h" 19f9765acdSGreg Clayton #include "lldb/Host/Host.h" 2057508026SGreg Clayton #include "lldb/Target/Target.h" 21f9765acdSGreg Clayton 22f9765acdSGreg Clayton // Project includes 23f9765acdSGreg Clayton #include "ProcessKDP.h" 24f9765acdSGreg Clayton #include "ProcessKDPLog.h" 25f9765acdSGreg Clayton //#include "ThreadKDP.h" 26f9765acdSGreg Clayton #include "StopInfoMachException.h" 27f9765acdSGreg Clayton 28f9765acdSGreg Clayton using namespace lldb; 29f9765acdSGreg Clayton using namespace lldb_private; 30f9765acdSGreg Clayton 31f9765acdSGreg Clayton const char * 32f9765acdSGreg Clayton ProcessKDP::GetPluginNameStatic() 33f9765acdSGreg Clayton { 34f9765acdSGreg Clayton return "kdp-remote"; 35f9765acdSGreg Clayton } 36f9765acdSGreg Clayton 37f9765acdSGreg Clayton const char * 38f9765acdSGreg Clayton ProcessKDP::GetPluginDescriptionStatic() 39f9765acdSGreg Clayton { 40f9765acdSGreg Clayton return "KDP Remote protocol based debugging plug-in for darwin kernel debugging."; 41f9765acdSGreg Clayton } 42f9765acdSGreg Clayton 43f9765acdSGreg Clayton void 44f9765acdSGreg Clayton ProcessKDP::Terminate() 45f9765acdSGreg Clayton { 46f9765acdSGreg Clayton PluginManager::UnregisterPlugin (ProcessKDP::CreateInstance); 47f9765acdSGreg Clayton } 48f9765acdSGreg Clayton 49f9765acdSGreg Clayton 50f9765acdSGreg Clayton Process* 51f9765acdSGreg Clayton ProcessKDP::CreateInstance (Target &target, Listener &listener) 52f9765acdSGreg Clayton { 53f9765acdSGreg Clayton return new ProcessKDP (target, listener); 54f9765acdSGreg Clayton } 55f9765acdSGreg Clayton 56f9765acdSGreg Clayton bool 57*3a29bdbeSGreg Clayton ProcessKDP::CanDebug(Target &target, bool plugin_specified_by_name) 58f9765acdSGreg Clayton { 59f9765acdSGreg Clayton // For now we are just making sure the file exists for a given module 60f9765acdSGreg Clayton ModuleSP exe_module_sp(target.GetExecutableModule()); 61f9765acdSGreg Clayton if (exe_module_sp.get()) 62f9765acdSGreg Clayton { 63f9765acdSGreg Clayton const llvm::Triple &triple_ref = target.GetArchitecture().GetTriple(); 64f9765acdSGreg Clayton if (triple_ref.getOS() == llvm::Triple::Darwin && 65f9765acdSGreg Clayton triple_ref.getVendor() == llvm::Triple::Apple) 66f9765acdSGreg Clayton { 67f9765acdSGreg Clayton ObjectFile *exe_objfile = exe_module_sp->GetObjectFile(); 68f9765acdSGreg Clayton if (exe_objfile->GetType() == ObjectFile::eTypeExecutable && 69f9765acdSGreg Clayton exe_objfile->GetStrata() == ObjectFile::eStrataKernel) 70f9765acdSGreg Clayton return true; 71f9765acdSGreg Clayton } 72f9765acdSGreg Clayton return false; 73f9765acdSGreg Clayton } 74*3a29bdbeSGreg Clayton // No target executable, assume we can debug if our plug-in was specified by name 75*3a29bdbeSGreg Clayton return plugin_specified_by_name; 76*3a29bdbeSGreg Clayton } 77f9765acdSGreg Clayton 78f9765acdSGreg Clayton //---------------------------------------------------------------------- 79f9765acdSGreg Clayton // ProcessKDP constructor 80f9765acdSGreg Clayton //---------------------------------------------------------------------- 81f9765acdSGreg Clayton ProcessKDP::ProcessKDP(Target& target, Listener &listener) : 82f9765acdSGreg Clayton Process (target, listener), 83f9765acdSGreg Clayton m_comm("lldb.process.kdp-remote.communication"), 84f9765acdSGreg Clayton m_async_broadcaster ("lldb.process.kdp-remote.async-broadcaster"), 85f9765acdSGreg Clayton m_async_thread (LLDB_INVALID_HOST_THREAD) 86f9765acdSGreg Clayton { 87f9765acdSGreg Clayton // m_async_broadcaster.SetEventName (eBroadcastBitAsyncThreadShouldExit, "async thread should exit"); 88f9765acdSGreg Clayton // m_async_broadcaster.SetEventName (eBroadcastBitAsyncContinue, "async thread continue"); 89f9765acdSGreg Clayton } 90f9765acdSGreg Clayton 91f9765acdSGreg Clayton //---------------------------------------------------------------------- 92f9765acdSGreg Clayton // Destructor 93f9765acdSGreg Clayton //---------------------------------------------------------------------- 94f9765acdSGreg Clayton ProcessKDP::~ProcessKDP() 95f9765acdSGreg Clayton { 96f9765acdSGreg Clayton Clear(); 97f9765acdSGreg Clayton } 98f9765acdSGreg Clayton 99f9765acdSGreg Clayton //---------------------------------------------------------------------- 100f9765acdSGreg Clayton // PluginInterface 101f9765acdSGreg Clayton //---------------------------------------------------------------------- 102f9765acdSGreg Clayton const char * 103f9765acdSGreg Clayton ProcessKDP::GetPluginName() 104f9765acdSGreg Clayton { 105f9765acdSGreg Clayton return "Process debugging plug-in that uses the Darwin KDP remote protocol"; 106f9765acdSGreg Clayton } 107f9765acdSGreg Clayton 108f9765acdSGreg Clayton const char * 109f9765acdSGreg Clayton ProcessKDP::GetShortPluginName() 110f9765acdSGreg Clayton { 111f9765acdSGreg Clayton return GetPluginNameStatic(); 112f9765acdSGreg Clayton } 113f9765acdSGreg Clayton 114f9765acdSGreg Clayton uint32_t 115f9765acdSGreg Clayton ProcessKDP::GetPluginVersion() 116f9765acdSGreg Clayton { 117f9765acdSGreg Clayton return 1; 118f9765acdSGreg Clayton } 119f9765acdSGreg Clayton 120f9765acdSGreg Clayton Error 121f9765acdSGreg Clayton ProcessKDP::WillLaunch (Module* module) 122f9765acdSGreg Clayton { 123f9765acdSGreg Clayton Error error; 124f9765acdSGreg Clayton error.SetErrorString ("launching not supported in kdp-remote plug-in"); 125f9765acdSGreg Clayton return error; 126f9765acdSGreg Clayton } 127f9765acdSGreg Clayton 128f9765acdSGreg Clayton Error 129f9765acdSGreg Clayton ProcessKDP::WillAttachToProcessWithID (lldb::pid_t pid) 130f9765acdSGreg Clayton { 131f9765acdSGreg Clayton Error error; 132f9765acdSGreg Clayton error.SetErrorString ("attaching to a by process ID not supported in kdp-remote plug-in"); 133f9765acdSGreg Clayton return error; 134f9765acdSGreg Clayton } 135f9765acdSGreg Clayton 136f9765acdSGreg Clayton Error 137f9765acdSGreg Clayton ProcessKDP::WillAttachToProcessWithName (const char *process_name, bool wait_for_launch) 138f9765acdSGreg Clayton { 139f9765acdSGreg Clayton Error error; 140f9765acdSGreg Clayton error.SetErrorString ("attaching to a by process name not supported in kdp-remote plug-in"); 141f9765acdSGreg Clayton return error; 142f9765acdSGreg Clayton } 143f9765acdSGreg Clayton 144f9765acdSGreg Clayton Error 145f9765acdSGreg Clayton ProcessKDP::DoConnectRemote (const char *remote_url) 146f9765acdSGreg Clayton { 147f9765acdSGreg Clayton // TODO: fill in the remote connection to the remote KDP here! 148f9765acdSGreg Clayton Error error; 149*3a29bdbeSGreg Clayton 150*3a29bdbeSGreg Clayton if (remote_url == NULL || remote_url[0] == '\0') 151*3a29bdbeSGreg Clayton remote_url = "udp://localhost:41139"; 152*3a29bdbeSGreg Clayton 153*3a29bdbeSGreg Clayton std::auto_ptr<ConnectionFileDescriptor> conn_ap(new ConnectionFileDescriptor()); 154*3a29bdbeSGreg Clayton if (conn_ap.get()) 155*3a29bdbeSGreg Clayton { 156*3a29bdbeSGreg Clayton // Only try once for now. 157*3a29bdbeSGreg Clayton // TODO: check if we should be retrying? 158*3a29bdbeSGreg Clayton const uint32_t max_retry_count = 1; 159*3a29bdbeSGreg Clayton for (uint32_t retry_count = 0; retry_count < max_retry_count; ++retry_count) 160*3a29bdbeSGreg Clayton { 161*3a29bdbeSGreg Clayton if (conn_ap->Connect(remote_url, &error) == eConnectionStatusSuccess) 162*3a29bdbeSGreg Clayton break; 163*3a29bdbeSGreg Clayton usleep (100000); 164*3a29bdbeSGreg Clayton } 165*3a29bdbeSGreg Clayton } 166*3a29bdbeSGreg Clayton 167*3a29bdbeSGreg Clayton if (conn_ap->IsConnected()) 168*3a29bdbeSGreg Clayton { 169*3a29bdbeSGreg Clayton const uint16_t reply_port = conn_ap->GetReadPort (); 170*3a29bdbeSGreg Clayton 171*3a29bdbeSGreg Clayton if (reply_port != 0) 172*3a29bdbeSGreg Clayton { 173*3a29bdbeSGreg Clayton m_comm.SetConnection(conn_ap.release()); 174*3a29bdbeSGreg Clayton 175*3a29bdbeSGreg Clayton if (m_comm.SendRequestReattach(reply_port)) 176*3a29bdbeSGreg Clayton { 177*3a29bdbeSGreg Clayton if (m_comm.SendRequestConnect(reply_port, reply_port, "Greetings from LLDB...")) 178*3a29bdbeSGreg Clayton { 179*3a29bdbeSGreg Clayton m_comm.GetVersion(); 180*3a29bdbeSGreg Clayton uint32_t cpu = m_comm.GetCPUType(); 181*3a29bdbeSGreg Clayton uint32_t sub = m_comm.GetCPUSubtype(); 182*3a29bdbeSGreg Clayton ArchSpec kernel_arch; 183*3a29bdbeSGreg Clayton kernel_arch.SetArchitecture(eArchTypeMachO, cpu, sub); 184*3a29bdbeSGreg Clayton m_target.SetArchitecture(kernel_arch); 185*3a29bdbeSGreg Clayton // TODO: thread registers based off of architecture... 186*3a29bdbeSGreg Clayton } 187*3a29bdbeSGreg Clayton } 188*3a29bdbeSGreg Clayton else 189*3a29bdbeSGreg Clayton { 190*3a29bdbeSGreg Clayton error.SetErrorString("KDP reattach failed"); 191*3a29bdbeSGreg Clayton } 192*3a29bdbeSGreg Clayton } 193*3a29bdbeSGreg Clayton else 194*3a29bdbeSGreg Clayton { 195*3a29bdbeSGreg Clayton error.SetErrorString("invalid reply port from UDP connection"); 196*3a29bdbeSGreg Clayton } 197*3a29bdbeSGreg Clayton } 198*3a29bdbeSGreg Clayton else 199*3a29bdbeSGreg Clayton { 200*3a29bdbeSGreg Clayton if (error.Success()) 201*3a29bdbeSGreg Clayton error.SetErrorStringWithFormat ("failed to connect to '%s'", remote_url); 202*3a29bdbeSGreg Clayton } 203*3a29bdbeSGreg Clayton if (error.Fail()) 204*3a29bdbeSGreg Clayton m_comm.Disconnect(); 205*3a29bdbeSGreg Clayton 206f9765acdSGreg Clayton return error; 207f9765acdSGreg Clayton } 208f9765acdSGreg Clayton 209f9765acdSGreg Clayton //---------------------------------------------------------------------- 210f9765acdSGreg Clayton // Process Control 211f9765acdSGreg Clayton //---------------------------------------------------------------------- 212f9765acdSGreg Clayton Error 213f9765acdSGreg Clayton ProcessKDP::DoLaunch (Module* module, 214f9765acdSGreg Clayton char const *argv[], 215f9765acdSGreg Clayton char const *envp[], 216f9765acdSGreg Clayton uint32_t launch_flags, 217f9765acdSGreg Clayton const char *stdin_path, 218f9765acdSGreg Clayton const char *stdout_path, 219f9765acdSGreg Clayton const char *stderr_path, 220f9765acdSGreg Clayton const char *working_dir) 221f9765acdSGreg Clayton { 222f9765acdSGreg Clayton Error error; 223f9765acdSGreg Clayton error.SetErrorString ("launching not supported in kdp-remote plug-in"); 224f9765acdSGreg Clayton return error; 225f9765acdSGreg Clayton } 226f9765acdSGreg Clayton 227f9765acdSGreg Clayton 228f9765acdSGreg Clayton Error 229f9765acdSGreg Clayton ProcessKDP::DoAttachToProcessWithID (lldb::pid_t attach_pid) 230f9765acdSGreg Clayton { 231f9765acdSGreg Clayton Error error; 232f9765acdSGreg Clayton error.SetErrorString ("attach to process by ID is not suppported in kdp remote debugging"); 233f9765acdSGreg Clayton return error; 234f9765acdSGreg Clayton } 235f9765acdSGreg Clayton 236f9765acdSGreg Clayton size_t 237f9765acdSGreg Clayton ProcessKDP::AttachInputReaderCallback (void *baton, 238f9765acdSGreg Clayton InputReader *reader, 239f9765acdSGreg Clayton lldb::InputReaderAction notification, 240f9765acdSGreg Clayton const char *bytes, 241f9765acdSGreg Clayton size_t bytes_len) 242f9765acdSGreg Clayton { 243f9765acdSGreg Clayton if (notification == eInputReaderGotToken) 244f9765acdSGreg Clayton { 245f9765acdSGreg Clayton // ProcessKDP *process = (ProcessKDP *)baton; 246f9765acdSGreg Clayton // if (process->m_waiting_for_attach) 247f9765acdSGreg Clayton // process->m_waiting_for_attach = false; 248f9765acdSGreg Clayton reader->SetIsDone(true); 249f9765acdSGreg Clayton return 1; 250f9765acdSGreg Clayton } 251f9765acdSGreg Clayton return 0; 252f9765acdSGreg Clayton } 253f9765acdSGreg Clayton 254f9765acdSGreg Clayton Error 255f9765acdSGreg Clayton ProcessKDP::DoAttachToProcessWithName (const char *process_name, bool wait_for_launch) 256f9765acdSGreg Clayton { 257f9765acdSGreg Clayton Error error; 258f9765acdSGreg Clayton error.SetErrorString ("attach to process by name is not suppported in kdp remote debugging"); 259f9765acdSGreg Clayton return error; 260f9765acdSGreg Clayton } 261f9765acdSGreg Clayton 262f9765acdSGreg Clayton 263f9765acdSGreg Clayton void 264f9765acdSGreg Clayton ProcessKDP::DidAttach () 265f9765acdSGreg Clayton { 266f9765acdSGreg Clayton LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_PROCESS)); 267f9765acdSGreg Clayton if (log) 268f9765acdSGreg Clayton log->Printf ("ProcessKDP::DidLaunch()"); 269f9765acdSGreg Clayton if (GetID() != LLDB_INVALID_PROCESS_ID) 270f9765acdSGreg Clayton { 271f9765acdSGreg Clayton // TODO: figure out the register context that we will use 272f9765acdSGreg Clayton } 273f9765acdSGreg Clayton } 274f9765acdSGreg Clayton 275f9765acdSGreg Clayton Error 276f9765acdSGreg Clayton ProcessKDP::WillResume () 277f9765acdSGreg Clayton { 278f9765acdSGreg Clayton return Error(); 279f9765acdSGreg Clayton } 280f9765acdSGreg Clayton 281f9765acdSGreg Clayton Error 282f9765acdSGreg Clayton ProcessKDP::DoResume () 283f9765acdSGreg Clayton { 284f9765acdSGreg Clayton Error error; 285f9765acdSGreg Clayton error.SetErrorString ("ProcessKDP::DoResume () is not implemented yet"); 286f9765acdSGreg Clayton return error; 287f9765acdSGreg Clayton } 288f9765acdSGreg Clayton 289f9765acdSGreg Clayton uint32_t 290f9765acdSGreg Clayton ProcessKDP::UpdateThreadListIfNeeded () 291f9765acdSGreg Clayton { 292f9765acdSGreg Clayton // locker will keep a mutex locked until it goes out of scope 293f9765acdSGreg Clayton LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_THREAD)); 294f9765acdSGreg Clayton if (log && log->GetMask().Test(KDP_LOG_VERBOSE)) 295f9765acdSGreg Clayton log->Printf ("ProcessKDP::%s (pid = %i)", __FUNCTION__, GetID()); 296f9765acdSGreg Clayton 297f9765acdSGreg Clayton Mutex::Locker locker (m_thread_list.GetMutex ()); 298f9765acdSGreg Clayton // TODO: get the thread list here! 299f9765acdSGreg Clayton const uint32_t stop_id = GetStopID(); 300f9765acdSGreg Clayton if (m_thread_list.GetSize(false) == 0 || stop_id != m_thread_list.GetStopID()) 301f9765acdSGreg Clayton { 302f9765acdSGreg Clayton // Update the thread list's stop id immediately so we don't recurse into this function. 303f9765acdSGreg Clayton // ThreadList curr_thread_list (this); 304f9765acdSGreg Clayton // curr_thread_list.SetStopID(stop_id); 305f9765acdSGreg Clayton // 306f9765acdSGreg Clayton // std::vector<lldb::tid_t> thread_ids; 307f9765acdSGreg Clayton // bool sequence_mutex_unavailable = false; 308f9765acdSGreg Clayton // const size_t num_thread_ids = m_comm.GetCurrentThreadIDs (thread_ids, sequence_mutex_unavailable); 309f9765acdSGreg Clayton // if (num_thread_ids > 0) 310f9765acdSGreg Clayton // { 311f9765acdSGreg Clayton // for (size_t i=0; i<num_thread_ids; ++i) 312f9765acdSGreg Clayton // { 313f9765acdSGreg Clayton // tid_t tid = thread_ids[i]; 314f9765acdSGreg Clayton // ThreadSP thread_sp (GetThreadList().FindThreadByID (tid, false)); 315f9765acdSGreg Clayton // if (!thread_sp) 316f9765acdSGreg Clayton // thread_sp.reset (new ThreadGDBRemote (*this, tid)); 317f9765acdSGreg Clayton // curr_thread_list.AddThread(thread_sp); 318f9765acdSGreg Clayton // } 319f9765acdSGreg Clayton // } 320f9765acdSGreg Clayton // 321f9765acdSGreg Clayton // if (sequence_mutex_unavailable == false) 322f9765acdSGreg Clayton // { 323f9765acdSGreg Clayton // m_thread_list = curr_thread_list; 324f9765acdSGreg Clayton // SetThreadStopInfo (m_last_stop_packet); 325f9765acdSGreg Clayton // } 326f9765acdSGreg Clayton } 327f9765acdSGreg Clayton return GetThreadList().GetSize(false); 328f9765acdSGreg Clayton } 329f9765acdSGreg Clayton 330f9765acdSGreg Clayton 331f9765acdSGreg Clayton StateType 332f9765acdSGreg Clayton ProcessKDP::SetThreadStopInfo (StringExtractor& stop_packet) 333f9765acdSGreg Clayton { 334f9765acdSGreg Clayton // TODO: figure out why we stopped given the packet that tells us we stopped... 335f9765acdSGreg Clayton return eStateStopped; 336f9765acdSGreg Clayton } 337f9765acdSGreg Clayton 338f9765acdSGreg Clayton void 339f9765acdSGreg Clayton ProcessKDP::RefreshStateAfterStop () 340f9765acdSGreg Clayton { 341f9765acdSGreg Clayton // Let all threads recover from stopping and do any clean up based 342f9765acdSGreg Clayton // on the previous thread state (if any). 343f9765acdSGreg Clayton m_thread_list.RefreshStateAfterStop(); 344f9765acdSGreg Clayton //SetThreadStopInfo (m_last_stop_packet); 345f9765acdSGreg Clayton } 346f9765acdSGreg Clayton 347f9765acdSGreg Clayton Error 348f9765acdSGreg Clayton ProcessKDP::DoHalt (bool &caused_stop) 349f9765acdSGreg Clayton { 350f9765acdSGreg Clayton Error error; 351f9765acdSGreg Clayton 352f9765acdSGreg Clayton // bool timed_out = false; 353f9765acdSGreg Clayton Mutex::Locker locker; 354f9765acdSGreg Clayton 355f9765acdSGreg Clayton if (m_public_state.GetValue() == eStateAttaching) 356f9765acdSGreg Clayton { 357f9765acdSGreg Clayton // We are being asked to halt during an attach. We need to just close 358f9765acdSGreg Clayton // our file handle and debugserver will go away, and we can be done... 359f9765acdSGreg Clayton m_comm.Disconnect(); 360f9765acdSGreg Clayton } 361f9765acdSGreg Clayton else 362f9765acdSGreg Clayton { 363f9765acdSGreg Clayton // TODO: add the ability to halt a running kernel 364f9765acdSGreg Clayton error.SetErrorString ("halt not supported in kdp-remote plug-in"); 365f9765acdSGreg Clayton // if (!m_comm.SendInterrupt (locker, 2, caused_stop, timed_out)) 366f9765acdSGreg Clayton // { 367f9765acdSGreg Clayton // if (timed_out) 368f9765acdSGreg Clayton // error.SetErrorString("timed out sending interrupt packet"); 369f9765acdSGreg Clayton // else 370f9765acdSGreg Clayton // error.SetErrorString("unknown error sending interrupt packet"); 371f9765acdSGreg Clayton // } 372f9765acdSGreg Clayton } 373f9765acdSGreg Clayton return error; 374f9765acdSGreg Clayton } 375f9765acdSGreg Clayton 376f9765acdSGreg Clayton Error 377f9765acdSGreg Clayton ProcessKDP::InterruptIfRunning (bool discard_thread_plans, 378f9765acdSGreg Clayton bool catch_stop_event, 379f9765acdSGreg Clayton EventSP &stop_event_sp) 380f9765acdSGreg Clayton { 381f9765acdSGreg Clayton Error error; 382f9765acdSGreg Clayton 383f9765acdSGreg Clayton LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS)); 384f9765acdSGreg Clayton 385f9765acdSGreg Clayton bool paused_private_state_thread = false; 386f9765acdSGreg Clayton const bool is_running = m_comm.IsRunning(); 387f9765acdSGreg Clayton if (log) 388f9765acdSGreg Clayton log->Printf ("ProcessKDP::InterruptIfRunning(discard_thread_plans=%i, catch_stop_event=%i) is_running=%i", 389f9765acdSGreg Clayton discard_thread_plans, 390f9765acdSGreg Clayton catch_stop_event, 391f9765acdSGreg Clayton is_running); 392f9765acdSGreg Clayton 393f9765acdSGreg Clayton if (discard_thread_plans) 394f9765acdSGreg Clayton { 395f9765acdSGreg Clayton if (log) 396f9765acdSGreg Clayton log->Printf ("ProcessKDP::InterruptIfRunning() discarding all thread plans"); 397f9765acdSGreg Clayton m_thread_list.DiscardThreadPlans(); 398f9765acdSGreg Clayton } 399f9765acdSGreg Clayton if (is_running) 400f9765acdSGreg Clayton { 401f9765acdSGreg Clayton if (catch_stop_event) 402f9765acdSGreg Clayton { 403f9765acdSGreg Clayton if (log) 404f9765acdSGreg Clayton log->Printf ("ProcessKDP::InterruptIfRunning() pausing private state thread"); 405f9765acdSGreg Clayton PausePrivateStateThread(); 406f9765acdSGreg Clayton paused_private_state_thread = true; 407f9765acdSGreg Clayton } 408f9765acdSGreg Clayton 409f9765acdSGreg Clayton bool timed_out = false; 410f9765acdSGreg Clayton // bool sent_interrupt = false; 411f9765acdSGreg Clayton Mutex::Locker locker; 412f9765acdSGreg Clayton 413f9765acdSGreg Clayton // TODO: implement halt in CommunicationKDP 414f9765acdSGreg Clayton // if (!m_comm.SendInterrupt (locker, 1, sent_interrupt, timed_out)) 415f9765acdSGreg Clayton // { 416f9765acdSGreg Clayton // if (timed_out) 417f9765acdSGreg Clayton // error.SetErrorString("timed out sending interrupt packet"); 418f9765acdSGreg Clayton // else 419f9765acdSGreg Clayton // error.SetErrorString("unknown error sending interrupt packet"); 420f9765acdSGreg Clayton // if (paused_private_state_thread) 421f9765acdSGreg Clayton // ResumePrivateStateThread(); 422f9765acdSGreg Clayton // return error; 423f9765acdSGreg Clayton // } 424f9765acdSGreg Clayton 425f9765acdSGreg Clayton if (catch_stop_event) 426f9765acdSGreg Clayton { 427f9765acdSGreg Clayton // LISTEN HERE 428f9765acdSGreg Clayton TimeValue timeout_time; 429f9765acdSGreg Clayton timeout_time = TimeValue::Now(); 430f9765acdSGreg Clayton timeout_time.OffsetWithSeconds(5); 431f9765acdSGreg Clayton StateType state = WaitForStateChangedEventsPrivate (&timeout_time, stop_event_sp); 432f9765acdSGreg Clayton 433f9765acdSGreg Clayton timed_out = state == eStateInvalid; 434f9765acdSGreg Clayton if (log) 435f9765acdSGreg Clayton log->Printf ("ProcessKDP::InterruptIfRunning() catch stop event: state = %s, timed-out=%i", StateAsCString(state), timed_out); 436f9765acdSGreg Clayton 437f9765acdSGreg Clayton if (timed_out) 438f9765acdSGreg Clayton error.SetErrorString("unable to verify target stopped"); 439f9765acdSGreg Clayton } 440f9765acdSGreg Clayton 441f9765acdSGreg Clayton if (paused_private_state_thread) 442f9765acdSGreg Clayton { 443f9765acdSGreg Clayton if (log) 444f9765acdSGreg Clayton log->Printf ("ProcessKDP::InterruptIfRunning() resuming private state thread"); 445f9765acdSGreg Clayton ResumePrivateStateThread(); 446f9765acdSGreg Clayton } 447f9765acdSGreg Clayton } 448f9765acdSGreg Clayton return error; 449f9765acdSGreg Clayton } 450f9765acdSGreg Clayton 451f9765acdSGreg Clayton Error 452f9765acdSGreg Clayton ProcessKDP::WillDetach () 453f9765acdSGreg Clayton { 454f9765acdSGreg Clayton LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS)); 455f9765acdSGreg Clayton if (log) 456f9765acdSGreg Clayton log->Printf ("ProcessKDP::WillDetach()"); 457f9765acdSGreg Clayton 458f9765acdSGreg Clayton bool discard_thread_plans = true; 459f9765acdSGreg Clayton bool catch_stop_event = true; 460f9765acdSGreg Clayton EventSP event_sp; 461f9765acdSGreg Clayton return InterruptIfRunning (discard_thread_plans, catch_stop_event, event_sp); 462f9765acdSGreg Clayton } 463f9765acdSGreg Clayton 464f9765acdSGreg Clayton Error 465f9765acdSGreg Clayton ProcessKDP::DoDetach() 466f9765acdSGreg Clayton { 467f9765acdSGreg Clayton Error error; 468f9765acdSGreg Clayton LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS)); 469f9765acdSGreg Clayton if (log) 470f9765acdSGreg Clayton log->Printf ("ProcessKDP::DoDetach()"); 471f9765acdSGreg Clayton 472f9765acdSGreg Clayton DisableAllBreakpointSites (); 473f9765acdSGreg Clayton 474f9765acdSGreg Clayton m_thread_list.DiscardThreadPlans(); 475f9765acdSGreg Clayton 476*3a29bdbeSGreg Clayton if (m_comm.IsConnected()) 477*3a29bdbeSGreg Clayton { 478*3a29bdbeSGreg Clayton 479*3a29bdbeSGreg Clayton m_comm.SendRequestDisconnect(); 480*3a29bdbeSGreg Clayton 48157508026SGreg Clayton size_t response_size = m_comm.Disconnect (); 482f9765acdSGreg Clayton if (log) 483f9765acdSGreg Clayton { 484f9765acdSGreg Clayton if (response_size) 485f9765acdSGreg Clayton log->PutCString ("ProcessKDP::DoDetach() detach packet sent successfully"); 486f9765acdSGreg Clayton else 487f9765acdSGreg Clayton log->PutCString ("ProcessKDP::DoDetach() detach packet send failed"); 488f9765acdSGreg Clayton } 489*3a29bdbeSGreg Clayton } 490f9765acdSGreg Clayton // Sleep for one second to let the process get all detached... 491f9765acdSGreg Clayton StopAsyncThread (); 492f9765acdSGreg Clayton 493f9765acdSGreg Clayton m_comm.StopReadThread(); 494f9765acdSGreg Clayton m_comm.Disconnect(); // Disconnect from the debug server. 495f9765acdSGreg Clayton 496f9765acdSGreg Clayton SetPrivateState (eStateDetached); 497f9765acdSGreg Clayton ResumePrivateStateThread(); 498f9765acdSGreg Clayton 499f9765acdSGreg Clayton //KillDebugserverProcess (); 500f9765acdSGreg Clayton return error; 501f9765acdSGreg Clayton } 502f9765acdSGreg Clayton 503f9765acdSGreg Clayton Error 504f9765acdSGreg Clayton ProcessKDP::DoDestroy () 505f9765acdSGreg Clayton { 506f9765acdSGreg Clayton Error error; 507f9765acdSGreg Clayton LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS)); 508f9765acdSGreg Clayton if (log) 509f9765acdSGreg Clayton log->Printf ("ProcessKDP::DoDestroy()"); 510f9765acdSGreg Clayton 511f9765acdSGreg Clayton // Interrupt if our inferior is running... 512f9765acdSGreg Clayton if (m_comm.IsConnected()) 513f9765acdSGreg Clayton { 514*3a29bdbeSGreg Clayton m_comm.SendRequestDisconnect(); 515*3a29bdbeSGreg Clayton 516f9765acdSGreg Clayton if (m_public_state.GetValue() == eStateAttaching) 517f9765acdSGreg Clayton { 518f9765acdSGreg Clayton // We are being asked to halt during an attach. We need to just close 519f9765acdSGreg Clayton // our file handle and debugserver will go away, and we can be done... 520f9765acdSGreg Clayton m_comm.Disconnect(); 521f9765acdSGreg Clayton } 522f9765acdSGreg Clayton else 523f9765acdSGreg Clayton { 524f9765acdSGreg Clayton 525f9765acdSGreg Clayton StringExtractor response; 526f9765acdSGreg Clayton // TODO: Send kill packet? 527f9765acdSGreg Clayton SetExitStatus(SIGABRT, NULL); 528f9765acdSGreg Clayton } 529f9765acdSGreg Clayton } 530f9765acdSGreg Clayton StopAsyncThread (); 531f9765acdSGreg Clayton m_comm.StopReadThread(); 532f9765acdSGreg Clayton m_comm.Disconnect(); // Disconnect from the debug server. 533f9765acdSGreg Clayton return error; 534f9765acdSGreg Clayton } 535f9765acdSGreg Clayton 536f9765acdSGreg Clayton //------------------------------------------------------------------ 537f9765acdSGreg Clayton // Process Queries 538f9765acdSGreg Clayton //------------------------------------------------------------------ 539f9765acdSGreg Clayton 540f9765acdSGreg Clayton bool 541f9765acdSGreg Clayton ProcessKDP::IsAlive () 542f9765acdSGreg Clayton { 543f9765acdSGreg Clayton return m_comm.IsConnected() && m_private_state.GetValue() != eStateExited; 544f9765acdSGreg Clayton } 545f9765acdSGreg Clayton 546f9765acdSGreg Clayton //------------------------------------------------------------------ 547f9765acdSGreg Clayton // Process Memory 548f9765acdSGreg Clayton //------------------------------------------------------------------ 549f9765acdSGreg Clayton size_t 550f9765acdSGreg Clayton ProcessKDP::DoReadMemory (addr_t addr, void *buf, size_t size, Error &error) 551f9765acdSGreg Clayton { 552f9765acdSGreg Clayton error.SetErrorString ("ProcessKDP::DoReadMemory not implemented"); 553f9765acdSGreg Clayton return 0; 554f9765acdSGreg Clayton } 555f9765acdSGreg Clayton 556f9765acdSGreg Clayton size_t 557f9765acdSGreg Clayton ProcessKDP::DoWriteMemory (addr_t addr, const void *buf, size_t size, Error &error) 558f9765acdSGreg Clayton { 559f9765acdSGreg Clayton error.SetErrorString ("ProcessKDP::DoReadMemory not implemented"); 560f9765acdSGreg Clayton return 0; 561f9765acdSGreg Clayton } 562f9765acdSGreg Clayton 563f9765acdSGreg Clayton lldb::addr_t 564f9765acdSGreg Clayton ProcessKDP::DoAllocateMemory (size_t size, uint32_t permissions, Error &error) 565f9765acdSGreg Clayton { 566f9765acdSGreg Clayton error.SetErrorString ("memory allocation not suppported in kdp remote debugging"); 567f9765acdSGreg Clayton return LLDB_INVALID_ADDRESS; 568f9765acdSGreg Clayton } 569f9765acdSGreg Clayton 570f9765acdSGreg Clayton Error 571f9765acdSGreg Clayton ProcessKDP::DoDeallocateMemory (lldb::addr_t addr) 572f9765acdSGreg Clayton { 573f9765acdSGreg Clayton Error error; 574f9765acdSGreg Clayton error.SetErrorString ("memory deallocation not suppported in kdp remote debugging"); 575f9765acdSGreg Clayton return error; 576f9765acdSGreg Clayton } 577f9765acdSGreg Clayton 578f9765acdSGreg Clayton Error 579f9765acdSGreg Clayton ProcessKDP::EnableBreakpoint (BreakpointSite *bp_site) 580f9765acdSGreg Clayton { 581f9765acdSGreg Clayton return EnableSoftwareBreakpoint (bp_site); 582f9765acdSGreg Clayton } 583f9765acdSGreg Clayton 584f9765acdSGreg Clayton Error 585f9765acdSGreg Clayton ProcessKDP::DisableBreakpoint (BreakpointSite *bp_site) 586f9765acdSGreg Clayton { 587f9765acdSGreg Clayton return DisableSoftwareBreakpoint (bp_site); 588f9765acdSGreg Clayton } 589f9765acdSGreg Clayton 590f9765acdSGreg Clayton Error 591f9765acdSGreg Clayton ProcessKDP::EnableWatchpoint (WatchpointLocation *wp) 592f9765acdSGreg Clayton { 593f9765acdSGreg Clayton Error error; 594f9765acdSGreg Clayton error.SetErrorString ("watchpoints are not suppported in kdp remote debugging"); 595f9765acdSGreg Clayton return error; 596f9765acdSGreg Clayton } 597f9765acdSGreg Clayton 598f9765acdSGreg Clayton Error 599f9765acdSGreg Clayton ProcessKDP::DisableWatchpoint (WatchpointLocation *wp) 600f9765acdSGreg Clayton { 601f9765acdSGreg Clayton Error error; 602f9765acdSGreg Clayton error.SetErrorString ("watchpoints are not suppported in kdp remote debugging"); 603f9765acdSGreg Clayton return error; 604f9765acdSGreg Clayton } 605f9765acdSGreg Clayton 606f9765acdSGreg Clayton void 607f9765acdSGreg Clayton ProcessKDP::Clear() 608f9765acdSGreg Clayton { 609f9765acdSGreg Clayton Mutex::Locker locker (m_thread_list.GetMutex ()); 610f9765acdSGreg Clayton m_thread_list.Clear(); 611f9765acdSGreg Clayton } 612f9765acdSGreg Clayton 613f9765acdSGreg Clayton Error 614f9765acdSGreg Clayton ProcessKDP::DoSignal (int signo) 615f9765acdSGreg Clayton { 616f9765acdSGreg Clayton Error error; 617f9765acdSGreg Clayton error.SetErrorString ("sending signals is not suppported in kdp remote debugging"); 618f9765acdSGreg Clayton return error; 619f9765acdSGreg Clayton } 620f9765acdSGreg Clayton 621f9765acdSGreg Clayton void 622f9765acdSGreg Clayton ProcessKDP::Initialize() 623f9765acdSGreg Clayton { 624f9765acdSGreg Clayton static bool g_initialized = false; 625f9765acdSGreg Clayton 626f9765acdSGreg Clayton if (g_initialized == false) 627f9765acdSGreg Clayton { 628f9765acdSGreg Clayton g_initialized = true; 629f9765acdSGreg Clayton PluginManager::RegisterPlugin (GetPluginNameStatic(), 630f9765acdSGreg Clayton GetPluginDescriptionStatic(), 631f9765acdSGreg Clayton CreateInstance); 632f9765acdSGreg Clayton 633f9765acdSGreg Clayton Log::Callbacks log_callbacks = { 634f9765acdSGreg Clayton ProcessKDPLog::DisableLog, 635f9765acdSGreg Clayton ProcessKDPLog::EnableLog, 636f9765acdSGreg Clayton ProcessKDPLog::ListLogCategories 637f9765acdSGreg Clayton }; 638f9765acdSGreg Clayton 639f9765acdSGreg Clayton Log::RegisterLogChannel (ProcessKDP::GetPluginNameStatic(), log_callbacks); 640f9765acdSGreg Clayton } 641f9765acdSGreg Clayton } 642f9765acdSGreg Clayton 643f9765acdSGreg Clayton bool 644f9765acdSGreg Clayton ProcessKDP::StartAsyncThread () 645f9765acdSGreg Clayton { 646f9765acdSGreg Clayton LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS)); 647f9765acdSGreg Clayton 648f9765acdSGreg Clayton if (log) 649f9765acdSGreg Clayton log->Printf ("ProcessKDP::%s ()", __FUNCTION__); 650f9765acdSGreg Clayton 651f9765acdSGreg Clayton // Create a thread that watches our internal state and controls which 652f9765acdSGreg Clayton // events make it to clients (into the DCProcess event queue). 653f9765acdSGreg Clayton m_async_thread = Host::ThreadCreate ("<lldb.process.kdp-remote.async>", ProcessKDP::AsyncThread, this, NULL); 654f9765acdSGreg Clayton return IS_VALID_LLDB_HOST_THREAD(m_async_thread); 655f9765acdSGreg Clayton } 656f9765acdSGreg Clayton 657f9765acdSGreg Clayton void 658f9765acdSGreg Clayton ProcessKDP::StopAsyncThread () 659f9765acdSGreg Clayton { 660f9765acdSGreg Clayton LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS)); 661f9765acdSGreg Clayton 662f9765acdSGreg Clayton if (log) 663f9765acdSGreg Clayton log->Printf ("ProcessKDP::%s ()", __FUNCTION__); 664f9765acdSGreg Clayton 665f9765acdSGreg Clayton m_async_broadcaster.BroadcastEvent (eBroadcastBitAsyncThreadShouldExit); 666f9765acdSGreg Clayton 667f9765acdSGreg Clayton // Stop the stdio thread 668f9765acdSGreg Clayton if (IS_VALID_LLDB_HOST_THREAD(m_async_thread)) 669f9765acdSGreg Clayton { 670f9765acdSGreg Clayton Host::ThreadJoin (m_async_thread, NULL, NULL); 671f9765acdSGreg Clayton } 672f9765acdSGreg Clayton } 673f9765acdSGreg Clayton 674f9765acdSGreg Clayton 675f9765acdSGreg Clayton void * 676f9765acdSGreg Clayton ProcessKDP::AsyncThread (void *arg) 677f9765acdSGreg Clayton { 678f9765acdSGreg Clayton ProcessKDP *process = (ProcessKDP*) arg; 679f9765acdSGreg Clayton 680f9765acdSGreg Clayton LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_PROCESS)); 681f9765acdSGreg Clayton if (log) 682f9765acdSGreg Clayton log->Printf ("ProcessKDP::%s (arg = %p, pid = %i) thread starting...", __FUNCTION__, arg, process->GetID()); 683f9765acdSGreg Clayton 684f9765acdSGreg Clayton Listener listener ("ProcessKDP::AsyncThread"); 685f9765acdSGreg Clayton EventSP event_sp; 686f9765acdSGreg Clayton const uint32_t desired_event_mask = eBroadcastBitAsyncContinue | 687f9765acdSGreg Clayton eBroadcastBitAsyncThreadShouldExit; 688f9765acdSGreg Clayton 689f9765acdSGreg Clayton if (listener.StartListeningForEvents (&process->m_async_broadcaster, desired_event_mask) == desired_event_mask) 690f9765acdSGreg Clayton { 691f9765acdSGreg Clayton listener.StartListeningForEvents (&process->m_comm, Communication::eBroadcastBitReadThreadDidExit); 692f9765acdSGreg Clayton 693f9765acdSGreg Clayton bool done = false; 694f9765acdSGreg Clayton while (!done) 695f9765acdSGreg Clayton { 696f9765acdSGreg Clayton if (log) 697f9765acdSGreg Clayton log->Printf ("ProcessKDP::%s (arg = %p, pid = %i) listener.WaitForEvent (NULL, event_sp)...", __FUNCTION__, arg, process->GetID()); 698f9765acdSGreg Clayton if (listener.WaitForEvent (NULL, event_sp)) 699f9765acdSGreg Clayton { 700f9765acdSGreg Clayton const uint32_t event_type = event_sp->GetType(); 701f9765acdSGreg Clayton if (event_sp->BroadcasterIs (&process->m_async_broadcaster)) 702f9765acdSGreg Clayton { 703f9765acdSGreg Clayton if (log) 704f9765acdSGreg Clayton log->Printf ("ProcessKDP::%s (arg = %p, pid = %i) Got an event of type: %d...", __FUNCTION__, arg, process->GetID(), event_type); 705f9765acdSGreg Clayton 706f9765acdSGreg Clayton switch (event_type) 707f9765acdSGreg Clayton { 708f9765acdSGreg Clayton case eBroadcastBitAsyncContinue: 709f9765acdSGreg Clayton { 710f9765acdSGreg Clayton const EventDataBytes *continue_packet = EventDataBytes::GetEventDataFromEvent(event_sp.get()); 711f9765acdSGreg Clayton 712f9765acdSGreg Clayton if (continue_packet) 713f9765acdSGreg Clayton { 714f9765acdSGreg Clayton // TODO: do continue support here 715f9765acdSGreg Clayton 716f9765acdSGreg Clayton // const char *continue_cstr = (const char *)continue_packet->GetBytes (); 717f9765acdSGreg Clayton // const size_t continue_cstr_len = continue_packet->GetByteSize (); 718f9765acdSGreg Clayton // if (log) 719f9765acdSGreg Clayton // log->Printf ("ProcessKDP::%s (arg = %p, pid = %i) got eBroadcastBitAsyncContinue: %s", __FUNCTION__, arg, process->GetID(), continue_cstr); 720f9765acdSGreg Clayton // 721f9765acdSGreg Clayton // if (::strstr (continue_cstr, "vAttach") == NULL) 722f9765acdSGreg Clayton // process->SetPrivateState(eStateRunning); 723f9765acdSGreg Clayton // StringExtractor response; 724f9765acdSGreg Clayton // StateType stop_state = process->GetCommunication().SendContinuePacketAndWaitForResponse (process, continue_cstr, continue_cstr_len, response); 725f9765acdSGreg Clayton // 726f9765acdSGreg Clayton // switch (stop_state) 727f9765acdSGreg Clayton // { 728f9765acdSGreg Clayton // case eStateStopped: 729f9765acdSGreg Clayton // case eStateCrashed: 730f9765acdSGreg Clayton // case eStateSuspended: 731f9765acdSGreg Clayton // process->m_last_stop_packet = response; 732f9765acdSGreg Clayton // process->SetPrivateState (stop_state); 733f9765acdSGreg Clayton // break; 734f9765acdSGreg Clayton // 735f9765acdSGreg Clayton // case eStateExited: 736f9765acdSGreg Clayton // process->m_last_stop_packet = response; 737f9765acdSGreg Clayton // response.SetFilePos(1); 738f9765acdSGreg Clayton // process->SetExitStatus(response.GetHexU8(), NULL); 739f9765acdSGreg Clayton // done = true; 740f9765acdSGreg Clayton // break; 741f9765acdSGreg Clayton // 742f9765acdSGreg Clayton // case eStateInvalid: 743f9765acdSGreg Clayton // process->SetExitStatus(-1, "lost connection"); 744f9765acdSGreg Clayton // break; 745f9765acdSGreg Clayton // 746f9765acdSGreg Clayton // default: 747f9765acdSGreg Clayton // process->SetPrivateState (stop_state); 748f9765acdSGreg Clayton // break; 749f9765acdSGreg Clayton // } 750f9765acdSGreg Clayton } 751f9765acdSGreg Clayton } 752f9765acdSGreg Clayton break; 753f9765acdSGreg Clayton 754f9765acdSGreg Clayton case eBroadcastBitAsyncThreadShouldExit: 755f9765acdSGreg Clayton if (log) 756f9765acdSGreg Clayton log->Printf ("ProcessKDP::%s (arg = %p, pid = %i) got eBroadcastBitAsyncThreadShouldExit...", __FUNCTION__, arg, process->GetID()); 757f9765acdSGreg Clayton done = true; 758f9765acdSGreg Clayton break; 759f9765acdSGreg Clayton 760f9765acdSGreg Clayton default: 761f9765acdSGreg Clayton if (log) 762f9765acdSGreg Clayton log->Printf ("ProcessKDP::%s (arg = %p, pid = %i) got unknown event 0x%8.8x", __FUNCTION__, arg, process->GetID(), event_type); 763f9765acdSGreg Clayton done = true; 764f9765acdSGreg Clayton break; 765f9765acdSGreg Clayton } 766f9765acdSGreg Clayton } 767f9765acdSGreg Clayton else if (event_sp->BroadcasterIs (&process->m_comm)) 768f9765acdSGreg Clayton { 769f9765acdSGreg Clayton if (event_type & Communication::eBroadcastBitReadThreadDidExit) 770f9765acdSGreg Clayton { 771f9765acdSGreg Clayton process->SetExitStatus (-1, "lost connection"); 772f9765acdSGreg Clayton done = true; 773f9765acdSGreg Clayton } 774f9765acdSGreg Clayton } 775f9765acdSGreg Clayton } 776f9765acdSGreg Clayton else 777f9765acdSGreg Clayton { 778f9765acdSGreg Clayton if (log) 779f9765acdSGreg Clayton log->Printf ("ProcessKDP::%s (arg = %p, pid = %i) listener.WaitForEvent (NULL, event_sp) => false", __FUNCTION__, arg, process->GetID()); 780f9765acdSGreg Clayton done = true; 781f9765acdSGreg Clayton } 782f9765acdSGreg Clayton } 783f9765acdSGreg Clayton } 784f9765acdSGreg Clayton 785f9765acdSGreg Clayton if (log) 786f9765acdSGreg Clayton log->Printf ("ProcessKDP::%s (arg = %p, pid = %i) thread exiting...", __FUNCTION__, arg, process->GetID()); 787f9765acdSGreg Clayton 788f9765acdSGreg Clayton process->m_async_thread = LLDB_INVALID_HOST_THREAD; 789f9765acdSGreg Clayton return NULL; 790f9765acdSGreg Clayton } 791f9765acdSGreg Clayton 792f9765acdSGreg Clayton 793