29#define LLDB_PROPERTIES_processfreebsdkernelcore
30#include "ProcessFreeBSDKernelCoreProperties.inc"
33#define LLDB_PROPERTIES_processfreebsdkernelcore
34#include "ProcessFreeBSDKernelCorePropertiesEnum.inc"
39 static llvm::StringRef GetSettingName() {
43 PluginProperties() : Properties() {
44 m_collection_sp = std::make_shared<OptionValueProperties>(GetSettingName());
45 m_collection_sp->Initialize(g_processfreebsdkernelcore_properties_def);
48 ~PluginProperties()
override =
default;
50 bool GetReadOnly()
const {
51 const uint32_t idx = ePropertyReadOnly;
52 return GetPropertyAtIndexAs<bool>(idx,
true);
59 static PluginProperties g_settings;
76 const FileSpec *crash_file,
bool can_connect) {
77 ModuleSP executable = target_sp->GetExecutableModule();
78 if (crash_file && !can_connect && executable) {
80 kvm_open2(executable->GetFileSpec().GetPath().c_str(),
81 crash_file->
GetPath().c_str(), O_RDONLY,
nullptr,
nullptr);
83 return std::make_shared<ProcessFreeBSDKernelCore>(target_sp, listener_sp,
90 static llvm::once_flag g_once_flag;
92 llvm::call_once(g_once_flag, []() {
101 debugger, PluginProperties::GetSettingName())) {
102 const bool is_global_setting =
true;
105 "Properties for the freebsd-kernel process plug-in.",
115 bool plugin_specified_by_name) {
141 const void *buf,
size_t size,
145 "Memory writes are disabled in read-only mode. Disable with 'settings "
146 "set plugin.process.freebsd-kernel-core.read-only false'");
151 rd = kvm_write(
m_kvm, addr, buf, size);
152 if (rd < 0 ||
static_cast<size_t>(rd) != size) {
155 return rd > 0 ? rd : 0;
162 if (old_thread_list.
GetSize(
false) == 0) {
169 switch (
GetTarget().GetArchitecture().GetMachine()) {
170 case llvm::Triple::aarch64:
171 case llvm::Triple::x86:
172 case llvm::Triple::x86_64:
184 int32_t offset_p_pid =
203 if (offset_p_list == -1 || offset_p_pid == -1 || offset_p_threads == -1 ||
204 offset_p_comm == -1 || offset_td_tid == -1 || offset_td_plist == -1 ||
205 offset_td_pcb == -1 || offset_td_oncpu == -1 || offset_td_name == -1)
221 constexpr size_t fbsd_maxcomlen = 19;
227 std::vector<lldb::addr_t> process_addrs;
232 process_addrs.push_back(proc);
237 for (
auto proc_it = process_addrs.rbegin(); proc_it != process_addrs.rend();
243 char comm[fbsd_maxcomlen + 1];
260 char thread_name[fbsd_maxcomlen + 1];
262 sizeof(thread_name),
error);
268 std::string thread_desc = llvm::formatv(
"(pid {0}) {1}", pid, comm);
269 if (*thread_name && strcmp(thread_name, comm)) {
271 thread_desc += thread_name;
278 if (tid == dumptid) {
281 thread_desc +=
" (crashed)";
282 }
else if (oncpu != -1) {
286 pcb_addr = stoppcbs + oncpu * pcbsize;
289 thread_desc += llvm::formatv(
" (on CPU {0})", oncpu);
296 thread->SetIsCrashedThread(
true);
302 const uint32_t num_threads = old_thread_list.
GetSize(
false);
303 for (uint32_t i = 0; i < num_threads; ++i)
306 return new_thread_list.
GetSize(
false) > 0;
312 rd = kvm_read2(
m_kvm, addr, buf, size);
313 if (rd < 0 ||
static_cast<size_t>(rd) != size) {
316 return rd > 0 ? rd : 0;
351 uint64_t offset_msg_ptr = 0;
352 uint64_t offset_msg_size = 0;
353 uint64_t offset_msg_wseq = 0;
354 uint64_t offset_msg_rseq = 0;
363 for (uint32_t i = 0; i < num_fields; i++) {
364 std::string field_name;
365 uint64_t field_offset = 0;
370 if (field_name ==
"msg_ptr") {
371 offset_msg_ptr = field_offset / 8;
373 }
else if (field_name ==
"msg_size") {
374 offset_msg_size = field_offset / 8;
376 }
else if (field_name ==
"msg_wseq") {
377 offset_msg_wseq = field_offset / 8;
379 }
else if (field_name ==
"msg_rseq") {
380 offset_msg_rseq = field_offset / 8;
385 if (field_found != 4) {
388 "FreeBSD-Kernel-Core: Could not find all required fields for msgbuf");
401 offset_msg_size = ptr_size + 4;
402 offset_msg_wseq = ptr_size + 8;
403 offset_msg_rseq = ptr_size + 12;
413 if (!
error.Success() || size == 0)
418 if (!
error.Success())
423 if (!
error.Success())
428 uint32_t rseq_pos = rseq % size;
429 uint32_t wseq_pos = wseq % size;
431 if (rseq_pos == wseq_pos)
439 stream_sp->PutCString(
"\nUnread portion of the kernel message buffer:\n");
442 if (rseq_pos < wseq_pos) {
444 size_t len = wseq_pos - rseq_pos;
445 std::string buf(len,
'\0');
447 if (
error.Success() && bytes_read > 0) {
448 buf.resize(bytes_read);
453 size_t len1 = size - rseq_pos;
454 std::string buf1(len1,
'\0');
455 size_t bytes_read1 =
ReadMemory(bufp + rseq_pos, &buf1[0], len1,
error);
456 if (
error.Success() && bytes_read1 > 0) {
457 buf1.resize(bytes_read1);
462 std::string buf2(wseq_pos,
'\0');
464 if (
error.Success() && bytes_read2 > 0) {
465 buf2.resize(bytes_read2);
471 stream_sp->PutChar(
'\n');
static llvm::raw_ostream & error(Stream &strm)
static PluginProperties & GetGlobalPluginProperties()
#define LLDB_LOGF(log,...)
#define LLDB_PLUGIN_DEFINE(PluginName)
static PluginProperties & GetGlobalPluginProperties()
static llvm::StringRef GetPluginNameStatic()
lldb_private::Status DoDestroy() override
static llvm::StringRef GetPluginNameStatic()
void PrintUnreadMessage()
lldb::addr_t FindSymbol(const char *name)
~ProcessFreeBSDKernelCore()
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.
static lldb::ProcessSP CreateInstance(lldb::TargetSP target_sp, lldb::ListenerSP listener, const lldb_private::FileSpec *crash_file_path, bool can_connect)
void RefreshStateAfterStop() override
Currently called as part of ShouldStop.
static void DebuggerInitialize(lldb_private::Debugger &debugger)
static llvm::StringRef GetPluginDescriptionStatic()
lldb_private::Status DoLoadCore() override
lldb_private::DynamicLoader * GetDynamicLoader() override
Get the dynamic loader plug-in for this process.
ProcessFreeBSDKernelCore(lldb::TargetSP target_sp, lldb::ListenerSP listener, kvm_t *kvm, const lldb_private::FileSpec &core_file)
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 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.
bool m_printed_unread_message
bool CanDebug(lldb::TargetSP target_sp, bool plugin_specified_by_name) override
Check if a plug-in instance can debug the file in module.
Generic representation of a type in a programming language.
CompilerType GetFieldAtIndex(size_t idx, std::string &name, uint64_t *bit_offset_ptr, uint32_t *bitfield_bit_size_ptr, bool *is_bitfield_ptr) const
uint32_t GetNumFields() const
A uniqued constant string class.
CommandInterpreter & GetCommandInterpreter()
lldb::StreamUP GetAsyncOutputStream()
static DynamicLoader * FindPlugin(Process *process, llvm::StringRef plugin_name)
Find a dynamic loader plugin for a given process.
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
void FindTypes(Module *search_first, const TypeQuery &query, lldb_private::TypeResults &results) const
Find types using a type-matching object that contains all search parameters.
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 lldb::OptionValuePropertiesSP GetSettingForProcessPlugin(Debugger &debugger, llvm::StringRef setting_name)
static bool UnregisterPlugin(ABICreateInstance create_callback)
PostMortemProcess(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp, const FileSpec &core_file)
int64_t ReadSignedIntegerFromMemory(lldb::addr_t load_addr, size_t byte_size, int64_t fail_value, Status &error)
size_t ReadCStringFromMemory(lldb::addr_t vm_addr, char *cstr, size_t cstr_max_len, Status &error)
Read a NULL terminated C string from memory.
lldb::DynamicLoaderUP m_dyld_up
virtual size_t ReadMemory(lldb::addr_t vm_addr, void *buf, size_t size, Status &error)
Read of memory from a process.
uint64_t ReadUnsignedIntegerFromMemory(lldb::addr_t load_addr, size_t byte_size, uint64_t fail_value, Status &error)
Reads an unsigned integer of the specified byte size from process memory.
lldb::addr_t ReadPointerFromMemory(lldb::addr_t vm_addr, Status &error)
uint32_t GetAddressByteSize() const
friend class DynamicLoader
Target & GetTarget()
Get the target object pointer for this module.
lldb::OptionValuePropertiesSP GetValueProperties() const
static Status FromErrorStringWithFormat(const char *format,...) __attribute__((format(printf
static Status FromErrorString(const char *str)
lldb::addr_t GetLoadAddress(Target *target) const
Debugger & GetDebugger() const
lldb::ModuleSP GetExecutableModule()
Gets the module for the main executable.
const ModuleList & GetImages() const
Get accessor for the images for this process.
void AddThread(const lldb::ThreadSP &thread_sp)
uint32_t GetSize(bool can_update=true)
lldb::ThreadSP GetThreadAtIndex(uint32_t idx, bool can_update=true)
lldb::TypeSP GetTypeAtIndex(uint32_t idx)
A class that contains all state required for type lookups.
This class tracks the state and results of a TypeQuery.
#define LLDB_INVALID_ADDRESS
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.
std::shared_ptr< lldb_private::Thread > ThreadSP
std::shared_ptr< lldb_private::Stream > StreamSP
std::shared_ptr< lldb_private::Process > ProcessSP
std::shared_ptr< lldb_private::Listener > ListenerSP
std::shared_ptr< lldb_private::Target > TargetSP
std::shared_ptr< lldb_private::Module > ModuleSP