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.RebuildModuleListWithExecutable(module_sp,
312 }
313 }
314 }
315 } else if (m_comm.RemoteIsDarwinKernel()) {
318 if (kernel_load_addr != LLDB_INVALID_ADDRESS) {
319 m_kernel_load_addr = kernel_load_addr;
320 }
321 }
322
323 // Set the thread ID
325 SetID(1);
328 const char *cstr;
329 if ((cstr = m_comm.GetKernelVersion()) != NULL)
330 target.GetDebugger().GetAsyncOutputStream()->Printf("Version: %s\n",
331 cstr);
332 } else {
333 return Status::FromErrorString("KDP_REATTACH failed");
334 }
335 } else {
336 return Status::FromErrorString("KDP_REATTACH failed");
337 }
338 } else {
339 return Status::FromErrorString("invalid reply port from UDP connection");
340 }
341 } else {
342 if (error.Success())
343 error = Status::FromErrorStringWithFormat("failed to connect to '%s'",
344 remote_url.str().c_str());
345 }
346 if (error.Fail())
347 m_comm.Disconnect();
348
349 return error;
350}
351
352// Process Control
354 ProcessLaunchInfo &launch_info) {
357 "launching not supported in kdp-remote plug-in");
358 return error;
359}
360
361Status
363 const ProcessAttachInfo &attach_info) {
366 "attach to process by ID is not supported in kdp remote debugging");
367 return error;
368}
369
370Status
372 const ProcessAttachInfo &attach_info) {
375 "attach to process by name is not supported in kdp remote debugging");
376 return error;
377}
378
379void ProcessKDP::DidAttach(ArchSpec &process_arch) {
380 Process::DidAttach(process_arch);
381
382 Log *log = GetLog(KDPLog::Process);
383 LLDB_LOGF(log, "ProcessKDP::DidAttach()");
385 GetHostArchitecture(process_arch);
386 }
387}
388
390
396
398
401 Log *log = GetLog(KDPLog::Process);
402
403 if (direction == RunDirection::eRunReverse)
405 "{0} does not support reverse execution of processes", GetPluginName());
406
407 // Only start the async thread if we try to do any process control
408 if (!m_async_thread.IsJoinable())
410
411 bool resume = false;
412
413 // With KDP there is only one thread we can tell what to do
414 ThreadSP kernel_thread_sp(m_thread_list.FindThreadByProtocolID(g_kernel_tid));
415
416 if (kernel_thread_sp) {
417 const StateType thread_resume_state =
418 kernel_thread_sp->GetTemporaryResumeState();
419
420 LLDB_LOGF(log, "ProcessKDP::DoResume() thread_resume_state = %s",
421 StateAsCString(thread_resume_state));
422 switch (thread_resume_state) {
423 case eStateSuspended:
424 // Nothing to do here when a thread will stay suspended we just leave the
425 // CPU mask bit set to zero for the thread
426 LLDB_LOGF(log, "ProcessKDP::DoResume() = suspended???");
427 break;
428
429 case eStateStepping: {
430 lldb::RegisterContextSP reg_ctx_sp(
431 kernel_thread_sp->GetRegisterContext());
432
433 if (reg_ctx_sp) {
434 LLDB_LOGF(
435 log,
436 "ProcessKDP::DoResume () reg_ctx_sp->HardwareSingleStep (true);");
437 reg_ctx_sp->HardwareSingleStep(true);
438 resume = true;
439 } else {
441 "KDP thread 0x%llx has no register context",
442 kernel_thread_sp->GetID());
443 }
444 } break;
445
446 case eStateRunning: {
447 lldb::RegisterContextSP reg_ctx_sp(
448 kernel_thread_sp->GetRegisterContext());
449
450 if (reg_ctx_sp) {
451 LLDB_LOGF(log, "ProcessKDP::DoResume () reg_ctx_sp->HardwareSingleStep "
452 "(false);");
453 reg_ctx_sp->HardwareSingleStep(false);
454 resume = true;
455 } else {
457 "KDP thread 0x%llx has no register context",
458 kernel_thread_sp->GetID());
459 }
460 } break;
461
462 default:
463 // The only valid thread resume states are listed above
464 llvm_unreachable("invalid thread resume state");
465 }
466 }
467
468 if (resume) {
469 LLDB_LOGF(log, "ProcessKDP::DoResume () sending resume");
470
471 if (m_comm.SendRequestResume()) {
474 } else
475 return Status::FromErrorString("KDP resume failed");
476 } else {
477 return Status::FromErrorString("kernel thread is suspended");
478 }
479
480 return error;
481}
482
484 // KDP only tells us about one thread/core. Any other threads will usually
485 // be the ones that are read from memory by the OS plug-ins.
486
487 ThreadSP thread_sp(m_kernel_thread_wp.lock());
488 if (!thread_sp) {
489 thread_sp = std::make_shared<ThreadKDP>(*this, g_kernel_tid);
490 m_kernel_thread_wp = thread_sp;
491 }
492 return thread_sp;
493}
494
496 ThreadList &new_thread_list) {
497 // locker will keep a mutex locked until it goes out of scope
498 Log *log = GetLog(KDPLog::Thread);
499 LLDB_LOG_VERBOSE(log, "pid = {0}", GetID());
500
501 // Even though there is a CPU mask, it doesn't mean we can see each CPU
502 // individually, there is really only one. Lets call this thread 1.
503 ThreadSP thread_sp(
504 old_thread_list.FindThreadByProtocolID(g_kernel_tid, false));
505 if (!thread_sp)
506 thread_sp = GetKernelThread();
507 new_thread_list.AddThread(thread_sp);
508
509 return new_thread_list.GetSize(false) > 0;
510}
511
513 // Let all threads recover from stopping and do any clean up based on the
514 // previous thread state (if any).
515 m_thread_list.RefreshStateAfterStop();
516}
517
518Status ProcessKDP::DoHalt(bool &caused_stop) {
520
521 if (m_comm.IsRunning()) {
523 // If we are attempting to destroy, we need to not return an error to Halt
524 // or DoDestroy won't get called. We are also currently running, so send
525 // a process stopped event
527 } else {
528 return Status::FromErrorString("KDP cannot interrupt a running kernel");
529 }
530 }
531 return error;
532}
533
534Status ProcessKDP::DoDetach(bool keep_stopped) {
536 Log *log = GetLog(KDPLog::Process);
537 LLDB_LOGF(log, "ProcessKDP::DoDetach(keep_stopped = %i)", keep_stopped);
538
539 if (m_comm.IsRunning()) {
540 // We are running and we can't interrupt a running kernel, so we need to
541 // just close the connection to the kernel and hope for the best
542 } else {
543 // If we are going to keep the target stopped, then don't send the
544 // disconnect message.
545 if (!keep_stopped && m_comm.IsConnected()) {
546 const bool success = m_comm.SendRequestDisconnect();
547 if (log) {
548 if (success)
549 log->PutCString(
550 "ProcessKDP::DoDetach() detach packet sent successfully");
551 else
552 log->PutCString(
553 "ProcessKDP::DoDetach() connection channel shutdown failed");
554 }
555 m_comm.Disconnect();
556 }
557 }
559 m_comm.Clear();
560
563
564 // KillDebugserverProcess ();
565 return error;
566}
567
569 // For KDP there really is no difference between destroy and detach
570 bool keep_stopped = false;
571 return DoDetach(keep_stopped);
572}
573
574// Process Queries
575
577 return m_comm.IsConnected() && Process::IsAlive();
578}
579
580// Process Memory
581size_t ProcessKDP::DoReadMemory(const ProcessAddress &process_addr, void *buf,
582 size_t size, Status &error) {
583 lldb::addr_t addr = process_addr.GetValue();
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;
588
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;
594 }
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;
601 }
602 }
603
604 return total_bytes_read;
605 }
606 error = Status::FromErrorString("not connected");
607 return 0;
608}
609
610size_t ProcessKDP::DoWriteMemory(addr_t addr, const void *buf, size_t size,
611 Status &error) {
612 if (m_comm.IsConnected())
613 return m_comm.SendRequestWriteMemory(addr, buf, size, error);
614 error = Status::FromErrorString("not connected");
615 return 0;
616}
617
618lldb::addr_t ProcessKDP::DoAllocateMemory(size_t size, uint32_t permissions,
619 Status &error) {
621 "memory allocation not supported in kdp remote debugging");
623}
624
628 "memory deallocation not supported in kdp remote debugging");
629 return error;
630}
631
633 if (bp_site->HardwareRequired())
634 return Status::FromErrorString("Hardware breakpoints are not supported.");
635
636 if (m_comm.LocalBreakpointsAreSupported()) {
638 if (!IsBreakpointSitePhysicallyEnabled(*bp_site)) {
639 if (m_comm.SendRequestBreakpoint(true, bp_site->GetLoadAddress())) {
640 SetBreakpointSiteEnabled(*bp_site);
642 } else {
643 return Status::FromErrorString("KDP set breakpoint failed");
644 }
645 }
646 return error;
647 }
648 return EnableSoftwareBreakpoint(bp_site);
649}
650
652 if (m_comm.LocalBreakpointsAreSupported()) {
654 if (IsBreakpointSitePhysicallyEnabled(*bp_site)) {
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 SetBreakpointSiteEnabled(*bp_site, false);
660 } else {
661 if (m_comm.SendRequestBreakpoint(false, bp_site->GetLoadAddress()))
662 SetBreakpointSiteEnabled(*bp_site, false);
663 else
664 return Status::FromErrorString("KDP remove breakpoint failed");
665 }
666 } else {
668 }
669 }
670 return error;
671 }
672 return DisableSoftwareBreakpoint(bp_site);
673}
674
676
680 "sending signals is not supported in kdp remote debugging");
681 return error;
682}
683
691
694 debugger, PluginProperties::GetSettingName())) {
695 const bool is_global_setting = true;
698 "Properties for the kdp-remote process plug-in.", is_global_setting);
699 }
700}
701
703 Log *log = GetLog(KDPLog::Process);
704
705 LLDB_LOGF(log, "ProcessKDP::StartAsyncThread ()");
706
707 if (m_async_thread.IsJoinable())
708 return true;
709
710 llvm::Expected<HostThread> async_thread = ThreadLauncher::LaunchThread(
711 "<lldb.process.kdp-remote.async>", [this] { return AsyncThread(); });
712 if (!async_thread) {
713 LLDB_LOG_ERROR(GetLog(LLDBLog::Host), async_thread.takeError(),
714 "failed to launch host thread: {0}");
715 return false;
716 }
717 m_async_thread = *async_thread;
718 return m_async_thread.IsJoinable();
719}
720
722 Log *log = GetLog(KDPLog::Process);
723
724 LLDB_LOGF(log, "ProcessKDP::StopAsyncThread ()");
725
727
728 // Stop the stdio thread
729 if (m_async_thread.IsJoinable())
730 m_async_thread.Join(nullptr);
731}
732
734 const lldb::pid_t pid = GetID();
735
736 Log *log = GetLog(KDPLog::Process);
737 LLDB_LOGF(log,
738 "ProcessKDP::AsyncThread(pid = %" PRIu64 ") thread starting...",
739 pid);
740
741 ListenerSP listener_sp(Listener::MakeListener("ProcessKDP::AsyncThread"));
742 EventSP event_sp;
743 const uint32_t desired_event_mask =
745
746 if (listener_sp->StartListeningForEvents(
747 &m_async_broadcaster, desired_event_mask) == desired_event_mask) {
748 bool done = false;
749 while (!done) {
750 LLDB_LOGF(log,
751 "ProcessKDP::AsyncThread (pid = %" PRIu64
752 ") listener.WaitForEvent (NULL, event_sp)...",
753 pid);
754 if (listener_sp->GetEvent(event_sp, std::nullopt)) {
755 uint32_t event_type = event_sp->GetType();
756 LLDB_LOGF(log,
757 "ProcessKDP::AsyncThread (pid = %" PRIu64
758 ") Got an event of type: %d...",
759 pid, event_type);
760
761 // When we are running, poll for 1 second to try and get an exception
762 // to indicate the process has stopped. If we don't get one, check to
763 // make sure no one asked us to exit
764 bool is_running = false;
765 DataExtractor exc_reply_packet;
766 do {
767 switch (event_type) {
769 is_running = true;
770 if (m_comm.WaitForPacketWithTimeoutMicroSeconds(
771 exc_reply_packet, 1 * USEC_PER_SEC)) {
772 ThreadSP thread_sp(GetKernelThread());
773 if (thread_sp) {
774 lldb::RegisterContextSP reg_ctx_sp(
775 thread_sp->GetRegisterContext());
776 if (reg_ctx_sp)
777 reg_ctx_sp->InvalidateAllRegisters();
778 static_cast<ThreadKDP *>(thread_sp.get())
779 ->SetStopInfoFrom_KDP_EXCEPTION(exc_reply_packet);
780 }
781
782 // TODO: parse the stop reply packet
783 is_running = false;
785 } else {
786 // Check to see if we are supposed to exit. There is no way to
787 // interrupt a running kernel, so all we can do is wait for an
788 // exception or detach...
789 if (listener_sp->GetEvent(event_sp,
790 std::chrono::microseconds(0))) {
791 // We got an event, go through the loop again
792 event_type = event_sp->GetType();
793 }
794 }
795 } break;
796
798 LLDB_LOGF(log,
799 "ProcessKDP::AsyncThread (pid = %" PRIu64
800 ") got eBroadcastBitAsyncThreadShouldExit...",
801 pid);
802 done = true;
803 is_running = false;
804 break;
805
806 default:
807 LLDB_LOGF(log,
808 "ProcessKDP::AsyncThread (pid = %" PRIu64
809 ") got unknown event 0x%8.8x",
810 pid, event_type);
811 done = true;
812 is_running = false;
813 break;
814 }
815 } while (is_running);
816 } else {
817 LLDB_LOGF(log,
818 "ProcessKDP::AsyncThread (pid = %" PRIu64
819 ") listener.WaitForEvent (NULL, event_sp) => false",
820 pid);
821 done = true;
822 }
823 }
824 }
825
826 LLDB_LOGF(log, "ProcessKDP::AsyncThread(pid = %" PRIu64 ") thread exiting...",
827 pid);
828
829 m_async_thread.Reset();
830 return NULL;
831}
832
834private:
838
839 Options *GetOptions() override { return &m_option_group; }
840
841public:
843 : CommandObjectParsed(interpreter, "process plugin packet send",
844 "Send a custom packet through the KDP protocol by "
845 "specifying the command byte and the packet "
846 "payload data. A packet will be sent with a "
847 "correct header and payload, and the raw result "
848 "bytes will be displayed as a string value. ",
849 NULL),
851 m_command_byte(LLDB_OPT_SET_1, true, "command", 'c', 0, eArgTypeNone,
852 "Specify the command byte to use when sending the KDP "
853 "request packet.",
854 0),
855 m_packet_data(LLDB_OPT_SET_1, false, "payload", 'p', 0, eArgTypeNone,
856 "Specify packet payload bytes as a hex ASCII string with "
857 "no spaces or hex prefixes.",
858 NULL) {
861 m_option_group.Finalize();
862 }
863
865
866 void DoExecute(Args &command, CommandReturnObject &result) override {
867 if (!m_command_byte.GetOptionValue().OptionWasSet()) {
868 result.AppendError(
869 "the --command option must be set to a valid command byte");
870 } else {
871 const uint64_t command_byte =
872 m_command_byte.GetOptionValue().GetValueAs<uint64_t>().value_or(0);
873 if (command_byte > 0 && command_byte <= UINT8_MAX) {
874 ProcessKDP *process =
875 (ProcessKDP *)m_interpreter.GetExecutionContext().GetProcessPtr();
876 if (process) {
877 const StateType state = process->GetState();
878
879 if (StateIsStoppedState(state, true)) {
880 std::vector<uint8_t> payload_bytes;
881 const char *ascii_hex_bytes_cstr =
882 m_packet_data.GetOptionValue().GetCurrentValue();
883 if (ascii_hex_bytes_cstr && ascii_hex_bytes_cstr[0]) {
884 StringExtractor extractor(ascii_hex_bytes_cstr);
885 const size_t ascii_hex_bytes_cstr_len =
886 extractor.GetStringRef().size();
887 if (ascii_hex_bytes_cstr_len & 1) {
888 result.AppendErrorWithFormat("payload data must contain an "
889 "even number of ASCII hex "
890 "characters: '%s'",
891 ascii_hex_bytes_cstr);
892 return;
893 }
894 payload_bytes.resize(ascii_hex_bytes_cstr_len / 2);
895 if (extractor.GetHexBytes(payload_bytes, '\xdd') !=
896 payload_bytes.size()) {
897 result.AppendErrorWithFormat("payload data must only contain "
898 "ASCII hex characters (no "
899 "spaces or hex prefixes): '%s'",
900 ascii_hex_bytes_cstr);
901 return;
902 }
903 }
905 DataExtractor reply;
907 command_byte,
908 payload_bytes.empty() ? NULL : payload_bytes.data(),
909 payload_bytes.size(), reply, error);
910
911 if (error.Success()) {
912 // Copy the binary bytes into a hex ASCII string for the result
913 StreamString packet;
914 packet.PutBytesAsRawHex8(
915 reply.GetDataStart(), reply.GetByteSize(),
917 result.AppendMessage(packet.GetString());
919 return;
920 } else {
921 const char *error_cstr = error.AsCString();
922 if (error_cstr && error_cstr[0])
923 result.AppendError(error_cstr);
924 else
925 result.AppendErrorWithFormat("unknown error 0x%8.8x",
926 error.GetError());
927 return;
928 }
929 } else {
930 result.AppendErrorWithFormat("process must be stopped in order "
931 "to send KDP packets, state is %s",
932 StateAsCString(state));
933 }
934 } else {
935 result.AppendError("invalid process");
936 }
937 } else {
938 result.AppendErrorWithFormat("invalid command byte 0x%" PRIx64
939 ", valid values are 1 - 255",
940 command_byte);
941 }
942 }
943 }
944};
945
947private:
948public:
950 : CommandObjectMultiword(interpreter, "process plugin packet",
951 "Commands that deal with KDP remote packets.",
952 NULL) {
954 "send",
956 }
957
958 ~CommandObjectProcessKDPPacket() override = default;
959};
960
962public:
965 interpreter, "process plugin",
966 "Commands for operating on a ProcessKDP process.",
967 "process plugin <subcommand> [<subcommand-options>]") {
969 interpreter)));
970 }
971
973};
974
976 if (!m_command_sp)
977 m_command_sp = std::make_shared<CommandObjectMultiwordProcessKDP>(
978 GetTarget().GetDebugger().GetCommandInterpreter());
979 return m_command_sp.get();
980}
static llvm::raw_ostream & error(Stream &strm)
static PluginProperties & GetGlobalPluginProperties()
#define LLDB_LOGF(log,...)
Definition Log.h:389
#define LLDB_LOG_ERROR(log, error,...)
Definition Log.h:405
#define LLDB_LOG_VERBOSE(log,...)
Definition Log.h:382
#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
size_t DoReadMemory(const lldb_private::ProcessAddress &addr, void *buf, size_t size, lldb_private::Status &error) override
Actually do the reading of memory from a process.
llvm::StringRef GetPluginName() override
Definition ProcessKDP.h:88
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:732
llvm::Triple & GetTriple()
Architecture triple accessor.
Definition ArchSpec.h:545
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.
void MergeFrom(const ArchSpec &other)
Merges fields from another ArchSpec into this ArchSpec.
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 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 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:100
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:56
static FileSystem & Instance()
static lldb::ListenerSP MakeListener(llvm::StringRef name)
Definition Listener.cpp:373
void PutCString(const char *cstr)
Definition Log.cpp:162
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:91
virtual ObjectFile * GetObjectFile()
Get the object file representation for the current architecture.
Definition Module.cpp:1179
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)
An address in a process, qualified by an address space.
lldb::addr_t GetValue() const
virtual Status DisableSoftwareBreakpoint(BreakpointSite *bp_site)
Definition Process.cpp:1982
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:552
ThreadList & GetThreadList()
Definition Process.h:2367
Process(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp)
Construct with a shared pointer to a target, and the Process listener.
Definition Process.cpp:485
void ResumePrivateStateThread()
Definition Process.cpp:4194
void SetBreakpointSiteEnabled(BreakpointSite &site, bool is_enabled=true)
Definition Process.h:3709
void SetCanJIT(bool can_jit)
Sets whether executing JIT-compiled code in this process is possible.
Definition Process.cpp:2769
lldb::DynamicLoaderUP m_dyld_up
Definition Process.h:3511
bool IsBreakpointSitePhysicallyEnabled(const BreakpointSite &site)
Definition Process.cpp:1709
void UpdateThreadListIfNeeded()
Definition Process.cpp:1163
lldb::StateType GetState()
Get accessor for the current process state.
Definition Process.cpp:1315
virtual Status EnableSoftwareBreakpoint(BreakpointSite *bp_site)
Definition Process.cpp:1902
virtual bool IsAlive()
Check if a process is still alive.
Definition Process.cpp:1138
virtual void DidAttach(ArchSpec &process_arch)
Called after attaching a process.
Definition Process.h:1030
void SetID(lldb::pid_t new_pid)
Sets the stored pid.
Definition Process.h:557
friend class Target
Definition Process.h:374
void SetPrivateState(lldb::StateType state)
Definition Process.cpp:1444
virtual void Finalize(bool destructing)
This object is about to be destroyed, do any necessary cleanup.
Definition Process.cpp:596
ThreadList m_thread_list
The threads for this process as the user will see them.
Definition Process.h:3481
friend class ThreadList
Definition Process.h:375
Target & GetTarget()
Get the target object pointer for this module.
Definition Process.h:1267
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:1356
bool SetArchitecture(const ArchSpec &arch_spec, bool set_platform=false, bool merge=true)
Set the architecture for this target.
Definition Target.cpp:1807
lldb::ModuleSP GetExecutableModule()
Gets the module for the main executable.
Definition Target.cpp:1630
static FileSpecList GetDefaultDebugFileSearchPaths()
Definition Target.cpp:2925
const ArchSpec & GetArchitecture() const
Definition Target.h:1315
void RebuildModuleListWithExecutable(lldb::ModuleSP &module_sp, LoadDependentFiles load_dependent_files=eLoadDependentsDefault)
Clear the module list and rebuild it around a new main executable.
Definition Target.cpp:1673
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:338
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:84
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:85
std::shared_ptr< lldb_private::Module > ModuleSP