LLDB mainline
ProcessKDP.cpp
Go to the documentation of this file.
1//===-- ProcessKDP.cpp ----------------------------------------------------===//
2//
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
6//
7//===----------------------------------------------------------------------===//
8
9#include <cerrno>
10#include <cstdlib>
11
12#include <memory>
13
14#include "lldb/Core/Debugger.h"
15#include "lldb/Core/Module.h"
19#include "lldb/Host/Host.h"
31#include "lldb/Target/Target.h"
32#include "lldb/Target/Thread.h"
34#include "lldb/Utility/Log.h"
35#include "lldb/Utility/State.h"
37#include "lldb/Utility/UUID.h"
38
39#define USEC_PER_SEC 1000000
40
43#include "ProcessKDP.h"
44#include "ProcessKDPLog.h"
45#include "ThreadKDP.h"
46
47using namespace lldb;
48using namespace lldb_private;
49
50LLDB_PLUGIN_DEFINE_ADV(ProcessKDP, ProcessMacOSXKernel)
51
52namespace {
53
54#define LLDB_PROPERTIES_processkdp
55#include "ProcessKDPProperties.inc"
56
57enum {
58#define LLDB_PROPERTIES_processkdp
59#include "ProcessKDPPropertiesEnum.inc"
60};
61
62class PluginProperties : public Properties {
63public:
64 static llvm::StringRef GetSettingName() {
66 }
67
68 PluginProperties() : Properties() {
69 m_collection_sp = std::make_shared<OptionValueProperties>(GetSettingName());
70 m_collection_sp->Initialize(g_processkdp_properties_def);
71 }
72
73 ~PluginProperties() override = default;
74
75 uint64_t GetPacketTimeout() {
76 const uint32_t idx = ePropertyKDPPacketTimeout;
77 return GetPropertyAtIndexAs<uint64_t>(
78 idx, g_processkdp_properties[idx].default_uint_value);
79 }
80};
81
82} // namespace
83
84static PluginProperties &GetGlobalPluginProperties() {
85 static PluginProperties g_settings;
86 return g_settings;
87}
88
89static const lldb::tid_t g_kernel_tid = 1;
90
92 return "KDP Remote protocol based debugging plug-in for darwin kernel "
93 "debugging.";
94}
95
100
102 ListenerSP listener_sp,
103 const FileSpec *crash_file_path,
104 bool can_connect) {
105 lldb::ProcessSP process_sp;
106 if (crash_file_path == NULL)
107 process_sp = std::make_shared<ProcessKDP>(target_sp, listener_sp);
108 return process_sp;
109}
110
111bool ProcessKDP::CanDebug(TargetSP target_sp, bool plugin_specified_by_name) {
112 if (plugin_specified_by_name)
113 return true;
114
115 // For now we are just making sure the file exists for a given module
116 Module *exe_module = target_sp->GetExecutableModulePointer();
117 if (exe_module) {
118 const llvm::Triple &triple_ref = target_sp->GetArchitecture().GetTriple();
119 switch (triple_ref.getOS()) {
120 case llvm::Triple::Darwin: // Should use "macosx" for desktop and "ios" for
121 // iOS, but accept darwin just in case
122 case llvm::Triple::MacOSX: // For desktop targets
123 case llvm::Triple::IOS: // For arm targets
124 case llvm::Triple::TvOS:
125 case llvm::Triple::WatchOS:
126 case llvm::Triple::XROS:
127 if (triple_ref.getVendor() == llvm::Triple::Apple) {
128 ObjectFile *exe_objfile = exe_module->GetObjectFile();
129 if (exe_objfile->GetType() == ObjectFile::eTypeExecutable &&
130 exe_objfile->GetStrata() == ObjectFile::eStrataKernel)
131 return true;
132 }
133 break;
134
135 default:
136 break;
137 }
138 }
139 return false;
140}
141
142// ProcessKDP constructor
144 : Process(target_sp, listener_sp),
145 m_comm("lldb.process.kdp-remote.communication"),
146 m_async_broadcaster(NULL, "lldb.process.kdp-remote.async-broadcaster"),
150 "async thread should exit");
152 "async thread continue");
153 const uint64_t timeout_seconds =
154 GetGlobalPluginProperties().GetPacketTimeout();
155 if (timeout_seconds > 0)
156 m_comm.SetPacketTimeout(std::chrono::seconds(timeout_seconds));
157}
158
159// Destructor
161 Clear();
162 // We need to call finalize on the process before destroying ourselves to
163 // make sure all of the broadcaster cleanup goes as planned. If we destruct
164 // this class, then Process::~Process() might have problems trying to fully
165 // destroy the broadcaster.
166 Finalize(true /* destructing */);
167}
168
172 "launching not supported in kdp-remote plug-in");
173 return error;
174}
175
179 "attaching to a by process ID not supported in kdp-remote plug-in");
180 return error;
181}
182
184 bool wait_for_launch) {
187 "attaching to a by process name not supported in kdp-remote plug-in");
188 return error;
189}
190
192 uint32_t cpu = m_comm.GetCPUType();
193 if (cpu) {
194 uint32_t sub = m_comm.GetCPUSubtype();
195 arch.SetArchitecture(eArchTypeMachO, cpu, sub);
196 // Leave architecture vendor as unspecified unknown
197 arch.GetTriple().setVendor(llvm::Triple::UnknownVendor);
198 arch.GetTriple().setVendorName(llvm::StringRef());
199 return true;
200 }
201 arch.Clear();
202 return false;
203}
204
205Status ProcessKDP::DoConnectRemote(llvm::StringRef remote_url) {
207
208 // Don't let any JIT happen when doing KDP as we can't allocate memory and we
209 // don't want to be mucking with threads that might already be handling
210 // exceptions
211 SetCanJIT(false);
212
213 if (remote_url.empty())
214 return Status::FromErrorString("empty connection URL");
215
216 std::unique_ptr<ConnectionFileDescriptor> conn_up(
218 if (conn_up) {
219 // Only try once for now.
220 // TODO: check if we should be retrying?
221 const uint32_t max_retry_count = 1;
222 for (uint32_t retry_count = 0; retry_count < max_retry_count;
223 ++retry_count) {
224 if (conn_up->Connect(remote_url, &error) == eConnectionStatusSuccess)
225 break;
226 usleep(100000);
227 }
228 }
229
230 if (conn_up->IsConnected()) {
231 const TCPSocket &socket =
232 static_cast<const TCPSocket &>(*conn_up->GetReadObject());
233 const uint16_t reply_port = socket.GetLocalPortNumber();
234
235 if (reply_port != 0) {
236 m_comm.SetConnection(std::move(conn_up));
237
238 if (m_comm.SendRequestReattach(reply_port)) {
239 if (m_comm.SendRequestConnect(reply_port, reply_port,
240 "Greetings from LLDB...")) {
241 m_comm.GetVersion();
242
243 Target &target = GetTarget();
244 ArchSpec kernel_arch;
245 // The host architecture
246 GetHostArchitecture(kernel_arch);
247 ArchSpec target_arch = target.GetArchitecture();
248 // Merge in any unspecified stuff into the target architecture in
249 // case the target arch isn't set at all or incompletely.
250 target_arch.MergeFrom(kernel_arch);
251 target.SetArchitecture(target_arch);
252
253 /* Get the kernel's UUID and load address via KDP_KERNELVERSION
254 * packet. */
255 /* An EFI kdp session has neither UUID nor load address. */
256
257 UUID kernel_uuid = m_comm.GetUUID();
258 addr_t kernel_load_addr = m_comm.GetLoadAddress();
259
260 if (m_comm.RemoteIsEFI()) {
261 // Select an invalid plugin name for the dynamic loader so one
262 // doesn't get used since EFI does its own manual loading via
263 // python scripting
264 m_dyld_plugin_name = "none";
265
266 if (kernel_uuid.IsValid()) {
267 // If EFI passed in a UUID= try to lookup UUID The slide will not
268 // be provided. But the UUID lookup will be used to launch EFI
269 // debug scripts from the dSYM, that can load all of the symbols.
270 ModuleSpec module_spec;
271 module_spec.GetUUID() = kernel_uuid;
272 module_spec.GetArchitecture() = target.GetArchitecture();
273
274 // Lookup UUID locally, before attempting dsymForUUID like action
275 FileSpecList search_paths =
277
278 StatisticsMap symbol_locator_map;
279 module_spec.GetSymbolFileSpec() =
281 module_spec, search_paths, symbol_locator_map);
282 if (module_spec.GetSymbolFileSpec()) {
283 ModuleSpec executable_module_spec =
285 module_spec, symbol_locator_map);
286 if (FileSystem::Instance().Exists(
287 executable_module_spec.GetFileSpec())) {
288 module_spec.GetFileSpec() =
289 executable_module_spec.GetFileSpec();
290 }
291 }
292 if (!module_spec.GetSymbolFileSpec() ||
293 !module_spec.GetSymbolFileSpec()) {
294 Status symbl_error;
296 symbl_error, true);
297 }
298
299 if (FileSystem::Instance().Exists(module_spec.GetFileSpec())) {
300 ModuleSP module_sp(new Module(module_spec));
301 module_sp->GetSymbolLocatorStatistics().merge(
302 symbol_locator_map);
303 if (module_sp.get() && module_sp->GetObjectFile()) {
304 // Get the current target executable
305 ModuleSP exe_module_sp(target.GetExecutableModule());
306
307 // Make sure you don't already have the right module loaded
308 // and they will be uniqued
309 if (exe_module_sp.get() != module_sp.get())
310 target.SetExecutableModule(module_sp, eLoadDependentsNo);
311 }
312 }
313 }
314 } else if (m_comm.RemoteIsDarwinKernel()) {
317 if (kernel_load_addr != LLDB_INVALID_ADDRESS) {
318 m_kernel_load_addr = kernel_load_addr;
319 }
320 }
321
322 // Set the thread ID
324 SetID(1);
327 const char *cstr;
328 if ((cstr = m_comm.GetKernelVersion()) != NULL)
329 target.GetDebugger().GetAsyncOutputStream()->Printf("Version: %s\n",
330 cstr);
331 } else {
332 return Status::FromErrorString("KDP_REATTACH failed");
333 }
334 } else {
335 return Status::FromErrorString("KDP_REATTACH failed");
336 }
337 } else {
338 return Status::FromErrorString("invalid reply port from UDP connection");
339 }
340 } else {
341 if (error.Success())
342 error = Status::FromErrorStringWithFormat("failed to connect to '%s'",
343 remote_url.str().c_str());
344 }
345 if (error.Fail())
346 m_comm.Disconnect();
347
348 return error;
349}
350
351// Process Control
353 ProcessLaunchInfo &launch_info) {
356 "launching not supported in kdp-remote plug-in");
357 return error;
358}
359
360Status
362 const ProcessAttachInfo &attach_info) {
365 "attach to process by ID is not supported in kdp remote debugging");
366 return error;
367}
368
369Status
371 const ProcessAttachInfo &attach_info) {
374 "attach to process by name is not supported in kdp remote debugging");
375 return error;
376}
377
378void ProcessKDP::DidAttach(ArchSpec &process_arch) {
379 Process::DidAttach(process_arch);
380
381 Log *log = GetLog(KDPLog::Process);
382 LLDB_LOGF(log, "ProcessKDP::DidAttach()");
384 GetHostArchitecture(process_arch);
385 }
386}
387
389
395
397
400 Log *log = GetLog(KDPLog::Process);
401
402 if (direction == RunDirection::eRunReverse)
404 "{0} does not support reverse execution of processes", GetPluginName());
405
406 // Only start the async thread if we try to do any process control
407 if (!m_async_thread.IsJoinable())
409
410 bool resume = false;
411
412 // With KDP there is only one thread we can tell what to do
413 ThreadSP kernel_thread_sp(m_thread_list.FindThreadByProtocolID(g_kernel_tid));
414
415 if (kernel_thread_sp) {
416 const StateType thread_resume_state =
417 kernel_thread_sp->GetTemporaryResumeState();
418
419 LLDB_LOGF(log, "ProcessKDP::DoResume() thread_resume_state = %s",
420 StateAsCString(thread_resume_state));
421 switch (thread_resume_state) {
422 case eStateSuspended:
423 // Nothing to do here when a thread will stay suspended we just leave the
424 // CPU mask bit set to zero for the thread
425 LLDB_LOGF(log, "ProcessKDP::DoResume() = suspended???");
426 break;
427
428 case eStateStepping: {
429 lldb::RegisterContextSP reg_ctx_sp(
430 kernel_thread_sp->GetRegisterContext());
431
432 if (reg_ctx_sp) {
433 LLDB_LOGF(
434 log,
435 "ProcessKDP::DoResume () reg_ctx_sp->HardwareSingleStep (true);");
436 reg_ctx_sp->HardwareSingleStep(true);
437 resume = true;
438 } else {
440 "KDP thread 0x%llx has no register context",
441 kernel_thread_sp->GetID());
442 }
443 } break;
444
445 case eStateRunning: {
446 lldb::RegisterContextSP reg_ctx_sp(
447 kernel_thread_sp->GetRegisterContext());
448
449 if (reg_ctx_sp) {
450 LLDB_LOGF(log, "ProcessKDP::DoResume () reg_ctx_sp->HardwareSingleStep "
451 "(false);");
452 reg_ctx_sp->HardwareSingleStep(false);
453 resume = true;
454 } else {
456 "KDP thread 0x%llx has no register context",
457 kernel_thread_sp->GetID());
458 }
459 } break;
460
461 default:
462 // The only valid thread resume states are listed above
463 llvm_unreachable("invalid thread resume state");
464 }
465 }
466
467 if (resume) {
468 LLDB_LOGF(log, "ProcessKDP::DoResume () sending resume");
469
470 if (m_comm.SendRequestResume()) {
473 } else
474 return Status::FromErrorString("KDP resume failed");
475 } else {
476 return Status::FromErrorString("kernel thread is suspended");
477 }
478
479 return error;
480}
481
483 // KDP only tells us about one thread/core. Any other threads will usually
484 // be the ones that are read from memory by the OS plug-ins.
485
486 ThreadSP thread_sp(m_kernel_thread_wp.lock());
487 if (!thread_sp) {
488 thread_sp = std::make_shared<ThreadKDP>(*this, g_kernel_tid);
489 m_kernel_thread_wp = thread_sp;
490 }
491 return thread_sp;
492}
493
495 ThreadList &new_thread_list) {
496 // locker will keep a mutex locked until it goes out of scope
497 Log *log = GetLog(KDPLog::Thread);
498 LLDB_LOGV(log, "pid = {0}", GetID());
499
500 // Even though there is a CPU mask, it doesn't mean we can see each CPU
501 // individually, there is really only one. Lets call this thread 1.
502 ThreadSP thread_sp(
503 old_thread_list.FindThreadByProtocolID(g_kernel_tid, false));
504 if (!thread_sp)
505 thread_sp = GetKernelThread();
506 new_thread_list.AddThread(thread_sp);
507
508 return new_thread_list.GetSize(false) > 0;
509}
510
512 // Let all threads recover from stopping and do any clean up based on the
513 // previous thread state (if any).
514 m_thread_list.RefreshStateAfterStop();
515}
516
517Status ProcessKDP::DoHalt(bool &caused_stop) {
519
520 if (m_comm.IsRunning()) {
522 // If we are attempting to destroy, we need to not return an error to Halt
523 // or DoDestroy won't get called. We are also currently running, so send
524 // a process stopped event
526 } else {
527 return Status::FromErrorString("KDP cannot interrupt a running kernel");
528 }
529 }
530 return error;
531}
532
533Status ProcessKDP::DoDetach(bool keep_stopped) {
535 Log *log = GetLog(KDPLog::Process);
536 LLDB_LOGF(log, "ProcessKDP::DoDetach(keep_stopped = %i)", keep_stopped);
537
538 if (m_comm.IsRunning()) {
539 // We are running and we can't interrupt a running kernel, so we need to
540 // just close the connection to the kernel and hope for the best
541 } else {
542 // If we are going to keep the target stopped, then don't send the
543 // disconnect message.
544 if (!keep_stopped && m_comm.IsConnected()) {
545 const bool success = m_comm.SendRequestDisconnect();
546 if (log) {
547 if (success)
548 log->PutCString(
549 "ProcessKDP::DoDetach() detach packet sent successfully");
550 else
551 log->PutCString(
552 "ProcessKDP::DoDetach() connection channel shutdown failed");
553 }
554 m_comm.Disconnect();
555 }
556 }
558 m_comm.Clear();
559
562
563 // KillDebugserverProcess ();
564 return error;
565}
566
568 // For KDP there really is no difference between destroy and detach
569 bool keep_stopped = false;
570 return DoDetach(keep_stopped);
571}
572
573// Process Queries
574
576 return m_comm.IsConnected() && Process::IsAlive();
577}
578
579// Process Memory
580size_t ProcessKDP::DoReadMemory(addr_t addr, void *buf, size_t size,
581 Status &error) {
582 uint8_t *data_buffer = (uint8_t *)buf;
583 if (m_comm.IsConnected()) {
584 const size_t max_read_size = 512;
585 size_t total_bytes_read = 0;
586
587 // Read the requested amount of memory in 512 byte chunks
588 while (total_bytes_read < size) {
589 size_t bytes_to_read_this_request = size - total_bytes_read;
590 if (bytes_to_read_this_request > max_read_size) {
591 bytes_to_read_this_request = max_read_size;
592 }
593 size_t bytes_read = m_comm.SendRequestReadMemory(
594 addr + total_bytes_read, data_buffer + total_bytes_read,
595 bytes_to_read_this_request, error);
596 total_bytes_read += bytes_read;
597 if (error.Fail() || bytes_read == 0) {
598 return total_bytes_read;
599 }
600 }
601
602 return total_bytes_read;
603 }
604 error = Status::FromErrorString("not connected");
605 return 0;
606}
607
608size_t ProcessKDP::DoWriteMemory(addr_t addr, const void *buf, size_t size,
609 Status &error) {
610 if (m_comm.IsConnected())
611 return m_comm.SendRequestWriteMemory(addr, buf, size, error);
612 error = Status::FromErrorString("not connected");
613 return 0;
614}
615
616lldb::addr_t ProcessKDP::DoAllocateMemory(size_t size, uint32_t permissions,
617 Status &error) {
619 "memory allocation not supported in kdp remote debugging");
621}
622
626 "memory deallocation not supported in kdp remote debugging");
627 return error;
628}
629
631 if (bp_site->HardwareRequired())
632 return Status::FromErrorString("Hardware breakpoints are not supported.");
633
634 if (m_comm.LocalBreakpointsAreSupported()) {
636 if (!bp_site->IsEnabled()) {
637 if (m_comm.SendRequestBreakpoint(true, bp_site->GetLoadAddress())) {
638 bp_site->SetEnabled(true);
640 } else {
641 return Status::FromErrorString("KDP set breakpoint failed");
642 }
643 }
644 return error;
645 }
646 return EnableSoftwareBreakpoint(bp_site);
647}
648
650 if (m_comm.LocalBreakpointsAreSupported()) {
652 if (bp_site->IsEnabled()) {
653 BreakpointSite::Type bp_type = bp_site->GetType();
654 if (bp_type == BreakpointSite::eExternal) {
655 if (m_destroy_in_process && m_comm.IsRunning()) {
656 // We are trying to destroy our connection and we are running
657 bp_site->SetEnabled(false);
658 } else {
659 if (m_comm.SendRequestBreakpoint(false, bp_site->GetLoadAddress()))
660 bp_site->SetEnabled(false);
661 else
662 return Status::FromErrorString("KDP remove breakpoint failed");
663 }
664 } else {
666 }
667 }
668 return error;
669 }
670 return DisableSoftwareBreakpoint(bp_site);
671}
672
674
678 "sending signals is not supported in kdp remote debugging");
679 return error;
680}
681
689
692 debugger, PluginProperties::GetSettingName())) {
693 const bool is_global_setting = true;
696 "Properties for the kdp-remote process plug-in.", is_global_setting);
697 }
698}
699
701 Log *log = GetLog(KDPLog::Process);
702
703 LLDB_LOGF(log, "ProcessKDP::StartAsyncThread ()");
704
705 if (m_async_thread.IsJoinable())
706 return true;
707
708 llvm::Expected<HostThread> async_thread = ThreadLauncher::LaunchThread(
709 "<lldb.process.kdp-remote.async>", [this] { return AsyncThread(); });
710 if (!async_thread) {
711 LLDB_LOG_ERROR(GetLog(LLDBLog::Host), async_thread.takeError(),
712 "failed to launch host thread: {0}");
713 return false;
714 }
715 m_async_thread = *async_thread;
716 return m_async_thread.IsJoinable();
717}
718
720 Log *log = GetLog(KDPLog::Process);
721
722 LLDB_LOGF(log, "ProcessKDP::StopAsyncThread ()");
723
725
726 // Stop the stdio thread
727 if (m_async_thread.IsJoinable())
728 m_async_thread.Join(nullptr);
729}
730
732 const lldb::pid_t pid = GetID();
733
734 Log *log = GetLog(KDPLog::Process);
735 LLDB_LOGF(log,
736 "ProcessKDP::AsyncThread(pid = %" PRIu64 ") thread starting...",
737 pid);
738
739 ListenerSP listener_sp(Listener::MakeListener("ProcessKDP::AsyncThread"));
740 EventSP event_sp;
741 const uint32_t desired_event_mask =
743
744 if (listener_sp->StartListeningForEvents(
745 &m_async_broadcaster, desired_event_mask) == desired_event_mask) {
746 bool done = false;
747 while (!done) {
748 LLDB_LOGF(log,
749 "ProcessKDP::AsyncThread (pid = %" PRIu64
750 ") listener.WaitForEvent (NULL, event_sp)...",
751 pid);
752 if (listener_sp->GetEvent(event_sp, std::nullopt)) {
753 uint32_t event_type = event_sp->GetType();
754 LLDB_LOGF(log,
755 "ProcessKDP::AsyncThread (pid = %" PRIu64
756 ") Got an event of type: %d...",
757 pid, event_type);
758
759 // When we are running, poll for 1 second to try and get an exception
760 // to indicate the process has stopped. If we don't get one, check to
761 // make sure no one asked us to exit
762 bool is_running = false;
763 DataExtractor exc_reply_packet;
764 do {
765 switch (event_type) {
767 is_running = true;
768 if (m_comm.WaitForPacketWithTimeoutMicroSeconds(
769 exc_reply_packet, 1 * USEC_PER_SEC)) {
770 ThreadSP thread_sp(GetKernelThread());
771 if (thread_sp) {
772 lldb::RegisterContextSP reg_ctx_sp(
773 thread_sp->GetRegisterContext());
774 if (reg_ctx_sp)
775 reg_ctx_sp->InvalidateAllRegisters();
776 static_cast<ThreadKDP *>(thread_sp.get())
777 ->SetStopInfoFrom_KDP_EXCEPTION(exc_reply_packet);
778 }
779
780 // TODO: parse the stop reply packet
781 is_running = false;
783 } else {
784 // Check to see if we are supposed to exit. There is no way to
785 // interrupt a running kernel, so all we can do is wait for an
786 // exception or detach...
787 if (listener_sp->GetEvent(event_sp,
788 std::chrono::microseconds(0))) {
789 // We got an event, go through the loop again
790 event_type = event_sp->GetType();
791 }
792 }
793 } break;
794
796 LLDB_LOGF(log,
797 "ProcessKDP::AsyncThread (pid = %" PRIu64
798 ") got eBroadcastBitAsyncThreadShouldExit...",
799 pid);
800 done = true;
801 is_running = false;
802 break;
803
804 default:
805 LLDB_LOGF(log,
806 "ProcessKDP::AsyncThread (pid = %" PRIu64
807 ") got unknown event 0x%8.8x",
808 pid, event_type);
809 done = true;
810 is_running = false;
811 break;
812 }
813 } while (is_running);
814 } else {
815 LLDB_LOGF(log,
816 "ProcessKDP::AsyncThread (pid = %" PRIu64
817 ") listener.WaitForEvent (NULL, event_sp) => false",
818 pid);
819 done = true;
820 }
821 }
822 }
823
824 LLDB_LOGF(log, "ProcessKDP::AsyncThread(pid = %" PRIu64 ") thread exiting...",
825 pid);
826
827 m_async_thread.Reset();
828 return NULL;
829}
830
832private:
836
837 Options *GetOptions() override { return &m_option_group; }
838
839public:
841 : CommandObjectParsed(interpreter, "process plugin packet send",
842 "Send a custom packet through the KDP protocol by "
843 "specifying the command byte and the packet "
844 "payload data. A packet will be sent with a "
845 "correct header and payload, and the raw result "
846 "bytes will be displayed as a string value. ",
847 NULL),
849 m_command_byte(LLDB_OPT_SET_1, true, "command", 'c', 0, eArgTypeNone,
850 "Specify the command byte to use when sending the KDP "
851 "request packet.",
852 0),
853 m_packet_data(LLDB_OPT_SET_1, false, "payload", 'p', 0, eArgTypeNone,
854 "Specify packet payload bytes as a hex ASCII string with "
855 "no spaces or hex prefixes.",
856 NULL) {
859 m_option_group.Finalize();
860 }
861
863
864 void DoExecute(Args &command, CommandReturnObject &result) override {
865 if (!m_command_byte.GetOptionValue().OptionWasSet()) {
866 result.AppendError(
867 "the --command option must be set to a valid command byte");
868 } else {
869 const uint64_t command_byte =
870 m_command_byte.GetOptionValue().GetValueAs<uint64_t>().value_or(0);
871 if (command_byte > 0 && command_byte <= UINT8_MAX) {
872 ProcessKDP *process =
873 (ProcessKDP *)m_interpreter.GetExecutionContext().GetProcessPtr();
874 if (process) {
875 const StateType state = process->GetState();
876
877 if (StateIsStoppedState(state, true)) {
878 std::vector<uint8_t> payload_bytes;
879 const char *ascii_hex_bytes_cstr =
880 m_packet_data.GetOptionValue().GetCurrentValue();
881 if (ascii_hex_bytes_cstr && ascii_hex_bytes_cstr[0]) {
882 StringExtractor extractor(ascii_hex_bytes_cstr);
883 const size_t ascii_hex_bytes_cstr_len =
884 extractor.GetStringRef().size();
885 if (ascii_hex_bytes_cstr_len & 1) {
886 result.AppendErrorWithFormat("payload data must contain an "
887 "even number of ASCII hex "
888 "characters: '%s'",
889 ascii_hex_bytes_cstr);
890 return;
891 }
892 payload_bytes.resize(ascii_hex_bytes_cstr_len / 2);
893 if (extractor.GetHexBytes(payload_bytes, '\xdd') !=
894 payload_bytes.size()) {
895 result.AppendErrorWithFormat("payload data must only contain "
896 "ASCII hex characters (no "
897 "spaces or hex prefixes): '%s'",
898 ascii_hex_bytes_cstr);
899 return;
900 }
901 }
903 DataExtractor reply;
905 command_byte,
906 payload_bytes.empty() ? NULL : payload_bytes.data(),
907 payload_bytes.size(), reply, error);
908
909 if (error.Success()) {
910 // Copy the binary bytes into a hex ASCII string for the result
911 StreamString packet;
912 packet.PutBytesAsRawHex8(
913 reply.GetDataStart(), reply.GetByteSize(),
915 result.AppendMessage(packet.GetString());
917 return;
918 } else {
919 const char *error_cstr = error.AsCString();
920 if (error_cstr && error_cstr[0])
921 result.AppendError(error_cstr);
922 else
923 result.AppendErrorWithFormat("unknown error 0x%8.8x",
924 error.GetError());
925 return;
926 }
927 } else {
928 result.AppendErrorWithFormat("process must be stopped in order "
929 "to send KDP packets, state is %s",
930 StateAsCString(state));
931 }
932 } else {
933 result.AppendError("invalid process");
934 }
935 } else {
936 result.AppendErrorWithFormat("invalid command byte 0x%" PRIx64
937 ", valid values are 1 - 255",
938 command_byte);
939 }
940 }
941 }
942};
943
945private:
946public:
948 : CommandObjectMultiword(interpreter, "process plugin packet",
949 "Commands that deal with KDP remote packets.",
950 NULL) {
952 "send",
954 }
955
956 ~CommandObjectProcessKDPPacket() override = default;
957};
958
960public:
963 interpreter, "process plugin",
964 "Commands for operating on a ProcessKDP process.",
965 "process plugin <subcommand> [<subcommand-options>]") {
967 interpreter)));
968 }
969
971};
972
974 if (!m_command_sp)
975 m_command_sp = std::make_shared<CommandObjectMultiwordProcessKDP>(
976 GetTarget().GetDebugger().GetCommandInterpreter());
977 return m_command_sp.get();
978}
static llvm::raw_ostream & error(Stream &strm)
static PluginProperties & GetGlobalPluginProperties()
#define LLDB_LOGF(log,...)
Definition Log.h:376
#define LLDB_LOG_ERROR(log, error,...)
Definition Log.h:392
#define LLDB_LOGV(log,...)
Definition Log.h:383
#define LLDB_PLUGIN_DEFINE_ADV(ClassName, PluginName)
static PluginProperties & GetGlobalPluginProperties()
#define USEC_PER_SEC
static const lldb::tid_t g_kernel_tid
CommandObjectMultiwordProcessKDP(CommandInterpreter &interpreter)
~CommandObjectMultiwordProcessKDP() override=default
CommandObjectProcessKDPPacketSend(CommandInterpreter &interpreter)
void DoExecute(Args &command, CommandReturnObject &result) override
Options * GetOptions() override
~CommandObjectProcessKDPPacketSend() override=default
~CommandObjectProcessKDPPacket() override=default
CommandObjectProcessKDPPacket(CommandInterpreter &interpreter)
bool SendRawRequest(uint8_t command_byte, const void *src, uint32_t src_len, lldb_private::DataExtractor &reply, lldb_private::Status &error)
static llvm::StringRef GetPluginNameStatic()
lldb_private::Status DoWillLaunch(lldb_private::Module *module) override
Called before launching to a process.
lldb_private::Broadcaster m_async_broadcaster
Definition ProcessKDP.h:164
llvm::StringRef GetPluginName() override
Definition ProcessKDP.h:88
size_t DoReadMemory(lldb::addr_t addr, void *buf, size_t size, lldb_private::Status &error) override
Actually do the reading of memory from a process.
lldb::CommandObjectSP m_command_sp
Definition ProcessKDP.h:168
void DidAttach(lldb_private::ArchSpec &process_arch) override
Called after attaching a process.
ProcessKDP(lldb::TargetSP target_sp, lldb::ListenerSP listener)
static void Terminate()
lldb_private::Status EnableBreakpointSite(lldb_private::BreakpointSite *bp_site) override
lldb::ThreadSP GetKernelThread()
static llvm::StringRef GetPluginDescriptionStatic()
static void Initialize()
llvm::StringRef m_dyld_plugin_name
Definition ProcessKDP.h:166
bool GetHostArchitecture(lldb_private::ArchSpec &arch)
lldb::ThreadWP m_kernel_thread_wp
Definition ProcessKDP.h:169
friend class ThreadKDP
Definition ProcessKDP.h:130
lldb_private::Status DoLaunch(lldb_private::Module *exe_module, lldb_private::ProcessLaunchInfo &launch_info) override
Launch a new process.
void * AsyncThread()
lldb_private::Status DoSignal(int signal) override
Sends a process a UNIX signal signal.
void RefreshStateAfterStop() override
Currently called as part of ShouldStop.
lldb_private::HostThread m_async_thread
Definition ProcessKDP.h:165
~ProcessKDP() override
lldb_private::DynamicLoader * GetDynamicLoader() override
Get the dynamic loader plug-in for this process.
CommunicationKDP & GetCommunication()
Definition ProcessKDP.h:127
lldb_private::Status WillResume() override
Called before resuming to a process.
lldb_private::Status DoHalt(bool &caused_stop) override
Halts a running process.
static lldb::ProcessSP CreateInstance(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp, const lldb_private::FileSpec *crash_file_path, bool can_connect)
lldb::addr_t m_kernel_load_addr
Definition ProcessKDP.h:167
lldb_private::Status DoResume(lldb::RunDirection direction) override
Resumes all of a process's threads as configured using the Thread run control functions.
lldb_private::Status DoConnectRemote(llvm::StringRef remote_url) override
Attach to a remote system via a URL.
bool IsAlive() override
Check if a process is still alive.
lldb_private::CommandObject * GetPluginCommandObject() override
Return a multi-word command object that can be used to expose plug-in specific commands.
bool StartAsyncThread()
lldb_private::Status DoAttachToProcessWithName(const char *process_name, const lldb_private::ProcessAttachInfo &attach_info) override
Attach to an existing process using a partial process name.
lldb_private::Status DoWillAttachToProcessWithName(const char *process_name, bool wait_for_launch) override
Called before attaching to a process.
lldb::addr_t GetImageInfoAddress() override
Get the image information address for the current process.
bool DoUpdateThreadList(lldb_private::ThreadList &old_thread_list, lldb_private::ThreadList &new_thread_list) override
Update the thread list following process plug-in's specific logic.
static void DebuggerInitialize(lldb_private::Debugger &debugger)
CommunicationKDP m_comm
Broadcaster event bits definitions.
Definition ProcessKDP.h:163
lldb::addr_t DoAllocateMemory(size_t size, uint32_t permissions, lldb_private::Status &error) override
Actually allocate memory in the process.
lldb_private::Status DisableBreakpointSite(lldb_private::BreakpointSite *bp_site) override
lldb_private::Status DoWillAttachToProcessWithID(lldb::pid_t pid) override
Called before attaching to a process.
lldb_private::Status DoAttachToProcessWithID(lldb::pid_t pid, const lldb_private::ProcessAttachInfo &attach_info) override
Attach to an existing process using a process ID.
size_t DoWriteMemory(lldb::addr_t addr, const void *buf, size_t size, lldb_private::Status &error) override
Actually do the writing of memory to a process.
bool CanDebug(lldb::TargetSP target_sp, bool plugin_specified_by_name) override
Check if a plug-in instance can debug the file in module.
lldb_private::Status DoDetach(bool keep_stopped) override
Detaches from a running or stopped process.
lldb_private::Status DoDeallocateMemory(lldb::addr_t ptr) override
Actually deallocate memory in the process.
lldb_private::Status DoDestroy() override
@ eBroadcastBitAsyncThreadShouldExit
Definition ProcessKDP.h:157
@ eBroadcastBitAsyncContinue
Definition ProcessKDP.h:156
void StopAsyncThread()
static llvm::StringRef GetPluginNameStatic()
Definition ProcessKDP.h:44
size_t GetHexBytes(llvm::MutableArrayRef< uint8_t > dest, uint8_t fail_fill_value)
llvm::StringRef GetStringRef() const
An architecture specification class.
Definition ArchSpec.h:32
void Clear()
Clears the object state.
Definition ArchSpec.cpp:538
llvm::Triple & GetTriple()
Architecture triple accessor.
Definition ArchSpec.h:457
bool SetArchitecture(ArchitectureType arch_type, uint32_t cpu, uint32_t sub, uint32_t os=0)
Change the architecture object type, CPU type and OS type.
Definition ArchSpec.cpp:843
void MergeFrom(const ArchSpec &other)
Merges fields from another ArchSpec into this ArchSpec.
Definition ArchSpec.cpp:801
A command line argument class.
Definition Args.h:33
Class that manages the actual breakpoint that will be inserted into the running program.
BreakpointSite::Type GetType() const
void SetType(BreakpointSite::Type type)
bool IsEnabled() const
Tells whether the current breakpoint site is enabled or not.
void SetEnabled(bool enabled)
Sets whether the current breakpoint site is enabled or not.
bool LoadSubCommand(llvm::StringRef cmd_name, const lldb::CommandObjectSP &command_obj) override
CommandObjectMultiword(CommandInterpreter &interpreter, const char *name, const char *help=nullptr, const char *syntax=nullptr, uint32_t flags=0)
CommandObjectParsed(CommandInterpreter &interpreter, const char *name, const char *help=nullptr, const char *syntax=nullptr, uint32_t flags=0)
CommandInterpreter & m_interpreter
void AppendMessage(llvm::StringRef in_string)
void void AppendError(llvm::StringRef in_string)
void SetStatus(lldb::ReturnStatus status)
void AppendErrorWithFormat(const char *format,...) __attribute__((format(printf
An data extractor class.
virtual uint64_t GetByteSize() const
Get the number of bytes contained in this object.
const uint8_t * GetDataStart() const
Get the data start pointer.
A class to manage flag bits.
Definition Debugger.h:87
lldb::StreamUP GetAsyncOutputStream()
A plug-in interface definition class for dynamic loaders.
static DynamicLoader * FindPlugin(Process *process, llvm::StringRef plugin_name)
Find a dynamic loader plugin for a given process.
A file collection class.
A file utility class.
Definition FileSpec.h:57
static FileSystem & Instance()
static lldb::ListenerSP MakeListener(const char *name)
Definition Listener.cpp:375
void PutCString(const char *cstr)
Definition Log.cpp:145
FileSpec & GetFileSpec()
Definition ModuleSpec.h:57
ArchSpec & GetArchitecture()
Definition ModuleSpec.h:93
FileSpec & GetSymbolFileSpec()
Definition ModuleSpec.h:81
A class that describes an executable image and its associated object and symbol files.
Definition Module.h:90
virtual ObjectFile * GetObjectFile()
Get the object file representation for the current architecture.
Definition Module.cpp:1188
A plug-in interface definition class for object file parsers.
Definition ObjectFile.h:46
@ eTypeExecutable
A normal executable.
Definition ObjectFile.h:55
A command line option parsing protocol class.
Definition Options.h:58
static bool DownloadObjectAndSymbolFile(ModuleSpec &module_spec, Status &error, bool force_lookup=true, bool copy_executable=true)
static bool RegisterPlugin(llvm::StringRef name, llvm::StringRef description, ABICreateInstance create_callback)
static bool CreateSettingForProcessPlugin(Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp, llvm::StringRef description, bool is_global_property)
static FileSpec LocateExecutableSymbolFile(const ModuleSpec &module_spec, const FileSpecList &default_search_paths, StatisticsMap &map)
static lldb::OptionValuePropertiesSP GetSettingForProcessPlugin(Debugger &debugger, llvm::StringRef setting_name)
static ModuleSpec LocateExecutableObjectFile(const ModuleSpec &module_spec, StatisticsMap &map)
static bool UnregisterPlugin(ABICreateInstance create_callback)
virtual Status DisableSoftwareBreakpoint(BreakpointSite *bp_site)
Definition Process.cpp:1810
lldb::pid_t GetID() const
Returns the pid of the process or LLDB_INVALID_PROCESS_ID if there is no known pid.
Definition Process.h:537
ThreadList & GetThreadList()
Definition Process.h:2269
Process(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp)
Construct with a shared pointer to a target, and the Process listener.
Definition Process.cpp:425
void ResumePrivateStateThread()
Definition Process.cpp:3962
void SetCanJIT(bool can_jit)
Sets whether executing JIT-compiled code in this process is possible.
Definition Process.cpp:2562
lldb::DynamicLoaderUP m_dyld_up
Definition Process.h:3407
void UpdateThreadListIfNeeded()
Definition Process.cpp:1106
lldb::StateType GetState()
Get accessor for the current process state.
Definition Process.cpp:1257
virtual Status EnableSoftwareBreakpoint(BreakpointSite *bp_site)
Definition Process.cpp:1730
virtual bool IsAlive()
Check if a process is still alive.
Definition Process.cpp:1081
virtual void DidAttach(ArchSpec &process_arch)
Called after attaching a process.
Definition Process.h:1015
void SetID(lldb::pid_t new_pid)
Sets the stored pid.
Definition Process.h:542
friend class Target
Definition Process.h:360
void SetPrivateState(lldb::StateType state)
Definition Process.cpp:1377
virtual void Finalize(bool destructing)
This object is about to be destroyed, do any necessary cleanup.
Definition Process.cpp:537
ThreadList m_thread_list
The threads for this process as the user will see them.
Definition Process.h:3380
friend class ThreadList
Definition Process.h:361
Target & GetTarget()
Get the target object pointer for this module.
Definition Process.h:1250
lldb::OptionValuePropertiesSP GetValueProperties() const
A class to count time for plugins.
Definition Statistics.h:94
An error handling class.
Definition Status.h:118
static Status FromErrorStringWithFormat(const char *format,...) __attribute__((format(printf
Definition Status.cpp:106
static Status FromErrorString(const char *str)
Definition Status.h:141
static Status static Status FromErrorStringWithFormatv(const char *format, Args &&...args)
Definition Status.h:151
virtual lldb::addr_t GetLoadAddress() const
llvm::StringRef GetString() const
size_t PutBytesAsRawHex8(const void *src, size_t src_len, lldb::ByteOrder src_byte_order=lldb::eByteOrderInvalid, lldb::ByteOrder dst_byte_order=lldb::eByteOrderInvalid)
Definition Stream.cpp:391
uint16_t GetLocalPortNumber() const
Definition TCPSocket.cpp:86
Debugger & GetDebugger() const
Definition Target.h:1224
bool SetArchitecture(const ArchSpec &arch_spec, bool set_platform=false, bool merge=true)
Set the architecture for this target.
Definition Target.cpp:1705
lldb::ModuleSP GetExecutableModule()
Gets the module for the main executable.
Definition Target.cpp:1525
static FileSpecList GetDefaultDebugFileSearchPaths()
Definition Target.cpp:2803
const ArchSpec & GetArchitecture() const
Definition Target.h:1183
void SetExecutableModule(lldb::ModuleSP &module_sp, LoadDependentFiles load_dependent_files=eLoadDependentsDefault)
Set the main executable module.
Definition Target.cpp:1576
void AddThread(const lldb::ThreadSP &thread_sp)
static llvm::Expected< HostThread > LaunchThread(llvm::StringRef name, std::function< lldb::thread_result_t()> thread_function, size_t min_stack_byte_size=0)
lldb::ThreadSP FindThreadByProtocolID(lldb::tid_t tid, bool can_update=true)
uint32_t GetSize(bool can_update=true)
Represents UUID's of various sizes.
Definition UUID.h:27
bool IsValid() const
Definition UUID.h:69
#define LLDB_OPT_SET_1
#define LLDB_OPT_SET_ALL
#define LLDB_INVALID_ADDRESS
#define LLDB_INVALID_PROCESS_ID
lldb::ByteOrder InlHostByteOrder()
Definition Endian.h:25
A class that represents a running process on the host machine.
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
Definition Log.h:332
bool StateIsStoppedState(lldb::StateType state, bool must_exist)
Check if a state represents a state where the process or thread is stopped.
Definition State.cpp:89
const char * StateAsCString(lldb::StateType state)
Converts a StateType to a C string.
Definition State.cpp:14
RunDirection
Execution directions.
std::shared_ptr< lldb_private::Thread > ThreadSP
std::shared_ptr< lldb_private::CommandObject > CommandObjectSP
@ eConnectionStatusSuccess
Success.
StateType
Process and Thread States.
@ eStateDetached
Process has been detached and can't be examined.
@ eStateStopped
Process or thread is stopped and can be examined.
@ eStateSuspended
Process or thread is in a suspended state as far as the debugger is concerned while other processes o...
@ eStateRunning
Process or thread is running and can't be examined.
@ eStateStepping
Process or thread is in the process of stepping and can not be examined.
std::shared_ptr< lldb_private::Process > ProcessSP
std::shared_ptr< lldb_private::Event > EventSP
@ eReturnStatusSuccessFinishResult
uint64_t pid_t
Definition lldb-types.h:83
std::shared_ptr< lldb_private::Listener > ListenerSP
uint64_t addr_t
Definition lldb-types.h:80
std::shared_ptr< lldb_private::Target > TargetSP
std::shared_ptr< lldb_private::RegisterContext > RegisterContextSP
uint64_t tid_t
Definition lldb-types.h:84
std::shared_ptr< lldb_private::Module > ModuleSP