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" 191f746071SGreg Clayton #include "lldb/Core/Module.h" 20*4bd4e7e3SJason Molenda #include "lldb/Core/ModuleSpec.h" 21f9765acdSGreg Clayton #include "lldb/Core/State.h" 22*4bd4e7e3SJason Molenda #include "lldb/Core/UUID.h" 23f9765acdSGreg Clayton #include "lldb/Host/Host.h" 24*4bd4e7e3SJason Molenda #include "lldb/Host/Symbols.h" 251f746071SGreg Clayton #include "lldb/Symbol/ObjectFile.h" 267925fbbaSGreg Clayton #include "lldb/Target/RegisterContext.h" 2757508026SGreg Clayton #include "lldb/Target/Target.h" 28a63d08c9SGreg Clayton #include "lldb/Target/Thread.h" 29f9765acdSGreg Clayton 30f9765acdSGreg Clayton // Project includes 31f9765acdSGreg Clayton #include "ProcessKDP.h" 32f9765acdSGreg Clayton #include "ProcessKDPLog.h" 33a63d08c9SGreg Clayton #include "ThreadKDP.h" 34f9765acdSGreg Clayton 35f9765acdSGreg Clayton using namespace lldb; 36f9765acdSGreg Clayton using namespace lldb_private; 37f9765acdSGreg Clayton 38f9765acdSGreg Clayton const char * 39f9765acdSGreg Clayton ProcessKDP::GetPluginNameStatic() 40f9765acdSGreg Clayton { 41f9765acdSGreg Clayton return "kdp-remote"; 42f9765acdSGreg Clayton } 43f9765acdSGreg Clayton 44f9765acdSGreg Clayton const char * 45f9765acdSGreg Clayton ProcessKDP::GetPluginDescriptionStatic() 46f9765acdSGreg Clayton { 47f9765acdSGreg Clayton return "KDP Remote protocol based debugging plug-in for darwin kernel debugging."; 48f9765acdSGreg Clayton } 49f9765acdSGreg Clayton 50f9765acdSGreg Clayton void 51f9765acdSGreg Clayton ProcessKDP::Terminate() 52f9765acdSGreg Clayton { 53f9765acdSGreg Clayton PluginManager::UnregisterPlugin (ProcessKDP::CreateInstance); 54f9765acdSGreg Clayton } 55f9765acdSGreg Clayton 56f9765acdSGreg Clayton 57c3776bf2SGreg Clayton lldb::ProcessSP 58c3776bf2SGreg Clayton ProcessKDP::CreateInstance (Target &target, 59c3776bf2SGreg Clayton Listener &listener, 60c3776bf2SGreg Clayton const FileSpec *crash_file_path) 61f9765acdSGreg Clayton { 62c3776bf2SGreg Clayton lldb::ProcessSP process_sp; 63c3776bf2SGreg Clayton if (crash_file_path == NULL) 64c3776bf2SGreg Clayton process_sp.reset(new ProcessKDP (target, listener)); 65c3776bf2SGreg Clayton return process_sp; 66f9765acdSGreg Clayton } 67f9765acdSGreg Clayton 68f9765acdSGreg Clayton bool 693a29bdbeSGreg Clayton ProcessKDP::CanDebug(Target &target, bool plugin_specified_by_name) 70f9765acdSGreg Clayton { 71596ed24eSGreg Clayton if (plugin_specified_by_name) 72596ed24eSGreg Clayton return true; 73596ed24eSGreg Clayton 74f9765acdSGreg Clayton // For now we are just making sure the file exists for a given module 75aa149cbdSGreg Clayton Module *exe_module = target.GetExecutableModulePointer(); 76aa149cbdSGreg Clayton if (exe_module) 77f9765acdSGreg Clayton { 78f9765acdSGreg Clayton const llvm::Triple &triple_ref = target.GetArchitecture().GetTriple(); 7970512317SGreg Clayton switch (triple_ref.getOS()) 8070512317SGreg Clayton { 8170512317SGreg Clayton case llvm::Triple::Darwin: // Should use "macosx" for desktop and "ios" for iOS, but accept darwin just in case 8270512317SGreg Clayton case llvm::Triple::MacOSX: // For desktop targets 8370512317SGreg Clayton case llvm::Triple::IOS: // For arm targets 8470512317SGreg Clayton if (triple_ref.getVendor() == llvm::Triple::Apple) 85f9765acdSGreg Clayton { 86aa149cbdSGreg Clayton ObjectFile *exe_objfile = exe_module->GetObjectFile(); 87f9765acdSGreg Clayton if (exe_objfile->GetType() == ObjectFile::eTypeExecutable && 88f9765acdSGreg Clayton exe_objfile->GetStrata() == ObjectFile::eStrataKernel) 89f9765acdSGreg Clayton return true; 90f9765acdSGreg Clayton } 9170512317SGreg Clayton break; 9270512317SGreg Clayton 9370512317SGreg Clayton default: 9470512317SGreg Clayton break; 9570512317SGreg Clayton } 96f9765acdSGreg Clayton } 97596ed24eSGreg Clayton return false; 983a29bdbeSGreg Clayton } 99f9765acdSGreg Clayton 100f9765acdSGreg Clayton //---------------------------------------------------------------------- 101f9765acdSGreg Clayton // ProcessKDP constructor 102f9765acdSGreg Clayton //---------------------------------------------------------------------- 103f9765acdSGreg Clayton ProcessKDP::ProcessKDP(Target& target, Listener &listener) : 104f9765acdSGreg Clayton Process (target, listener), 105f9765acdSGreg Clayton m_comm("lldb.process.kdp-remote.communication"), 1064bddaeb5SJim Ingham m_async_broadcaster (NULL, "lldb.process.kdp-remote.async-broadcaster"), 10797d5cf05SGreg Clayton m_async_thread (LLDB_INVALID_HOST_THREAD), 10897d5cf05SGreg Clayton m_destroy_in_process (false) 109f9765acdSGreg Clayton { 1107925fbbaSGreg Clayton m_async_broadcaster.SetEventName (eBroadcastBitAsyncThreadShouldExit, "async thread should exit"); 1117925fbbaSGreg Clayton m_async_broadcaster.SetEventName (eBroadcastBitAsyncContinue, "async thread continue"); 112f9765acdSGreg Clayton } 113f9765acdSGreg Clayton 114f9765acdSGreg Clayton //---------------------------------------------------------------------- 115f9765acdSGreg Clayton // Destructor 116f9765acdSGreg Clayton //---------------------------------------------------------------------- 117f9765acdSGreg Clayton ProcessKDP::~ProcessKDP() 118f9765acdSGreg Clayton { 119f9765acdSGreg Clayton Clear(); 120e24c4acfSGreg Clayton // We need to call finalize on the process before destroying ourselves 121e24c4acfSGreg Clayton // to make sure all of the broadcaster cleanup goes as planned. If we 122e24c4acfSGreg Clayton // destruct this class, then Process::~Process() might have problems 123e24c4acfSGreg Clayton // trying to fully destroy the broadcaster. 124e24c4acfSGreg Clayton Finalize(); 125f9765acdSGreg Clayton } 126f9765acdSGreg Clayton 127f9765acdSGreg Clayton //---------------------------------------------------------------------- 128f9765acdSGreg Clayton // PluginInterface 129f9765acdSGreg Clayton //---------------------------------------------------------------------- 130f9765acdSGreg Clayton const char * 131f9765acdSGreg Clayton ProcessKDP::GetPluginName() 132f9765acdSGreg Clayton { 133f9765acdSGreg Clayton return "Process debugging plug-in that uses the Darwin KDP remote protocol"; 134f9765acdSGreg Clayton } 135f9765acdSGreg Clayton 136f9765acdSGreg Clayton const char * 137f9765acdSGreg Clayton ProcessKDP::GetShortPluginName() 138f9765acdSGreg Clayton { 139f9765acdSGreg Clayton return GetPluginNameStatic(); 140f9765acdSGreg Clayton } 141f9765acdSGreg Clayton 142f9765acdSGreg Clayton uint32_t 143f9765acdSGreg Clayton ProcessKDP::GetPluginVersion() 144f9765acdSGreg Clayton { 145f9765acdSGreg Clayton return 1; 146f9765acdSGreg Clayton } 147f9765acdSGreg Clayton 148f9765acdSGreg Clayton Error 149f9765acdSGreg Clayton ProcessKDP::WillLaunch (Module* module) 150f9765acdSGreg Clayton { 151f9765acdSGreg Clayton Error error; 152f9765acdSGreg Clayton error.SetErrorString ("launching not supported in kdp-remote plug-in"); 153f9765acdSGreg Clayton return error; 154f9765acdSGreg Clayton } 155f9765acdSGreg Clayton 156f9765acdSGreg Clayton Error 157f9765acdSGreg Clayton ProcessKDP::WillAttachToProcessWithID (lldb::pid_t pid) 158f9765acdSGreg Clayton { 159f9765acdSGreg Clayton Error error; 160f9765acdSGreg Clayton error.SetErrorString ("attaching to a by process ID not supported in kdp-remote plug-in"); 161f9765acdSGreg Clayton return error; 162f9765acdSGreg Clayton } 163f9765acdSGreg Clayton 164f9765acdSGreg Clayton Error 165f9765acdSGreg Clayton ProcessKDP::WillAttachToProcessWithName (const char *process_name, bool wait_for_launch) 166f9765acdSGreg Clayton { 167f9765acdSGreg Clayton Error error; 168f9765acdSGreg Clayton error.SetErrorString ("attaching to a by process name not supported in kdp-remote plug-in"); 169f9765acdSGreg Clayton return error; 170f9765acdSGreg Clayton } 171f9765acdSGreg Clayton 172f9765acdSGreg Clayton Error 173*4bd4e7e3SJason Molenda ProcessKDP::DoConnectRemote (Stream *strm, const char *remote_url) 174f9765acdSGreg Clayton { 175f9765acdSGreg Clayton Error error; 1763a29bdbeSGreg Clayton 1777925fbbaSGreg Clayton // Don't let any JIT happen when doing KDP as we can't allocate 1787925fbbaSGreg Clayton // memory and we don't want to be mucking with threads that might 1797925fbbaSGreg Clayton // already be handling exceptions 1807925fbbaSGreg Clayton SetCanJIT(false); 1817925fbbaSGreg Clayton 1823a29bdbeSGreg Clayton if (remote_url == NULL || remote_url[0] == '\0') 1837925fbbaSGreg Clayton { 1847925fbbaSGreg Clayton error.SetErrorStringWithFormat ("invalid connection URL '%s'", remote_url); 1857925fbbaSGreg Clayton return error; 1867925fbbaSGreg Clayton } 1873a29bdbeSGreg Clayton 1883a29bdbeSGreg Clayton std::auto_ptr<ConnectionFileDescriptor> conn_ap(new ConnectionFileDescriptor()); 1893a29bdbeSGreg Clayton if (conn_ap.get()) 1903a29bdbeSGreg Clayton { 1913a29bdbeSGreg Clayton // Only try once for now. 1923a29bdbeSGreg Clayton // TODO: check if we should be retrying? 1933a29bdbeSGreg Clayton const uint32_t max_retry_count = 1; 1943a29bdbeSGreg Clayton for (uint32_t retry_count = 0; retry_count < max_retry_count; ++retry_count) 1953a29bdbeSGreg Clayton { 1963a29bdbeSGreg Clayton if (conn_ap->Connect(remote_url, &error) == eConnectionStatusSuccess) 1973a29bdbeSGreg Clayton break; 1983a29bdbeSGreg Clayton usleep (100000); 1993a29bdbeSGreg Clayton } 2003a29bdbeSGreg Clayton } 2013a29bdbeSGreg Clayton 2023a29bdbeSGreg Clayton if (conn_ap->IsConnected()) 2033a29bdbeSGreg Clayton { 2043a29bdbeSGreg Clayton const uint16_t reply_port = conn_ap->GetReadPort (); 2053a29bdbeSGreg Clayton 2063a29bdbeSGreg Clayton if (reply_port != 0) 2073a29bdbeSGreg Clayton { 2083a29bdbeSGreg Clayton m_comm.SetConnection(conn_ap.release()); 2093a29bdbeSGreg Clayton 2103a29bdbeSGreg Clayton if (m_comm.SendRequestReattach(reply_port)) 2113a29bdbeSGreg Clayton { 2123a29bdbeSGreg Clayton if (m_comm.SendRequestConnect(reply_port, reply_port, "Greetings from LLDB...")) 2133a29bdbeSGreg Clayton { 2143a29bdbeSGreg Clayton m_comm.GetVersion(); 2153a29bdbeSGreg Clayton uint32_t cpu = m_comm.GetCPUType(); 2163a29bdbeSGreg Clayton uint32_t sub = m_comm.GetCPUSubtype(); 2173a29bdbeSGreg Clayton ArchSpec kernel_arch; 2183a29bdbeSGreg Clayton kernel_arch.SetArchitecture(eArchTypeMachO, cpu, sub); 2193a29bdbeSGreg Clayton m_target.SetArchitecture(kernel_arch); 220*4bd4e7e3SJason Molenda 221*4bd4e7e3SJason Molenda /* Get the kernel's UUID and load address via kdp-kernelversion packet. */ 222*4bd4e7e3SJason Molenda 223*4bd4e7e3SJason Molenda UUID kernel_uuid = m_comm.GetUUID (); 224*4bd4e7e3SJason Molenda addr_t kernel_load_addr = m_comm.GetLoadAddress (); 225*4bd4e7e3SJason Molenda if (strm) 226*4bd4e7e3SJason Molenda { 227*4bd4e7e3SJason Molenda char uuidbuf[64]; 228*4bd4e7e3SJason Molenda strm->Printf ("Kernel UUID: %s\n", kernel_uuid.GetAsCString (uuidbuf, sizeof (uuidbuf))); 229*4bd4e7e3SJason Molenda strm->Printf ("Load Address: 0x%llx\n", kernel_load_addr); 230*4bd4e7e3SJason Molenda strm->Flush (); 231*4bd4e7e3SJason Molenda } 232*4bd4e7e3SJason Molenda 233*4bd4e7e3SJason Molenda /* Set the kernel's LoadAddress based on the information from kdp. 234*4bd4e7e3SJason Molenda This would normally be handled by the DynamicLoaderDarwinKernel plugin but there's no easy 235*4bd4e7e3SJason Molenda way to communicate the UUID / load addr from kdp back up to that plugin so we'll set it here. */ 236*4bd4e7e3SJason Molenda ModuleSP exe_module_sp = m_target.GetExecutableModule (); 237*4bd4e7e3SJason Molenda bool find_and_load_kernel = true; 238*4bd4e7e3SJason Molenda if (exe_module_sp.get ()) 239*4bd4e7e3SJason Molenda { 240*4bd4e7e3SJason Molenda ObjectFile *exe_objfile = exe_module_sp->GetObjectFile(); 241*4bd4e7e3SJason Molenda if (exe_objfile->GetType() == ObjectFile::eTypeExecutable && 242*4bd4e7e3SJason Molenda exe_objfile->GetStrata() == ObjectFile::eStrataKernel) 243*4bd4e7e3SJason Molenda { 244*4bd4e7e3SJason Molenda UUID exe_objfile_uuid; 245*4bd4e7e3SJason Molenda if (exe_objfile->GetUUID (&exe_objfile_uuid) && kernel_uuid == exe_objfile_uuid 246*4bd4e7e3SJason Molenda && exe_objfile->GetHeaderAddress().IsValid()) 247*4bd4e7e3SJason Molenda { 248*4bd4e7e3SJason Molenda find_and_load_kernel = false; 249*4bd4e7e3SJason Molenda addr_t slide = kernel_load_addr - exe_objfile->GetHeaderAddress().GetFileAddress(); 250*4bd4e7e3SJason Molenda if (slide != 0) 251*4bd4e7e3SJason Molenda { 252*4bd4e7e3SJason Molenda bool changed = false; 253*4bd4e7e3SJason Molenda exe_module_sp->SetLoadAddress (m_target, slide, changed); 254*4bd4e7e3SJason Molenda if (changed) 255*4bd4e7e3SJason Molenda { 256*4bd4e7e3SJason Molenda ModuleList modlist; 257*4bd4e7e3SJason Molenda modlist.Append (exe_module_sp); 258*4bd4e7e3SJason Molenda m_target.ModulesDidLoad (modlist); 259*4bd4e7e3SJason Molenda } 260*4bd4e7e3SJason Molenda } 261*4bd4e7e3SJason Molenda } 262*4bd4e7e3SJason Molenda } 263*4bd4e7e3SJason Molenda } 264*4bd4e7e3SJason Molenda 265*4bd4e7e3SJason Molenda // If the executable binary is not the same as the kernel being run on the remote host, 266*4bd4e7e3SJason Molenda // see if Symbols::DownloadObjectAndSymbolFile can find us a symbol file based on the UUID 267*4bd4e7e3SJason Molenda // and if so, load it at the correct address. 268*4bd4e7e3SJason Molenda if (find_and_load_kernel && kernel_load_addr != LLDB_INVALID_ADDRESS && kernel_uuid.IsValid()) 269*4bd4e7e3SJason Molenda { 270*4bd4e7e3SJason Molenda ModuleSpec sym_spec; 271*4bd4e7e3SJason Molenda sym_spec.GetUUID() = kernel_uuid; 272*4bd4e7e3SJason Molenda if (Symbols::DownloadObjectAndSymbolFile (sym_spec) 273*4bd4e7e3SJason Molenda && sym_spec.GetArchitecture().IsValid() 274*4bd4e7e3SJason Molenda && sym_spec.GetSymbolFileSpec().Exists()) 275*4bd4e7e3SJason Molenda { 276*4bd4e7e3SJason Molenda ModuleSP kernel_sp = m_target.GetSharedModule (sym_spec); 277*4bd4e7e3SJason Molenda if (kernel_sp.get()) 278*4bd4e7e3SJason Molenda { 279*4bd4e7e3SJason Molenda m_target.SetExecutableModule(kernel_sp, false); 280*4bd4e7e3SJason Molenda if (kernel_sp->GetObjectFile() && kernel_sp->GetObjectFile()->GetHeaderAddress().IsValid()) 281*4bd4e7e3SJason Molenda { 282*4bd4e7e3SJason Molenda addr_t slide = kernel_load_addr - kernel_sp->GetObjectFile()->GetHeaderAddress().GetFileAddress(); 283*4bd4e7e3SJason Molenda bool changed = false; 284*4bd4e7e3SJason Molenda kernel_sp->SetLoadAddress (m_target, slide, changed); 285*4bd4e7e3SJason Molenda if (changed) 286*4bd4e7e3SJason Molenda { 287*4bd4e7e3SJason Molenda ModuleList modlist; 288*4bd4e7e3SJason Molenda modlist.Append (kernel_sp); 289*4bd4e7e3SJason Molenda m_target.ModulesDidLoad (modlist); 290*4bd4e7e3SJason Molenda } 291*4bd4e7e3SJason Molenda if (strm) 292*4bd4e7e3SJason Molenda { 293*4bd4e7e3SJason Molenda strm->Printf ("Loaded kernel file %s/%s\n", 294*4bd4e7e3SJason Molenda kernel_sp->GetFileSpec().GetDirectory().AsCString(), 295*4bd4e7e3SJason Molenda kernel_sp->GetFileSpec().GetFilename().AsCString()); 296*4bd4e7e3SJason Molenda strm->Flush (); 297*4bd4e7e3SJason Molenda } 298*4bd4e7e3SJason Molenda } 299*4bd4e7e3SJason Molenda } 300*4bd4e7e3SJason Molenda } 301*4bd4e7e3SJason Molenda } 302*4bd4e7e3SJason Molenda 303*4bd4e7e3SJason Molenda 30497d5cf05SGreg Clayton // Set the thread ID 30597d5cf05SGreg Clayton UpdateThreadListIfNeeded (); 306a63d08c9SGreg Clayton SetID (1); 30756d9a1b3SGreg Clayton GetThreadList (); 308a63d08c9SGreg Clayton SetPrivateState (eStateStopped); 30907e66e3eSGreg Clayton StreamSP async_strm_sp(m_target.GetDebugger().GetAsyncOutputStream()); 31007e66e3eSGreg Clayton if (async_strm_sp) 31107e66e3eSGreg Clayton { 3125b88216dSGreg Clayton const char *cstr; 3135b88216dSGreg Clayton if ((cstr = m_comm.GetKernelVersion ()) != NULL) 31407e66e3eSGreg Clayton { 3155b88216dSGreg Clayton async_strm_sp->Printf ("Version: %s\n", cstr); 31607e66e3eSGreg Clayton async_strm_sp->Flush(); 31707e66e3eSGreg Clayton } 3185b88216dSGreg Clayton // if ((cstr = m_comm.GetImagePath ()) != NULL) 3195b88216dSGreg Clayton // { 3205b88216dSGreg Clayton // async_strm_sp->Printf ("Image Path: %s\n", cstr); 3215b88216dSGreg Clayton // async_strm_sp->Flush(); 3225b88216dSGreg Clayton // } 32307e66e3eSGreg Clayton } 3243a29bdbeSGreg Clayton } 32597d5cf05SGreg Clayton else 32697d5cf05SGreg Clayton { 32797d5cf05SGreg Clayton puts ("KDP_CONNECT failed"); // REMOVE THIS 32897d5cf05SGreg Clayton error.SetErrorString("KDP_REATTACH failed"); 32997d5cf05SGreg Clayton } 3303a29bdbeSGreg Clayton } 3313a29bdbeSGreg Clayton else 3323a29bdbeSGreg Clayton { 33397d5cf05SGreg Clayton puts ("KDP_REATTACH failed"); // REMOVE THIS 33497d5cf05SGreg Clayton error.SetErrorString("KDP_REATTACH failed"); 3353a29bdbeSGreg Clayton } 3363a29bdbeSGreg Clayton } 3373a29bdbeSGreg Clayton else 3383a29bdbeSGreg Clayton { 3393a29bdbeSGreg Clayton error.SetErrorString("invalid reply port from UDP connection"); 3403a29bdbeSGreg Clayton } 3413a29bdbeSGreg Clayton } 3423a29bdbeSGreg Clayton else 3433a29bdbeSGreg Clayton { 3443a29bdbeSGreg Clayton if (error.Success()) 3453a29bdbeSGreg Clayton error.SetErrorStringWithFormat ("failed to connect to '%s'", remote_url); 3463a29bdbeSGreg Clayton } 3473a29bdbeSGreg Clayton if (error.Fail()) 3483a29bdbeSGreg Clayton m_comm.Disconnect(); 3493a29bdbeSGreg Clayton 350f9765acdSGreg Clayton return error; 351f9765acdSGreg Clayton } 352f9765acdSGreg Clayton 353f9765acdSGreg Clayton //---------------------------------------------------------------------- 354f9765acdSGreg Clayton // Process Control 355f9765acdSGreg Clayton //---------------------------------------------------------------------- 356f9765acdSGreg Clayton Error 357982c9762SGreg Clayton ProcessKDP::DoLaunch (Module *exe_module, 358982c9762SGreg Clayton const ProcessLaunchInfo &launch_info) 359f9765acdSGreg Clayton { 360f9765acdSGreg Clayton Error error; 361f9765acdSGreg Clayton error.SetErrorString ("launching not supported in kdp-remote plug-in"); 362f9765acdSGreg Clayton return error; 363f9765acdSGreg Clayton } 364f9765acdSGreg Clayton 365f9765acdSGreg Clayton 366f9765acdSGreg Clayton Error 367f9765acdSGreg Clayton ProcessKDP::DoAttachToProcessWithID (lldb::pid_t attach_pid) 368f9765acdSGreg Clayton { 369f9765acdSGreg Clayton Error error; 370f9765acdSGreg Clayton error.SetErrorString ("attach to process by ID is not suppported in kdp remote debugging"); 371f9765acdSGreg Clayton return error; 372f9765acdSGreg Clayton } 373f9765acdSGreg Clayton 374f9765acdSGreg Clayton Error 37584647048SHan Ming Ong ProcessKDP::DoAttachToProcessWithID (lldb::pid_t attach_pid, const ProcessAttachInfo &attach_info) 37684647048SHan Ming Ong { 37784647048SHan Ming Ong Error error; 37884647048SHan Ming Ong error.SetErrorString ("attach to process by ID is not suppported in kdp remote debugging"); 37984647048SHan Ming Ong return error; 38084647048SHan Ming Ong } 38184647048SHan Ming Ong 38284647048SHan Ming Ong Error 38384647048SHan Ming Ong ProcessKDP::DoAttachToProcessWithName (const char *process_name, bool wait_for_launch, const ProcessAttachInfo &attach_info) 384f9765acdSGreg Clayton { 385f9765acdSGreg Clayton Error error; 386f9765acdSGreg Clayton error.SetErrorString ("attach to process by name is not suppported in kdp remote debugging"); 387f9765acdSGreg Clayton return error; 388f9765acdSGreg Clayton } 389f9765acdSGreg Clayton 390f9765acdSGreg Clayton 391f9765acdSGreg Clayton void 392f9765acdSGreg Clayton ProcessKDP::DidAttach () 393f9765acdSGreg Clayton { 394f9765acdSGreg Clayton LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_PROCESS)); 395f9765acdSGreg Clayton if (log) 39654cb8f83SJohnny Chen log->Printf ("ProcessKDP::DidAttach()"); 397f9765acdSGreg Clayton if (GetID() != LLDB_INVALID_PROCESS_ID) 398f9765acdSGreg Clayton { 399f9765acdSGreg Clayton // TODO: figure out the register context that we will use 400f9765acdSGreg Clayton } 401f9765acdSGreg Clayton } 402f9765acdSGreg Clayton 403f9765acdSGreg Clayton Error 404f9765acdSGreg Clayton ProcessKDP::WillResume () 405f9765acdSGreg Clayton { 406f9765acdSGreg Clayton return Error(); 407f9765acdSGreg Clayton } 408f9765acdSGreg Clayton 409f9765acdSGreg Clayton Error 410f9765acdSGreg Clayton ProcessKDP::DoResume () 411f9765acdSGreg Clayton { 412f9765acdSGreg Clayton Error error; 4137925fbbaSGreg Clayton LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_PROCESS)); 4147925fbbaSGreg Clayton // Only start the async thread if we try to do any process control 4157925fbbaSGreg Clayton if (!IS_VALID_LLDB_HOST_THREAD(m_async_thread)) 4167925fbbaSGreg Clayton StartAsyncThread (); 4177925fbbaSGreg Clayton 41897d5cf05SGreg Clayton bool resume = false; 4197925fbbaSGreg Clayton 42097d5cf05SGreg Clayton // With KDP there is only one thread we can tell what to do 42197d5cf05SGreg Clayton ThreadSP kernel_thread_sp (GetKernelThread(m_thread_list, m_thread_list)); 42297d5cf05SGreg Clayton if (kernel_thread_sp) 4234b1b8b3eSGreg Clayton { 42497d5cf05SGreg Clayton const StateType thread_resume_state = kernel_thread_sp->GetTemporaryResumeState(); 4257925fbbaSGreg Clayton switch (thread_resume_state) 4264b1b8b3eSGreg Clayton { 4277925fbbaSGreg Clayton case eStateSuspended: 4287925fbbaSGreg Clayton // Nothing to do here when a thread will stay suspended 4297925fbbaSGreg Clayton // we just leave the CPU mask bit set to zero for the thread 43097d5cf05SGreg Clayton puts("REMOVE THIS: ProcessKDP::DoResume () -- thread suspended"); 4317925fbbaSGreg Clayton break; 4327925fbbaSGreg Clayton 4337925fbbaSGreg Clayton case eStateStepping: 43497d5cf05SGreg Clayton puts("REMOVE THIS: ProcessKDP::DoResume () -- thread stepping"); 43597d5cf05SGreg Clayton kernel_thread_sp->GetRegisterContext()->HardwareSingleStep (true); 43697d5cf05SGreg Clayton resume = true; 4377925fbbaSGreg Clayton break; 4387925fbbaSGreg Clayton 43997d5cf05SGreg Clayton case eStateRunning: 44097d5cf05SGreg Clayton puts("REMOVE THIS: ProcessKDP::DoResume () -- thread running"); 44197d5cf05SGreg Clayton kernel_thread_sp->GetRegisterContext()->HardwareSingleStep (false); 44297d5cf05SGreg Clayton resume = true; 4437925fbbaSGreg Clayton break; 4447925fbbaSGreg Clayton 4457925fbbaSGreg Clayton default: 44697d5cf05SGreg Clayton // The only valid thread resume states are listed above 4477925fbbaSGreg Clayton assert (!"invalid thread resume state"); 4487925fbbaSGreg Clayton break; 4494b1b8b3eSGreg Clayton } 4504b1b8b3eSGreg Clayton } 4517925fbbaSGreg Clayton 45297d5cf05SGreg Clayton if (resume) 45397d5cf05SGreg Clayton { 45497d5cf05SGreg Clayton if (log) 45597d5cf05SGreg Clayton log->Printf ("ProcessKDP::DoResume () sending resume"); 45697d5cf05SGreg Clayton 45797d5cf05SGreg Clayton if (m_comm.SendRequestResume ()) 4587925fbbaSGreg Clayton { 4597925fbbaSGreg Clayton m_async_broadcaster.BroadcastEvent (eBroadcastBitAsyncContinue); 4607925fbbaSGreg Clayton SetPrivateState(eStateRunning); 4617925fbbaSGreg Clayton } 4624b1b8b3eSGreg Clayton else 46307e66e3eSGreg Clayton error.SetErrorString ("KDP resume failed"); 4647925fbbaSGreg Clayton } 4657925fbbaSGreg Clayton else 4667925fbbaSGreg Clayton { 46797d5cf05SGreg Clayton error.SetErrorString ("kernel thread is suspended"); 4687925fbbaSGreg Clayton } 4697925fbbaSGreg Clayton 470f9765acdSGreg Clayton return error; 471f9765acdSGreg Clayton } 472f9765acdSGreg Clayton 47397d5cf05SGreg Clayton lldb::ThreadSP 47497d5cf05SGreg Clayton ProcessKDP::GetKernelThread(ThreadList &old_thread_list, ThreadList &new_thread_list) 47597d5cf05SGreg Clayton { 47697d5cf05SGreg Clayton // KDP only tells us about one thread/core. Any other threads will usually 47797d5cf05SGreg Clayton // be the ones that are read from memory by the OS plug-ins. 47897d5cf05SGreg Clayton const lldb::tid_t kernel_tid = 1; 47997d5cf05SGreg Clayton ThreadSP thread_sp (old_thread_list.FindThreadByID (kernel_tid, false)); 48097d5cf05SGreg Clayton if (!thread_sp) 48197d5cf05SGreg Clayton { 48297d5cf05SGreg Clayton thread_sp.reset(new ThreadKDP (shared_from_this(), kernel_tid)); 48397d5cf05SGreg Clayton new_thread_list.AddThread(thread_sp); 48497d5cf05SGreg Clayton } 48597d5cf05SGreg Clayton return thread_sp; 48697d5cf05SGreg Clayton } 48797d5cf05SGreg Clayton 48897d5cf05SGreg Clayton 48997d5cf05SGreg Clayton 49097d5cf05SGreg Clayton 4919fc13556SGreg Clayton bool 49256d9a1b3SGreg Clayton ProcessKDP::UpdateThreadList (ThreadList &old_thread_list, ThreadList &new_thread_list) 493f9765acdSGreg Clayton { 494f9765acdSGreg Clayton // locker will keep a mutex locked until it goes out of scope 495f9765acdSGreg Clayton LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_THREAD)); 496f9765acdSGreg Clayton if (log && log->GetMask().Test(KDP_LOG_VERBOSE)) 49781c22f61SGreg Clayton log->Printf ("ProcessKDP::%s (pid = %llu)", __FUNCTION__, GetID()); 498f9765acdSGreg Clayton 49997d5cf05SGreg Clayton // Even though there is a CPU mask, it doesn't mean to can see each CPU 50097d5cf05SGreg Clayton // indivudually, there is really only one. Lets call this thread 1. 50197d5cf05SGreg Clayton GetKernelThread (old_thread_list, new_thread_list); 50297d5cf05SGreg Clayton 5039fc13556SGreg Clayton return new_thread_list.GetSize(false) > 0; 504f9765acdSGreg Clayton } 505f9765acdSGreg Clayton 506f9765acdSGreg Clayton void 507f9765acdSGreg Clayton ProcessKDP::RefreshStateAfterStop () 508f9765acdSGreg Clayton { 509f9765acdSGreg Clayton // Let all threads recover from stopping and do any clean up based 510f9765acdSGreg Clayton // on the previous thread state (if any). 511f9765acdSGreg Clayton m_thread_list.RefreshStateAfterStop(); 512f9765acdSGreg Clayton } 513f9765acdSGreg Clayton 514f9765acdSGreg Clayton Error 515f9765acdSGreg Clayton ProcessKDP::DoHalt (bool &caused_stop) 516f9765acdSGreg Clayton { 517f9765acdSGreg Clayton Error error; 518f9765acdSGreg Clayton 51997d5cf05SGreg Clayton if (m_comm.IsRunning()) 520f9765acdSGreg Clayton { 52197d5cf05SGreg Clayton if (m_destroy_in_process) 52297d5cf05SGreg Clayton { 52397d5cf05SGreg Clayton // If we are attemping to destroy, we need to not return an error to 52497d5cf05SGreg Clayton // Halt or DoDestroy won't get called. 52597d5cf05SGreg Clayton // We are also currently running, so send a process stopped event 52697d5cf05SGreg Clayton SetPrivateState (eStateStopped); 527f9765acdSGreg Clayton } 528f9765acdSGreg Clayton else 529f9765acdSGreg Clayton { 53097d5cf05SGreg Clayton error.SetErrorString ("KDP cannot interrupt a running kernel"); 531f9765acdSGreg Clayton } 532f9765acdSGreg Clayton } 533f9765acdSGreg Clayton return error; 534f9765acdSGreg Clayton } 535f9765acdSGreg Clayton 536f9765acdSGreg Clayton Error 537f9765acdSGreg Clayton ProcessKDP::DoDetach() 538f9765acdSGreg Clayton { 539f9765acdSGreg Clayton Error error; 540f9765acdSGreg Clayton LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS)); 541f9765acdSGreg Clayton if (log) 542f9765acdSGreg Clayton log->Printf ("ProcessKDP::DoDetach()"); 543f9765acdSGreg Clayton 54497d5cf05SGreg Clayton if (m_comm.IsRunning()) 54597d5cf05SGreg Clayton { 54697d5cf05SGreg Clayton // We are running and we can't interrupt a running kernel, so we need 54797d5cf05SGreg Clayton // to just close the connection to the kernel and hope for the best 54897d5cf05SGreg Clayton } 54997d5cf05SGreg Clayton else 55097d5cf05SGreg Clayton { 551f9765acdSGreg Clayton DisableAllBreakpointSites (); 552f9765acdSGreg Clayton 553f9765acdSGreg Clayton m_thread_list.DiscardThreadPlans(); 554f9765acdSGreg Clayton 5553a29bdbeSGreg Clayton if (m_comm.IsConnected()) 5563a29bdbeSGreg Clayton { 5573a29bdbeSGreg Clayton 5583a29bdbeSGreg Clayton m_comm.SendRequestDisconnect(); 5593a29bdbeSGreg Clayton 56057508026SGreg Clayton size_t response_size = m_comm.Disconnect (); 561f9765acdSGreg Clayton if (log) 562f9765acdSGreg Clayton { 563f9765acdSGreg Clayton if (response_size) 564f9765acdSGreg Clayton log->PutCString ("ProcessKDP::DoDetach() detach packet sent successfully"); 565f9765acdSGreg Clayton else 566f9765acdSGreg Clayton log->PutCString ("ProcessKDP::DoDetach() detach packet send failed"); 567f9765acdSGreg Clayton } 5683a29bdbeSGreg Clayton } 56997d5cf05SGreg Clayton } 570f9765acdSGreg Clayton StopAsyncThread (); 57174d4193eSGreg Clayton m_comm.Clear(); 572f9765acdSGreg Clayton 573f9765acdSGreg Clayton SetPrivateState (eStateDetached); 574f9765acdSGreg Clayton ResumePrivateStateThread(); 575f9765acdSGreg Clayton 576f9765acdSGreg Clayton //KillDebugserverProcess (); 577f9765acdSGreg Clayton return error; 578f9765acdSGreg Clayton } 579f9765acdSGreg Clayton 580f9765acdSGreg Clayton Error 58197d5cf05SGreg Clayton ProcessKDP::WillDestroy () 58297d5cf05SGreg Clayton { 58397d5cf05SGreg Clayton Error error; 58497d5cf05SGreg Clayton m_destroy_in_process = true; 58597d5cf05SGreg Clayton return error; 58697d5cf05SGreg Clayton } 58797d5cf05SGreg Clayton 58897d5cf05SGreg Clayton Error 589f9765acdSGreg Clayton ProcessKDP::DoDestroy () 590f9765acdSGreg Clayton { 5917925fbbaSGreg Clayton // For KDP there really is no difference between destroy and detach 5927925fbbaSGreg Clayton return DoDetach(); 593f9765acdSGreg Clayton } 594f9765acdSGreg Clayton 595f9765acdSGreg Clayton //------------------------------------------------------------------ 596f9765acdSGreg Clayton // Process Queries 597f9765acdSGreg Clayton //------------------------------------------------------------------ 598f9765acdSGreg Clayton 599f9765acdSGreg Clayton bool 600f9765acdSGreg Clayton ProcessKDP::IsAlive () 601f9765acdSGreg Clayton { 602f9765acdSGreg Clayton return m_comm.IsConnected() && m_private_state.GetValue() != eStateExited; 603f9765acdSGreg Clayton } 604f9765acdSGreg Clayton 605f9765acdSGreg Clayton //------------------------------------------------------------------ 606f9765acdSGreg Clayton // Process Memory 607f9765acdSGreg Clayton //------------------------------------------------------------------ 608f9765acdSGreg Clayton size_t 609f9765acdSGreg Clayton ProcessKDP::DoReadMemory (addr_t addr, void *buf, size_t size, Error &error) 610f9765acdSGreg Clayton { 611a63d08c9SGreg Clayton if (m_comm.IsConnected()) 612a63d08c9SGreg Clayton return m_comm.SendRequestReadMemory (addr, buf, size, error); 613a63d08c9SGreg Clayton error.SetErrorString ("not connected"); 614f9765acdSGreg Clayton return 0; 615f9765acdSGreg Clayton } 616f9765acdSGreg Clayton 617f9765acdSGreg Clayton size_t 618f9765acdSGreg Clayton ProcessKDP::DoWriteMemory (addr_t addr, const void *buf, size_t size, Error &error) 619f9765acdSGreg Clayton { 6207925fbbaSGreg Clayton if (m_comm.IsConnected()) 6217925fbbaSGreg Clayton return m_comm.SendRequestWriteMemory (addr, buf, size, error); 6227925fbbaSGreg Clayton error.SetErrorString ("not connected"); 623f9765acdSGreg Clayton return 0; 624f9765acdSGreg Clayton } 625f9765acdSGreg Clayton 626f9765acdSGreg Clayton lldb::addr_t 627f9765acdSGreg Clayton ProcessKDP::DoAllocateMemory (size_t size, uint32_t permissions, Error &error) 628f9765acdSGreg Clayton { 629f9765acdSGreg Clayton error.SetErrorString ("memory allocation not suppported in kdp remote debugging"); 630f9765acdSGreg Clayton return LLDB_INVALID_ADDRESS; 631f9765acdSGreg Clayton } 632f9765acdSGreg Clayton 633f9765acdSGreg Clayton Error 634f9765acdSGreg Clayton ProcessKDP::DoDeallocateMemory (lldb::addr_t addr) 635f9765acdSGreg Clayton { 636f9765acdSGreg Clayton Error error; 637f9765acdSGreg Clayton error.SetErrorString ("memory deallocation not suppported in kdp remote debugging"); 638f9765acdSGreg Clayton return error; 639f9765acdSGreg Clayton } 640f9765acdSGreg Clayton 641f9765acdSGreg Clayton Error 642f9765acdSGreg Clayton ProcessKDP::EnableBreakpoint (BreakpointSite *bp_site) 643f9765acdSGreg Clayton { 64407e66e3eSGreg Clayton if (m_comm.LocalBreakpointsAreSupported ()) 64507e66e3eSGreg Clayton { 64607e66e3eSGreg Clayton Error error; 6475b88216dSGreg Clayton if (!bp_site->IsEnabled()) 6485b88216dSGreg Clayton { 6495b88216dSGreg Clayton if (m_comm.SendRequestBreakpoint(true, bp_site->GetLoadAddress())) 6505b88216dSGreg Clayton { 6515b88216dSGreg Clayton bp_site->SetEnabled(true); 6525b88216dSGreg Clayton bp_site->SetType (BreakpointSite::eExternal); 6535b88216dSGreg Clayton } 6545b88216dSGreg Clayton else 6555b88216dSGreg Clayton { 65607e66e3eSGreg Clayton error.SetErrorString ("KDP set breakpoint failed"); 6575b88216dSGreg Clayton } 6585b88216dSGreg Clayton } 65907e66e3eSGreg Clayton return error; 66007e66e3eSGreg Clayton } 661f9765acdSGreg Clayton return EnableSoftwareBreakpoint (bp_site); 662f9765acdSGreg Clayton } 663f9765acdSGreg Clayton 664f9765acdSGreg Clayton Error 665f9765acdSGreg Clayton ProcessKDP::DisableBreakpoint (BreakpointSite *bp_site) 666f9765acdSGreg Clayton { 66707e66e3eSGreg Clayton if (m_comm.LocalBreakpointsAreSupported ()) 66807e66e3eSGreg Clayton { 66907e66e3eSGreg Clayton Error error; 6705b88216dSGreg Clayton if (bp_site->IsEnabled()) 6715b88216dSGreg Clayton { 6725b88216dSGreg Clayton BreakpointSite::Type bp_type = bp_site->GetType(); 6735b88216dSGreg Clayton if (bp_type == BreakpointSite::eExternal) 6745b88216dSGreg Clayton { 67597d5cf05SGreg Clayton if (m_destroy_in_process && m_comm.IsRunning()) 67697d5cf05SGreg Clayton { 67797d5cf05SGreg Clayton // We are trying to destroy our connection and we are running 67897d5cf05SGreg Clayton bp_site->SetEnabled(false); 67997d5cf05SGreg Clayton } 68097d5cf05SGreg Clayton else 68197d5cf05SGreg Clayton { 6825b88216dSGreg Clayton if (m_comm.SendRequestBreakpoint(false, bp_site->GetLoadAddress())) 6835b88216dSGreg Clayton bp_site->SetEnabled(false); 6845b88216dSGreg Clayton else 68507e66e3eSGreg Clayton error.SetErrorString ("KDP remove breakpoint failed"); 6865b88216dSGreg Clayton } 68797d5cf05SGreg Clayton } 6885b88216dSGreg Clayton else 6895b88216dSGreg Clayton { 6905b88216dSGreg Clayton error = DisableSoftwareBreakpoint (bp_site); 6915b88216dSGreg Clayton } 6925b88216dSGreg Clayton } 69307e66e3eSGreg Clayton return error; 69407e66e3eSGreg Clayton } 695f9765acdSGreg Clayton return DisableSoftwareBreakpoint (bp_site); 696f9765acdSGreg Clayton } 697f9765acdSGreg Clayton 698f9765acdSGreg Clayton Error 69901a67860SJohnny Chen ProcessKDP::EnableWatchpoint (Watchpoint *wp) 700f9765acdSGreg Clayton { 701f9765acdSGreg Clayton Error error; 702f9765acdSGreg Clayton error.SetErrorString ("watchpoints are not suppported in kdp remote debugging"); 703f9765acdSGreg Clayton return error; 704f9765acdSGreg Clayton } 705f9765acdSGreg Clayton 706f9765acdSGreg Clayton Error 70701a67860SJohnny Chen ProcessKDP::DisableWatchpoint (Watchpoint *wp) 708f9765acdSGreg Clayton { 709f9765acdSGreg Clayton Error error; 710f9765acdSGreg Clayton error.SetErrorString ("watchpoints are not suppported in kdp remote debugging"); 711f9765acdSGreg Clayton return error; 712f9765acdSGreg Clayton } 713f9765acdSGreg Clayton 714f9765acdSGreg Clayton void 715f9765acdSGreg Clayton ProcessKDP::Clear() 716f9765acdSGreg Clayton { 717f9765acdSGreg Clayton m_thread_list.Clear(); 718f9765acdSGreg Clayton } 719f9765acdSGreg Clayton 720f9765acdSGreg Clayton Error 721f9765acdSGreg Clayton ProcessKDP::DoSignal (int signo) 722f9765acdSGreg Clayton { 723f9765acdSGreg Clayton Error error; 724f9765acdSGreg Clayton error.SetErrorString ("sending signals is not suppported in kdp remote debugging"); 725f9765acdSGreg Clayton return error; 726f9765acdSGreg Clayton } 727f9765acdSGreg Clayton 728f9765acdSGreg Clayton void 729f9765acdSGreg Clayton ProcessKDP::Initialize() 730f9765acdSGreg Clayton { 731f9765acdSGreg Clayton static bool g_initialized = false; 732f9765acdSGreg Clayton 733f9765acdSGreg Clayton if (g_initialized == false) 734f9765acdSGreg Clayton { 735f9765acdSGreg Clayton g_initialized = true; 736f9765acdSGreg Clayton PluginManager::RegisterPlugin (GetPluginNameStatic(), 737f9765acdSGreg Clayton GetPluginDescriptionStatic(), 738f9765acdSGreg Clayton CreateInstance); 739f9765acdSGreg Clayton 740f9765acdSGreg Clayton Log::Callbacks log_callbacks = { 741f9765acdSGreg Clayton ProcessKDPLog::DisableLog, 742f9765acdSGreg Clayton ProcessKDPLog::EnableLog, 743f9765acdSGreg Clayton ProcessKDPLog::ListLogCategories 744f9765acdSGreg Clayton }; 745f9765acdSGreg Clayton 746f9765acdSGreg Clayton Log::RegisterLogChannel (ProcessKDP::GetPluginNameStatic(), log_callbacks); 747f9765acdSGreg Clayton } 748f9765acdSGreg Clayton } 749f9765acdSGreg Clayton 750f9765acdSGreg Clayton bool 751f9765acdSGreg Clayton ProcessKDP::StartAsyncThread () 752f9765acdSGreg Clayton { 753f9765acdSGreg Clayton LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS)); 754f9765acdSGreg Clayton 755f9765acdSGreg Clayton if (log) 7567925fbbaSGreg Clayton log->Printf ("ProcessKDP::StartAsyncThread ()"); 757f9765acdSGreg Clayton 7587925fbbaSGreg Clayton if (IS_VALID_LLDB_HOST_THREAD(m_async_thread)) 7597925fbbaSGreg Clayton return true; 7607925fbbaSGreg Clayton 761f9765acdSGreg Clayton m_async_thread = Host::ThreadCreate ("<lldb.process.kdp-remote.async>", ProcessKDP::AsyncThread, this, NULL); 762f9765acdSGreg Clayton return IS_VALID_LLDB_HOST_THREAD(m_async_thread); 763f9765acdSGreg Clayton } 764f9765acdSGreg Clayton 765f9765acdSGreg Clayton void 766f9765acdSGreg Clayton ProcessKDP::StopAsyncThread () 767f9765acdSGreg Clayton { 768f9765acdSGreg Clayton LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS)); 769f9765acdSGreg Clayton 770f9765acdSGreg Clayton if (log) 7717925fbbaSGreg Clayton log->Printf ("ProcessKDP::StopAsyncThread ()"); 772f9765acdSGreg Clayton 773f9765acdSGreg Clayton m_async_broadcaster.BroadcastEvent (eBroadcastBitAsyncThreadShouldExit); 774f9765acdSGreg Clayton 775f9765acdSGreg Clayton // Stop the stdio thread 776f9765acdSGreg Clayton if (IS_VALID_LLDB_HOST_THREAD(m_async_thread)) 777f9765acdSGreg Clayton { 778f9765acdSGreg Clayton Host::ThreadJoin (m_async_thread, NULL, NULL); 7797925fbbaSGreg Clayton m_async_thread = LLDB_INVALID_HOST_THREAD; 780f9765acdSGreg Clayton } 781f9765acdSGreg Clayton } 782f9765acdSGreg Clayton 783f9765acdSGreg Clayton 784f9765acdSGreg Clayton void * 785f9765acdSGreg Clayton ProcessKDP::AsyncThread (void *arg) 786f9765acdSGreg Clayton { 787f9765acdSGreg Clayton ProcessKDP *process = (ProcessKDP*) arg; 788f9765acdSGreg Clayton 7897925fbbaSGreg Clayton const lldb::pid_t pid = process->GetID(); 7907925fbbaSGreg Clayton 791f9765acdSGreg Clayton LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_PROCESS)); 792f9765acdSGreg Clayton if (log) 7937925fbbaSGreg Clayton log->Printf ("ProcessKDP::AsyncThread (arg = %p, pid = %llu) thread starting...", arg, pid); 794f9765acdSGreg Clayton 795f9765acdSGreg Clayton Listener listener ("ProcessKDP::AsyncThread"); 796f9765acdSGreg Clayton EventSP event_sp; 797f9765acdSGreg Clayton const uint32_t desired_event_mask = eBroadcastBitAsyncContinue | 798f9765acdSGreg Clayton eBroadcastBitAsyncThreadShouldExit; 799f9765acdSGreg Clayton 8007925fbbaSGreg Clayton 801f9765acdSGreg Clayton if (listener.StartListeningForEvents (&process->m_async_broadcaster, desired_event_mask) == desired_event_mask) 802f9765acdSGreg Clayton { 803f9765acdSGreg Clayton bool done = false; 804f9765acdSGreg Clayton while (!done) 805f9765acdSGreg Clayton { 806f9765acdSGreg Clayton if (log) 8077925fbbaSGreg Clayton log->Printf ("ProcessKDP::AsyncThread (pid = %llu) listener.WaitForEvent (NULL, event_sp)...", 8087925fbbaSGreg Clayton pid); 809f9765acdSGreg Clayton if (listener.WaitForEvent (NULL, event_sp)) 810f9765acdSGreg Clayton { 8117925fbbaSGreg Clayton uint32_t event_type = event_sp->GetType(); 812f9765acdSGreg Clayton if (log) 8137925fbbaSGreg Clayton log->Printf ("ProcessKDP::AsyncThread (pid = %llu) Got an event of type: %d...", 8147925fbbaSGreg Clayton pid, 8157925fbbaSGreg Clayton event_type); 816f9765acdSGreg Clayton 8177925fbbaSGreg Clayton // When we are running, poll for 1 second to try and get an exception 8187925fbbaSGreg Clayton // to indicate the process has stopped. If we don't get one, check to 8197925fbbaSGreg Clayton // make sure no one asked us to exit 8207925fbbaSGreg Clayton bool is_running = false; 8217925fbbaSGreg Clayton DataExtractor exc_reply_packet; 8227925fbbaSGreg Clayton do 8237925fbbaSGreg Clayton { 824f9765acdSGreg Clayton switch (event_type) 825f9765acdSGreg Clayton { 826f9765acdSGreg Clayton case eBroadcastBitAsyncContinue: 827f9765acdSGreg Clayton { 8287925fbbaSGreg Clayton is_running = true; 8297925fbbaSGreg Clayton if (process->m_comm.WaitForPacketWithTimeoutMicroSeconds (exc_reply_packet, 1 * USEC_PER_SEC)) 830f9765acdSGreg Clayton { 83197d5cf05SGreg Clayton ThreadSP thread_sp (process->GetKernelThread(process->GetThreadList(), process->GetThreadList())); 83297d5cf05SGreg Clayton thread_sp->GetRegisterContext()->InvalidateAllRegisters(); 83397d5cf05SGreg Clayton static_cast<ThreadKDP *>(thread_sp.get())->SetStopInfoFrom_KDP_EXCEPTION (exc_reply_packet); 83497d5cf05SGreg Clayton 8357925fbbaSGreg Clayton // TODO: parse the stop reply packet 8367925fbbaSGreg Clayton is_running = false; 8377925fbbaSGreg Clayton process->SetPrivateState(eStateStopped); 8387925fbbaSGreg Clayton } 8397925fbbaSGreg Clayton else 8407925fbbaSGreg Clayton { 8417925fbbaSGreg Clayton // Check to see if we are supposed to exit. There is no way to 8427925fbbaSGreg Clayton // interrupt a running kernel, so all we can do is wait for an 8437925fbbaSGreg Clayton // exception or detach... 8447925fbbaSGreg Clayton if (listener.GetNextEvent(event_sp)) 8457925fbbaSGreg Clayton { 8467925fbbaSGreg Clayton // We got an event, go through the loop again 8477925fbbaSGreg Clayton event_type = event_sp->GetType(); 8487925fbbaSGreg Clayton } 849f9765acdSGreg Clayton } 850f9765acdSGreg Clayton } 851f9765acdSGreg Clayton break; 852f9765acdSGreg Clayton 853f9765acdSGreg Clayton case eBroadcastBitAsyncThreadShouldExit: 854f9765acdSGreg Clayton if (log) 8557925fbbaSGreg Clayton log->Printf ("ProcessKDP::AsyncThread (pid = %llu) got eBroadcastBitAsyncThreadShouldExit...", 8567925fbbaSGreg Clayton pid); 857f9765acdSGreg Clayton done = true; 8587925fbbaSGreg Clayton is_running = false; 859f9765acdSGreg Clayton break; 860f9765acdSGreg Clayton 861f9765acdSGreg Clayton default: 862f9765acdSGreg Clayton if (log) 8637925fbbaSGreg Clayton log->Printf ("ProcessKDP::AsyncThread (pid = %llu) got unknown event 0x%8.8x", 8647925fbbaSGreg Clayton pid, 8657925fbbaSGreg Clayton event_type); 866f9765acdSGreg Clayton done = true; 8677925fbbaSGreg Clayton is_running = false; 868f9765acdSGreg Clayton break; 869f9765acdSGreg Clayton } 8707925fbbaSGreg Clayton } while (is_running); 871f9765acdSGreg Clayton } 872f9765acdSGreg Clayton else 873f9765acdSGreg Clayton { 874f9765acdSGreg Clayton if (log) 8757925fbbaSGreg Clayton log->Printf ("ProcessKDP::AsyncThread (pid = %llu) listener.WaitForEvent (NULL, event_sp) => false", 8767925fbbaSGreg Clayton pid); 877f9765acdSGreg Clayton done = true; 878f9765acdSGreg Clayton } 879f9765acdSGreg Clayton } 880f9765acdSGreg Clayton } 881f9765acdSGreg Clayton 882f9765acdSGreg Clayton if (log) 8837925fbbaSGreg Clayton log->Printf ("ProcessKDP::AsyncThread (arg = %p, pid = %llu) thread exiting...", 8847925fbbaSGreg Clayton arg, 8857925fbbaSGreg Clayton pid); 886f9765acdSGreg Clayton 887f9765acdSGreg Clayton process->m_async_thread = LLDB_INVALID_HOST_THREAD; 888f9765acdSGreg Clayton return NULL; 889f9765acdSGreg Clayton } 890f9765acdSGreg Clayton 891f9765acdSGreg Clayton 892