https://github.com/mchoo7 updated https://github.com/llvm/llvm-project/pull/178027
>From 9d93dd3f8b4dd4428d11cc141defcb4916fa420d Mon Sep 17 00:00:00 2001 From: Minsoo Choo <[email protected]> Date: Sun, 25 Jan 2026 22:00:47 -0500 Subject: [PATCH] [lldb] [Process/FreeBSDKernel] Show crash info on start This is equivalent of kgdb_dmesg() in fbsd-kvm.c in FreeBSD kgdb(1) port. Crash info isn't printed in batch mode. Signed-off-by: Minsoo Choo <[email protected]> --- .../FreeBSDKernel/ProcessFreeBSDKernel.cpp | 124 ++++++++++++++++++ .../FreeBSDKernel/ProcessFreeBSDKernel.h | 5 + 2 files changed, 129 insertions(+) diff --git a/lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.cpp b/lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.cpp index c7da9f215972f..17bfc29d103a7 100644 --- a/lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.cpp +++ b/lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.cpp @@ -6,9 +6,12 @@ // //===----------------------------------------------------------------------===// +#include "lldb/Core/Debugger.h" #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" +#include "lldb/Symbol/Type.h" #include "lldb/Target/DynamicLoader.h" +#include "lldb/Utility/StreamString.h" #include "Plugins/DynamicLoader/FreeBSD-Kernel/DynamicLoaderFreeBSDKernel.h" #include "ProcessFreeBSDKernel.h" @@ -111,6 +114,12 @@ void ProcessFreeBSDKernel::Terminate() { PluginManager::UnregisterPlugin(ProcessFreeBSDKernel::CreateInstance); } +void ProcessFreeBSDKernel::DidAttach(ArchSpec &process_arch) { + Process::DidAttach(process_arch); + + ShowCrashInfo(); +} + Status ProcessFreeBSDKernel::DoDestroy() { return Status(); } bool ProcessFreeBSDKernel::CanDebug(lldb::TargetSP target_sp, @@ -277,6 +286,121 @@ lldb::addr_t ProcessFreeBSDKernel::FindSymbol(const char *name) { return sym ? sym->GetLoadAddress(&GetTarget()) : LLDB_INVALID_ADDRESS; } +void ProcessFreeBSDKernel::ShowCrashInfo() { + Status error; + + // Find msgbufp symbol (pointer to message buffer) + lldb::addr_t msgbufp_addr = FindSymbol("msgbufp"); + if (msgbufp_addr == LLDB_INVALID_ADDRESS) + return; + + // Read the pointer value + lldb::addr_t msgbufp = ReadPointerFromMemory(msgbufp_addr, error); + if (!error.Success() || msgbufp == LLDB_INVALID_ADDRESS) + return; + + // Get the type information for struct msgbuf from DWARF + TypeQuery query("msgbuf"); + TypeResults results; + GetTarget().GetImages().FindTypes(nullptr, query, results); + + uint64_t offset_msg_ptr = 0; + uint64_t offset_msg_size = 0; + uint64_t offset_msg_wseq = 0; + uint64_t offset_msg_rseq = 0; + + if (results.GetTypeMap().GetSize() > 0) { + // Found type info - use it to get field offsets + CompilerType msgbuf_type = + results.GetTypeMap().GetTypeAtIndex(0)->GetForwardCompilerType(); + + uint32_t num_fields = msgbuf_type.GetNumFields(); + for (uint32_t i = 0; i < num_fields; i++) { + std::string field_name; + uint64_t field_offset = 0; + uint32_t field_bitfield_bit_size = 0; + bool field_is_bitfield = false; + + msgbuf_type.GetFieldAtIndex(i, field_name, &field_offset, + &field_bitfield_bit_size, &field_is_bitfield); + + if (field_name == "msg_ptr") + offset_msg_ptr = field_offset / 8; // Convert bits to bytes + else if (field_name == "msg_size") + offset_msg_size = field_offset / 8; + else if (field_name == "msg_wseq") + offset_msg_wseq = field_offset / 8; + else if (field_name == "msg_rseq") + offset_msg_rseq = field_offset / 8; + } + } else { + // Fallback: use hardcoded offsets based on struct layout + // struct msgbuf layout (from sys/sys/msgbuf.h): + // char *msg_ptr; - offset 0 + // u_int msg_magic; - offset ptr_size + // u_int msg_size; - offset ptr_size + 4 + // u_int msg_wseq; - offset ptr_size + 8 + // u_int msg_rseq; - offset ptr_size + 12 + uint32_t ptr_size = GetAddressByteSize(); + offset_msg_ptr = 0; + offset_msg_size = ptr_size + 4; + offset_msg_wseq = ptr_size + 8; + offset_msg_rseq = ptr_size + 12; + } + + // Read struct msgbuf fields + lldb::addr_t bufp = ReadPointerFromMemory(msgbufp + offset_msg_ptr, error); + if (!error.Success() || bufp == LLDB_INVALID_ADDRESS) + return; + + uint32_t size = + ReadUnsignedIntegerFromMemory(msgbufp + offset_msg_size, 4, 0, error); + if (!error.Success() || size == 0) + return; + + uint32_t wseq = + ReadUnsignedIntegerFromMemory(msgbufp + offset_msg_wseq, 4, 0, error); + if (!error.Success()) + return; + + uint32_t rseq = + ReadUnsignedIntegerFromMemory(msgbufp + offset_msg_rseq, 4, 0, error); + if (!error.Success()) + return; + + // Convert sequences to positions + // MSGBUF_SEQ_TO_POS macro in FreeBSD: ((seq) % (size)) + uint32_t rseq_pos = rseq % size; + uint32_t wseq_pos = wseq % size; + + if (rseq_pos == wseq_pos) + return; + + // Print crash info at once using stream + lldb::StreamSP stream_sp = GetTarget().GetDebugger().GetAsyncOutputStream(); + if (!stream_sp) + return; + + stream_sp->Printf("\nUnread portion of the kernel message buffer:\n"); + + uint8_t c = 0; + while (rseq_pos != wseq_pos) { + size_t bytes_read = ReadMemory(bufp + rseq_pos, &c, 1, error); + if (!error.Success() || bytes_read != 1) + break; + + stream_sp->PutChar(c); + rseq_pos++; + if (rseq_pos >= size) + rseq_pos = 0; + } + + if (c != '\n') + stream_sp->PutChar('\n'); + stream_sp->PutChar('\n'); + stream_sp->Flush(); +} + #if LLDB_ENABLE_FBSDVMCORE ProcessFreeBSDKernelFVC::ProcessFreeBSDKernelFVC(lldb::TargetSP target_sp, diff --git a/lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.h b/lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.h index 81c567581dd56..73d49d723ee14 100644 --- a/lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.h +++ b/lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.h @@ -33,6 +33,8 @@ class ProcessFreeBSDKernel : public lldb_private::PostMortemProcess { llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } + void DidAttach(lldb_private::ArchSpec &process_arch) override; + lldb_private::Status DoDestroy() override; bool CanDebug(lldb::TargetSP target_sp, @@ -49,6 +51,9 @@ class ProcessFreeBSDKernel : public lldb_private::PostMortemProcess { lldb_private::ThreadList &new_thread_list) override; lldb::addr_t FindSymbol(const char *name); + +private: + void ShowCrashInfo(); }; #endif // LLDB_SOURCE_PLUGINS_PROCESS_FREEBSDKERNEL_PROCESSFREEBSDKERNEL_H _______________________________________________ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
