1 //===-- ProcessKDP.cpp ----------------------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
15 #include "lldb/Core/Debugger.h"
16 #include "lldb/Core/Module.h"
17 #include "lldb/Core/ModuleSpec.h"
18 #include "lldb/Core/PluginManager.h"
19 #include "lldb/Host/ConnectionFileDescriptor.h"
20 #include "lldb/Host/Host.h"
21 #include "lldb/Host/ThreadLauncher.h"
22 #include "lldb/Host/common/TCPSocket.h"
23 #include "lldb/Interpreter/CommandInterpreter.h"
24 #include "lldb/Interpreter/CommandObject.h"
25 #include "lldb/Interpreter/CommandObjectMultiword.h"
26 #include "lldb/Interpreter/CommandReturnObject.h"
27 #include "lldb/Interpreter/OptionGroupString.h"
28 #include "lldb/Interpreter/OptionGroupUInt64.h"
29 #include "lldb/Interpreter/OptionValueProperties.h"
30 #include "lldb/Symbol/LocateSymbolFile.h"
31 #include "lldb/Symbol/ObjectFile.h"
32 #include "lldb/Target/RegisterContext.h"
33 #include "lldb/Target/Target.h"
34 #include "lldb/Target/Thread.h"
35 #include "lldb/Utility/LLDBLog.h"
36 #include "lldb/Utility/Log.h"
37 #include "lldb/Utility/State.h"
38 #include "lldb/Utility/StringExtractor.h"
39 #include "lldb/Utility/UUID.h"
41 #include "llvm/Support/Threading.h"
43 #define USEC_PER_SEC 1000000
45 #include "Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h"
46 #include "Plugins/DynamicLoader/Static/DynamicLoaderStatic.h"
47 #include "ProcessKDP.h"
48 #include "ProcessKDPLog.h"
49 #include "ThreadKDP.h"
52 using namespace lldb_private
;
54 LLDB_PLUGIN_DEFINE_ADV(ProcessKDP
, ProcessMacOSXKernel
)
58 #define LLDB_PROPERTIES_processkdp
59 #include "ProcessKDPProperties.inc"
62 #define LLDB_PROPERTIES_processkdp
63 #include "ProcessKDPPropertiesEnum.inc"
66 class PluginProperties
: public Properties
{
68 static llvm::StringRef
GetSettingName() {
69 return ProcessKDP::GetPluginNameStatic();
72 PluginProperties() : Properties() {
73 m_collection_sp
= std::make_shared
<OptionValueProperties
>(GetSettingName());
74 m_collection_sp
->Initialize(g_processkdp_properties
);
77 ~PluginProperties() override
= default;
79 uint64_t GetPacketTimeout() {
80 const uint32_t idx
= ePropertyKDPPacketTimeout
;
81 return GetPropertyAtIndexAs
<uint64_t>(
82 idx
, g_processkdp_properties
[idx
].default_uint_value
);
88 static PluginProperties
&GetGlobalPluginProperties() {
89 static PluginProperties g_settings
;
93 static const lldb::tid_t g_kernel_tid
= 1;
95 llvm::StringRef
ProcessKDP::GetPluginDescriptionStatic() {
96 return "KDP Remote protocol based debugging plug-in for darwin kernel "
100 void ProcessKDP::Terminate() {
101 PluginManager::UnregisterPlugin(ProcessKDP::CreateInstance
);
104 lldb::ProcessSP
ProcessKDP::CreateInstance(TargetSP target_sp
,
105 ListenerSP listener_sp
,
106 const FileSpec
*crash_file_path
,
108 lldb::ProcessSP process_sp
;
109 if (crash_file_path
== NULL
)
110 process_sp
= std::make_shared
<ProcessKDP
>(target_sp
, listener_sp
);
114 bool ProcessKDP::CanDebug(TargetSP target_sp
, bool plugin_specified_by_name
) {
115 if (plugin_specified_by_name
)
118 // For now we are just making sure the file exists for a given module
119 Module
*exe_module
= target_sp
->GetExecutableModulePointer();
121 const llvm::Triple
&triple_ref
= target_sp
->GetArchitecture().GetTriple();
122 switch (triple_ref
.getOS()) {
123 case llvm::Triple::Darwin
: // Should use "macosx" for desktop and "ios" for
124 // iOS, but accept darwin just in case
125 case llvm::Triple::MacOSX
: // For desktop targets
126 case llvm::Triple::IOS
: // For arm targets
127 case llvm::Triple::TvOS
:
128 case llvm::Triple::WatchOS
:
129 if (triple_ref
.getVendor() == llvm::Triple::Apple
) {
130 ObjectFile
*exe_objfile
= exe_module
->GetObjectFile();
131 if (exe_objfile
->GetType() == ObjectFile::eTypeExecutable
&&
132 exe_objfile
->GetStrata() == ObjectFile::eStrataKernel
)
144 // ProcessKDP constructor
145 ProcessKDP::ProcessKDP(TargetSP target_sp
, ListenerSP listener_sp
)
146 : Process(target_sp
, listener_sp
),
147 m_comm("lldb.process.kdp-remote.communication"),
148 m_async_broadcaster(NULL
, "lldb.process.kdp-remote.async-broadcaster"),
149 m_kernel_load_addr(LLDB_INVALID_ADDRESS
), m_command_sp(),
150 m_kernel_thread_wp() {
151 m_async_broadcaster
.SetEventName(eBroadcastBitAsyncThreadShouldExit
,
152 "async thread should exit");
153 m_async_broadcaster
.SetEventName(eBroadcastBitAsyncContinue
,
154 "async thread continue");
155 const uint64_t timeout_seconds
=
156 GetGlobalPluginProperties().GetPacketTimeout();
157 if (timeout_seconds
> 0)
158 m_comm
.SetPacketTimeout(std::chrono::seconds(timeout_seconds
));
162 ProcessKDP::~ProcessKDP() {
164 // We need to call finalize on the process before destroying ourselves to
165 // make sure all of the broadcaster cleanup goes as planned. If we destruct
166 // this class, then Process::~Process() might have problems trying to fully
167 // destroy the broadcaster.
171 Status
ProcessKDP::DoWillLaunch(Module
*module
) {
173 error
.SetErrorString("launching not supported in kdp-remote plug-in");
177 Status
ProcessKDP::DoWillAttachToProcessWithID(lldb::pid_t pid
) {
179 error
.SetErrorString(
180 "attaching to a by process ID not supported in kdp-remote plug-in");
184 Status
ProcessKDP::DoWillAttachToProcessWithName(const char *process_name
,
185 bool wait_for_launch
) {
187 error
.SetErrorString(
188 "attaching to a by process name not supported in kdp-remote plug-in");
192 bool ProcessKDP::GetHostArchitecture(ArchSpec
&arch
) {
193 uint32_t cpu
= m_comm
.GetCPUType();
195 uint32_t sub
= m_comm
.GetCPUSubtype();
196 arch
.SetArchitecture(eArchTypeMachO
, cpu
, sub
);
197 // Leave architecture vendor as unspecified unknown
198 arch
.GetTriple().setVendor(llvm::Triple::UnknownVendor
);
199 arch
.GetTriple().setVendorName(llvm::StringRef());
206 Status
ProcessKDP::DoConnectRemote(llvm::StringRef remote_url
) {
209 // Don't let any JIT happen when doing KDP as we can't allocate memory and we
210 // don't want to be mucking with threads that might already be handling
214 if (remote_url
.empty()) {
215 error
.SetErrorStringWithFormat("empty connection URL");
219 std::unique_ptr
<ConnectionFileDescriptor
> conn_up(
220 new ConnectionFileDescriptor());
222 // Only try once for now.
223 // TODO: check if we should be retrying?
224 const uint32_t max_retry_count
= 1;
225 for (uint32_t retry_count
= 0; retry_count
< max_retry_count
;
227 if (conn_up
->Connect(remote_url
, &error
) == eConnectionStatusSuccess
)
233 if (conn_up
->IsConnected()) {
234 const TCPSocket
&socket
=
235 static_cast<const TCPSocket
&>(*conn_up
->GetReadObject());
236 const uint16_t reply_port
= socket
.GetLocalPortNumber();
238 if (reply_port
!= 0) {
239 m_comm
.SetConnection(std::move(conn_up
));
241 if (m_comm
.SendRequestReattach(reply_port
)) {
242 if (m_comm
.SendRequestConnect(reply_port
, reply_port
,
243 "Greetings from LLDB...")) {
246 Target
&target
= GetTarget();
247 ArchSpec kernel_arch
;
248 // The host architecture
249 GetHostArchitecture(kernel_arch
);
250 ArchSpec target_arch
= target
.GetArchitecture();
251 // Merge in any unspecified stuff into the target architecture in
252 // case the target arch isn't set at all or incompletely.
253 target_arch
.MergeFrom(kernel_arch
);
254 target
.SetArchitecture(target_arch
);
256 /* Get the kernel's UUID and load address via KDP_KERNELVERSION
258 /* An EFI kdp session has neither UUID nor load address. */
260 UUID kernel_uuid
= m_comm
.GetUUID();
261 addr_t kernel_load_addr
= m_comm
.GetLoadAddress();
263 if (m_comm
.RemoteIsEFI()) {
264 // Select an invalid plugin name for the dynamic loader so one
265 // doesn't get used since EFI does its own manual loading via
267 m_dyld_plugin_name
= "none";
269 if (kernel_uuid
.IsValid()) {
270 // If EFI passed in a UUID= try to lookup UUID The slide will not
271 // be provided. But the UUID lookup will be used to launch EFI
272 // debug scripts from the dSYM, that can load all of the symbols.
273 ModuleSpec module_spec
;
274 module_spec
.GetUUID() = kernel_uuid
;
275 module_spec
.GetArchitecture() = target
.GetArchitecture();
277 // Lookup UUID locally, before attempting dsymForUUID like action
278 FileSpecList search_paths
=
279 Target::GetDefaultDebugFileSearchPaths();
280 module_spec
.GetSymbolFileSpec() =
281 Symbols::LocateExecutableSymbolFile(module_spec
,
283 if (module_spec
.GetSymbolFileSpec()) {
284 ModuleSpec executable_module_spec
=
285 Symbols::LocateExecutableObjectFile(module_spec
);
286 if (FileSystem::Instance().Exists(
287 executable_module_spec
.GetFileSpec())) {
288 module_spec
.GetFileSpec() =
289 executable_module_spec
.GetFileSpec();
292 if (!module_spec
.GetSymbolFileSpec() ||
293 !module_spec
.GetSymbolFileSpec()) {
295 Symbols::DownloadObjectAndSymbolFile(module_spec
, symbl_error
,
299 if (FileSystem::Instance().Exists(module_spec
.GetFileSpec())) {
300 ModuleSP
module_sp(new Module(module_spec
));
301 if (module_sp
.get() && module_sp
->GetObjectFile()) {
302 // Get the current target executable
303 ModuleSP
exe_module_sp(target
.GetExecutableModule());
305 // Make sure you don't already have the right module loaded
306 // and they will be uniqued
307 if (exe_module_sp
.get() != module_sp
.get())
308 target
.SetExecutableModule(module_sp
, eLoadDependentsNo
);
312 } else if (m_comm
.RemoteIsDarwinKernel()) {
314 DynamicLoaderDarwinKernel::GetPluginNameStatic();
315 if (kernel_load_addr
!= LLDB_INVALID_ADDRESS
) {
316 m_kernel_load_addr
= kernel_load_addr
;
321 UpdateThreadListIfNeeded();
324 SetPrivateState(eStateStopped
);
325 StreamSP
async_strm_sp(target
.GetDebugger().GetAsyncOutputStream());
328 if ((cstr
= m_comm
.GetKernelVersion()) != NULL
) {
329 async_strm_sp
->Printf("Version: %s\n", cstr
);
330 async_strm_sp
->Flush();
332 // if ((cstr = m_comm.GetImagePath ()) != NULL)
334 // async_strm_sp->Printf ("Image Path:
336 // async_strm_sp->Flush();
340 error
.SetErrorString("KDP_REATTACH failed");
343 error
.SetErrorString("KDP_REATTACH failed");
346 error
.SetErrorString("invalid reply port from UDP connection");
350 error
.SetErrorStringWithFormat("failed to connect to '%s'",
351 remote_url
.str().c_str());
360 Status
ProcessKDP::DoLaunch(Module
*exe_module
,
361 ProcessLaunchInfo
&launch_info
) {
363 error
.SetErrorString("launching not supported in kdp-remote plug-in");
368 ProcessKDP::DoAttachToProcessWithID(lldb::pid_t attach_pid
,
369 const ProcessAttachInfo
&attach_info
) {
371 error
.SetErrorString(
372 "attach to process by ID is not supported in kdp remote debugging");
377 ProcessKDP::DoAttachToProcessWithName(const char *process_name
,
378 const ProcessAttachInfo
&attach_info
) {
380 error
.SetErrorString(
381 "attach to process by name is not supported in kdp remote debugging");
385 void ProcessKDP::DidAttach(ArchSpec
&process_arch
) {
386 Process::DidAttach(process_arch
);
388 Log
*log
= GetLog(KDPLog::Process
);
389 LLDB_LOGF(log
, "ProcessKDP::DidAttach()");
390 if (GetID() != LLDB_INVALID_PROCESS_ID
) {
391 GetHostArchitecture(process_arch
);
395 addr_t
ProcessKDP::GetImageInfoAddress() { return m_kernel_load_addr
; }
397 lldb_private::DynamicLoader
*ProcessKDP::GetDynamicLoader() {
398 if (m_dyld_up
.get() == NULL
)
399 m_dyld_up
.reset(DynamicLoader::FindPlugin(this, m_dyld_plugin_name
));
400 return m_dyld_up
.get();
403 Status
ProcessKDP::WillResume() { return Status(); }
405 Status
ProcessKDP::DoResume() {
407 Log
*log
= GetLog(KDPLog::Process
);
408 // Only start the async thread if we try to do any process control
409 if (!m_async_thread
.IsJoinable())
414 // With KDP there is only one thread we can tell what to do
415 ThreadSP
kernel_thread_sp(m_thread_list
.FindThreadByProtocolID(g_kernel_tid
));
417 if (kernel_thread_sp
) {
418 const StateType thread_resume_state
=
419 kernel_thread_sp
->GetTemporaryResumeState();
421 LLDB_LOGF(log
, "ProcessKDP::DoResume() thread_resume_state = %s",
422 StateAsCString(thread_resume_state
));
423 switch (thread_resume_state
) {
424 case eStateSuspended
:
425 // Nothing to do here when a thread will stay suspended we just leave the
426 // CPU mask bit set to zero for the thread
427 LLDB_LOGF(log
, "ProcessKDP::DoResume() = suspended???");
430 case eStateStepping
: {
431 lldb::RegisterContextSP
reg_ctx_sp(
432 kernel_thread_sp
->GetRegisterContext());
437 "ProcessKDP::DoResume () reg_ctx_sp->HardwareSingleStep (true);");
438 reg_ctx_sp
->HardwareSingleStep(true);
441 error
.SetErrorStringWithFormat(
442 "KDP thread 0x%llx has no register context",
443 kernel_thread_sp
->GetID());
447 case eStateRunning
: {
448 lldb::RegisterContextSP
reg_ctx_sp(
449 kernel_thread_sp
->GetRegisterContext());
452 LLDB_LOGF(log
, "ProcessKDP::DoResume () reg_ctx_sp->HardwareSingleStep "
454 reg_ctx_sp
->HardwareSingleStep(false);
457 error
.SetErrorStringWithFormat(
458 "KDP thread 0x%llx has no register context",
459 kernel_thread_sp
->GetID());
464 // The only valid thread resume states are listed above
465 llvm_unreachable("invalid thread resume state");
470 LLDB_LOGF(log
, "ProcessKDP::DoResume () sending resume");
472 if (m_comm
.SendRequestResume()) {
473 m_async_broadcaster
.BroadcastEvent(eBroadcastBitAsyncContinue
);
474 SetPrivateState(eStateRunning
);
476 error
.SetErrorString("KDP resume failed");
478 error
.SetErrorString("kernel thread is suspended");
484 lldb::ThreadSP
ProcessKDP::GetKernelThread() {
485 // KDP only tells us about one thread/core. Any other threads will usually
486 // be the ones that are read from memory by the OS plug-ins.
488 ThreadSP
thread_sp(m_kernel_thread_wp
.lock());
490 thread_sp
= std::make_shared
<ThreadKDP
>(*this, g_kernel_tid
);
491 m_kernel_thread_wp
= thread_sp
;
496 bool ProcessKDP::DoUpdateThreadList(ThreadList
&old_thread_list
,
497 ThreadList
&new_thread_list
) {
498 // locker will keep a mutex locked until it goes out of scope
499 Log
*log
= GetLog(KDPLog::Thread
);
500 LLDB_LOGV(log
, "pid = {0}", GetID());
502 // Even though there is a CPU mask, it doesn't mean we can see each CPU
503 // individually, there is really only one. Lets call this thread 1.
505 old_thread_list
.FindThreadByProtocolID(g_kernel_tid
, false));
507 thread_sp
= GetKernelThread();
508 new_thread_list
.AddThread(thread_sp
);
510 return new_thread_list
.GetSize(false) > 0;
513 void ProcessKDP::RefreshStateAfterStop() {
514 // Let all threads recover from stopping and do any clean up based on the
515 // previous thread state (if any).
516 m_thread_list
.RefreshStateAfterStop();
519 Status
ProcessKDP::DoHalt(bool &caused_stop
) {
522 if (m_comm
.IsRunning()) {
523 if (m_destroy_in_process
) {
524 // If we are attempting to destroy, we need to not return an error to Halt
525 // or DoDestroy won't get called. We are also currently running, so send
526 // a process stopped event
527 SetPrivateState(eStateStopped
);
529 error
.SetErrorString("KDP cannot interrupt a running kernel");
535 Status
ProcessKDP::DoDetach(bool keep_stopped
) {
537 Log
*log
= GetLog(KDPLog::Process
);
538 LLDB_LOGF(log
, "ProcessKDP::DoDetach(keep_stopped = %i)", keep_stopped
);
540 if (m_comm
.IsRunning()) {
541 // We are running and we can't interrupt a running kernel, so we need to
542 // just close the connection to the kernel and hope for the best
544 // If we are going to keep the target stopped, then don't send the
545 // disconnect message.
546 if (!keep_stopped
&& m_comm
.IsConnected()) {
547 const bool success
= m_comm
.SendRequestDisconnect();
551 "ProcessKDP::DoDetach() detach packet sent successfully");
554 "ProcessKDP::DoDetach() connection channel shutdown failed");
562 SetPrivateState(eStateDetached
);
563 ResumePrivateStateThread();
565 // KillDebugserverProcess ();
569 Status
ProcessKDP::DoDestroy() {
570 // For KDP there really is no difference between destroy and detach
571 bool keep_stopped
= false;
572 return DoDetach(keep_stopped
);
577 bool ProcessKDP::IsAlive() {
578 return m_comm
.IsConnected() && Process::IsAlive();
582 size_t ProcessKDP::DoReadMemory(addr_t addr
, void *buf
, size_t size
,
584 uint8_t *data_buffer
= (uint8_t *)buf
;
585 if (m_comm
.IsConnected()) {
586 const size_t max_read_size
= 512;
587 size_t total_bytes_read
= 0;
589 // Read the requested amount of memory in 512 byte chunks
590 while (total_bytes_read
< size
) {
591 size_t bytes_to_read_this_request
= size
- total_bytes_read
;
592 if (bytes_to_read_this_request
> max_read_size
) {
593 bytes_to_read_this_request
= max_read_size
;
595 size_t bytes_read
= m_comm
.SendRequestReadMemory(
596 addr
+ total_bytes_read
, data_buffer
+ total_bytes_read
,
597 bytes_to_read_this_request
, error
);
598 total_bytes_read
+= bytes_read
;
599 if (error
.Fail() || bytes_read
== 0) {
600 return total_bytes_read
;
604 return total_bytes_read
;
606 error
.SetErrorString("not connected");
610 size_t ProcessKDP::DoWriteMemory(addr_t addr
, const void *buf
, size_t size
,
612 if (m_comm
.IsConnected())
613 return m_comm
.SendRequestWriteMemory(addr
, buf
, size
, error
);
614 error
.SetErrorString("not connected");
618 lldb::addr_t
ProcessKDP::DoAllocateMemory(size_t size
, uint32_t permissions
,
620 error
.SetErrorString(
621 "memory allocation not supported in kdp remote debugging");
622 return LLDB_INVALID_ADDRESS
;
625 Status
ProcessKDP::DoDeallocateMemory(lldb::addr_t addr
) {
627 error
.SetErrorString(
628 "memory deallocation not supported in kdp remote debugging");
632 Status
ProcessKDP::EnableBreakpointSite(BreakpointSite
*bp_site
) {
633 if (bp_site
->HardwareRequired())
634 return Status("Hardware breakpoints are not supported.");
636 if (m_comm
.LocalBreakpointsAreSupported()) {
638 if (!bp_site
->IsEnabled()) {
639 if (m_comm
.SendRequestBreakpoint(true, bp_site
->GetLoadAddress())) {
640 bp_site
->SetEnabled(true);
641 bp_site
->SetType(BreakpointSite::eExternal
);
643 error
.SetErrorString("KDP set breakpoint failed");
648 return EnableSoftwareBreakpoint(bp_site
);
651 Status
ProcessKDP::DisableBreakpointSite(BreakpointSite
*bp_site
) {
652 if (m_comm
.LocalBreakpointsAreSupported()) {
654 if (bp_site
->IsEnabled()) {
655 BreakpointSite::Type bp_type
= bp_site
->GetType();
656 if (bp_type
== BreakpointSite::eExternal
) {
657 if (m_destroy_in_process
&& m_comm
.IsRunning()) {
658 // We are trying to destroy our connection and we are running
659 bp_site
->SetEnabled(false);
661 if (m_comm
.SendRequestBreakpoint(false, bp_site
->GetLoadAddress()))
662 bp_site
->SetEnabled(false);
664 error
.SetErrorString("KDP remove breakpoint failed");
667 error
= DisableSoftwareBreakpoint(bp_site
);
672 return DisableSoftwareBreakpoint(bp_site
);
675 Status
ProcessKDP::EnableWatchpoint(Watchpoint
*wp
, bool notify
) {
677 error
.SetErrorString(
678 "watchpoints are not supported in kdp remote debugging");
682 Status
ProcessKDP::DisableWatchpoint(Watchpoint
*wp
, bool notify
) {
684 error
.SetErrorString(
685 "watchpoints are not supported in kdp remote debugging");
689 void ProcessKDP::Clear() { m_thread_list
.Clear(); }
691 Status
ProcessKDP::DoSignal(int signo
) {
693 error
.SetErrorString(
694 "sending signals is not supported in kdp remote debugging");
698 void ProcessKDP::Initialize() {
699 static llvm::once_flag g_once_flag
;
701 llvm::call_once(g_once_flag
, []() {
702 PluginManager::RegisterPlugin(GetPluginNameStatic(),
703 GetPluginDescriptionStatic(), CreateInstance
,
706 ProcessKDPLog::Initialize();
710 void ProcessKDP::DebuggerInitialize(lldb_private::Debugger
&debugger
) {
711 if (!PluginManager::GetSettingForProcessPlugin(
712 debugger
, PluginProperties::GetSettingName())) {
713 const bool is_global_setting
= true;
714 PluginManager::CreateSettingForProcessPlugin(
715 debugger
, GetGlobalPluginProperties().GetValueProperties(),
716 "Properties for the kdp-remote process plug-in.", is_global_setting
);
720 bool ProcessKDP::StartAsyncThread() {
721 Log
*log
= GetLog(KDPLog::Process
);
723 LLDB_LOGF(log
, "ProcessKDP::StartAsyncThread ()");
725 if (m_async_thread
.IsJoinable())
728 llvm::Expected
<HostThread
> async_thread
= ThreadLauncher::LaunchThread(
729 "<lldb.process.kdp-remote.async>", [this] { return AsyncThread(); });
731 LLDB_LOG_ERROR(GetLog(LLDBLog::Host
), async_thread
.takeError(),
732 "failed to launch host thread: {0}");
735 m_async_thread
= *async_thread
;
736 return m_async_thread
.IsJoinable();
739 void ProcessKDP::StopAsyncThread() {
740 Log
*log
= GetLog(KDPLog::Process
);
742 LLDB_LOGF(log
, "ProcessKDP::StopAsyncThread ()");
744 m_async_broadcaster
.BroadcastEvent(eBroadcastBitAsyncThreadShouldExit
);
746 // Stop the stdio thread
747 if (m_async_thread
.IsJoinable())
748 m_async_thread
.Join(nullptr);
751 void *ProcessKDP::AsyncThread() {
752 const lldb::pid_t pid
= GetID();
754 Log
*log
= GetLog(KDPLog::Process
);
756 "ProcessKDP::AsyncThread(pid = %" PRIu64
") thread starting...",
759 ListenerSP
listener_sp(Listener::MakeListener("ProcessKDP::AsyncThread"));
761 const uint32_t desired_event_mask
=
762 eBroadcastBitAsyncContinue
| eBroadcastBitAsyncThreadShouldExit
;
764 if (listener_sp
->StartListeningForEvents(
765 &m_async_broadcaster
, desired_event_mask
) == desired_event_mask
) {
769 "ProcessKDP::AsyncThread (pid = %" PRIu64
770 ") listener.WaitForEvent (NULL, event_sp)...",
772 if (listener_sp
->GetEvent(event_sp
, std::nullopt
)) {
773 uint32_t event_type
= event_sp
->GetType();
775 "ProcessKDP::AsyncThread (pid = %" PRIu64
776 ") Got an event of type: %d...",
779 // When we are running, poll for 1 second to try and get an exception
780 // to indicate the process has stopped. If we don't get one, check to
781 // make sure no one asked us to exit
782 bool is_running
= false;
783 DataExtractor exc_reply_packet
;
785 switch (event_type
) {
786 case eBroadcastBitAsyncContinue
: {
788 if (m_comm
.WaitForPacketWithTimeoutMicroSeconds(
789 exc_reply_packet
, 1 * USEC_PER_SEC
)) {
790 ThreadSP
thread_sp(GetKernelThread());
792 lldb::RegisterContextSP
reg_ctx_sp(
793 thread_sp
->GetRegisterContext());
795 reg_ctx_sp
->InvalidateAllRegisters();
796 static_cast<ThreadKDP
*>(thread_sp
.get())
797 ->SetStopInfoFrom_KDP_EXCEPTION(exc_reply_packet
);
800 // TODO: parse the stop reply packet
802 SetPrivateState(eStateStopped
);
804 // Check to see if we are supposed to exit. There is no way to
805 // interrupt a running kernel, so all we can do is wait for an
806 // exception or detach...
807 if (listener_sp
->GetEvent(event_sp
,
808 std::chrono::microseconds(0))) {
809 // We got an event, go through the loop again
810 event_type
= event_sp
->GetType();
815 case eBroadcastBitAsyncThreadShouldExit
:
817 "ProcessKDP::AsyncThread (pid = %" PRIu64
818 ") got eBroadcastBitAsyncThreadShouldExit...",
826 "ProcessKDP::AsyncThread (pid = %" PRIu64
827 ") got unknown event 0x%8.8x",
833 } while (is_running
);
836 "ProcessKDP::AsyncThread (pid = %" PRIu64
837 ") listener.WaitForEvent (NULL, event_sp) => false",
844 LLDB_LOGF(log
, "ProcessKDP::AsyncThread(pid = %" PRIu64
") thread exiting...",
847 m_async_thread
.Reset();
851 class CommandObjectProcessKDPPacketSend
: public CommandObjectParsed
{
853 OptionGroupOptions m_option_group
;
854 OptionGroupUInt64 m_command_byte
;
855 OptionGroupString m_packet_data
;
857 Options
*GetOptions() override
{ return &m_option_group
; }
860 CommandObjectProcessKDPPacketSend(CommandInterpreter
&interpreter
)
861 : CommandObjectParsed(interpreter
, "process plugin packet send",
862 "Send a custom packet through the KDP protocol by "
863 "specifying the command byte and the packet "
864 "payload data. A packet will be sent with a "
865 "correct header and payload, and the raw result "
866 "bytes will be displayed as a string value. ",
869 m_command_byte(LLDB_OPT_SET_1
, true, "command", 'c', 0, eArgTypeNone
,
870 "Specify the command byte to use when sending the KDP "
873 m_packet_data(LLDB_OPT_SET_1
, false, "payload", 'p', 0, eArgTypeNone
,
874 "Specify packet payload bytes as a hex ASCII string with "
875 "no spaces or hex prefixes.",
877 m_option_group
.Append(&m_command_byte
, LLDB_OPT_SET_ALL
, LLDB_OPT_SET_1
);
878 m_option_group
.Append(&m_packet_data
, LLDB_OPT_SET_ALL
, LLDB_OPT_SET_1
);
879 m_option_group
.Finalize();
882 ~CommandObjectProcessKDPPacketSend() override
= default;
884 void DoExecute(Args
&command
, CommandReturnObject
&result
) override
{
885 if (!m_command_byte
.GetOptionValue().OptionWasSet()) {
887 "the --command option must be set to a valid command byte");
889 const uint64_t command_byte
=
890 m_command_byte
.GetOptionValue().GetValueAs
<uint64_t>().value_or(0);
891 if (command_byte
> 0 && command_byte
<= UINT8_MAX
) {
892 ProcessKDP
*process
=
893 (ProcessKDP
*)m_interpreter
.GetExecutionContext().GetProcessPtr();
895 const StateType state
= process
->GetState();
897 if (StateIsStoppedState(state
, true)) {
898 std::vector
<uint8_t> payload_bytes
;
899 const char *ascii_hex_bytes_cstr
=
900 m_packet_data
.GetOptionValue().GetCurrentValue();
901 if (ascii_hex_bytes_cstr
&& ascii_hex_bytes_cstr
[0]) {
902 StringExtractor
extractor(ascii_hex_bytes_cstr
);
903 const size_t ascii_hex_bytes_cstr_len
=
904 extractor
.GetStringRef().size();
905 if (ascii_hex_bytes_cstr_len
& 1) {
906 result
.AppendErrorWithFormat("payload data must contain an "
907 "even number of ASCII hex "
909 ascii_hex_bytes_cstr
);
912 payload_bytes
.resize(ascii_hex_bytes_cstr_len
/ 2);
913 if (extractor
.GetHexBytes(payload_bytes
, '\xdd') !=
914 payload_bytes
.size()) {
915 result
.AppendErrorWithFormat("payload data must only contain "
916 "ASCII hex characters (no "
917 "spaces or hex prefixes): '%s'",
918 ascii_hex_bytes_cstr
);
924 process
->GetCommunication().SendRawRequest(
926 payload_bytes
.empty() ? NULL
: payload_bytes
.data(),
927 payload_bytes
.size(), reply
, error
);
929 if (error
.Success()) {
930 // Copy the binary bytes into a hex ASCII string for the result
932 packet
.PutBytesAsRawHex8(
933 reply
.GetDataStart(), reply
.GetByteSize(),
934 endian::InlHostByteOrder(), endian::InlHostByteOrder());
935 result
.AppendMessage(packet
.GetString());
936 result
.SetStatus(eReturnStatusSuccessFinishResult
);
939 const char *error_cstr
= error
.AsCString();
940 if (error_cstr
&& error_cstr
[0])
941 result
.AppendError(error_cstr
);
943 result
.AppendErrorWithFormat("unknown error 0x%8.8x",
948 result
.AppendErrorWithFormat("process must be stopped in order "
949 "to send KDP packets, state is %s",
950 StateAsCString(state
));
953 result
.AppendError("invalid process");
956 result
.AppendErrorWithFormat("invalid command byte 0x%" PRIx64
957 ", valid values are 1 - 255",
964 class CommandObjectProcessKDPPacket
: public CommandObjectMultiword
{
967 CommandObjectProcessKDPPacket(CommandInterpreter
&interpreter
)
968 : CommandObjectMultiword(interpreter
, "process plugin packet",
969 "Commands that deal with KDP remote packets.",
973 CommandObjectSP(new CommandObjectProcessKDPPacketSend(interpreter
)));
976 ~CommandObjectProcessKDPPacket() override
= default;
979 class CommandObjectMultiwordProcessKDP
: public CommandObjectMultiword
{
981 CommandObjectMultiwordProcessKDP(CommandInterpreter
&interpreter
)
982 : CommandObjectMultiword(
983 interpreter
, "process plugin",
984 "Commands for operating on a ProcessKDP process.",
985 "process plugin <subcommand> [<subcommand-options>]") {
986 LoadSubCommand("packet", CommandObjectSP(new CommandObjectProcessKDPPacket(
990 ~CommandObjectMultiwordProcessKDP() override
= default;
993 CommandObject
*ProcessKDP::GetPluginCommandObject() {
995 m_command_sp
= std::make_shared
<CommandObjectMultiwordProcessKDP
>(
996 GetTarget().GetDebugger().GetCommandInterpreter());
997 return m_command_sp
.get();