[lldb] [llvm] [lldb][Process/FreeBSDKernel] Print unread message buffer on start (PR #178027)

Minsoo Choo via llvm-commits llvm-commits at lists.llvm.org
Thu Feb 19 04:48:52 PST 2026


https://github.com/mchoo7 updated https://github.com/llvm/llvm-project/pull/178027

>From 9986846bb72373e70b181effbd3cb5d7d58825cb Mon Sep 17 00:00:00 2001
From: Minsoo Choo <minsoochoo0122 at proton.me>
Date: Sun, 25 Jan 2026 22:00:47 -0500
Subject: [PATCH 1/6] [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 <minsoochoo0122 at proton.me>
---
 .../FreeBSDKernel/ProcessFreeBSDKernel.cpp    | 125 +++++++++++++++++-
 .../FreeBSDKernel/ProcessFreeBSDKernel.h      |   5 +
 2 files changed, 129 insertions(+), 1 deletion(-)

diff --git a/lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.cpp b/lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.cpp
index c7da9f215972f..3dbeb736562e2 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"
@@ -118,7 +121,12 @@ bool ProcessFreeBSDKernel::CanDebug(lldb::TargetSP target_sp,
   return true;
 }
 
-void ProcessFreeBSDKernel::RefreshStateAfterStop() {}
+void ProcessFreeBSDKernel::RefreshStateAfterStop() {
+  if (!m_displayed_crash_info) {
+    ShowCrashInfo();
+    m_displayed_crash_info = true;
+  }
+}
 
 bool ProcessFreeBSDKernel::DoUpdateThreadList(ThreadList &old_thread_list,
                                               ThreadList &new_thread_list) {
@@ -277,6 +285,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..7a17dd67f68c5 100644
--- a/lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.h
+++ b/lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.h
@@ -49,6 +49,11 @@ class ProcessFreeBSDKernel : public lldb_private::PostMortemProcess {
                           lldb_private::ThreadList &new_thread_list) override;
 
   lldb::addr_t FindSymbol(const char *name);
+
+private:
+  void ShowCrashInfo();
+
+  bool m_displayed_crash_info = false;
 };
 
 #endif // LLDB_SOURCE_PLUGINS_PROCESS_FREEBSDKERNEL_PROCESSFREEBSDKERNEL_H

>From d96782c5636ff30617c094ef8c3c2b23791a0d01 Mon Sep 17 00:00:00 2001
From: Minsoo Choo <minsoochoo0122 at proton.me>
Date: Wed, 4 Feb 2026 10:06:17 -0500
Subject: [PATCH 2/6] fixup! [lldb] [Process/FreeBSDKernel] Show crash info on
 start

Signed-off-by: Minsoo Choo <minsoochoo0122 at proton.me>
---
 .../FreeBSDKernel/ProcessFreeBSDKernel.cpp    | 53 +++++++++++++------
 1 file changed, 38 insertions(+), 15 deletions(-)

diff --git a/lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.cpp b/lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.cpp
index 3dbeb736562e2..375eeb3d68852 100644
--- a/lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.cpp
+++ b/lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.cpp
@@ -9,6 +9,7 @@
 #include "lldb/Core/Debugger.h"
 #include "lldb/Core/Module.h"
 #include "lldb/Core/PluginManager.h"
+#include "lldb/Interpreter/CommandInterpreter.h"
 #include "lldb/Symbol/Type.h"
 #include "lldb/Target/DynamicLoader.h"
 #include "lldb/Utility/StreamString.h"
@@ -286,6 +287,12 @@ lldb::addr_t ProcessFreeBSDKernel::FindSymbol(const char *name) {
 }
 
 void ProcessFreeBSDKernel::ShowCrashInfo() {
+  Target &target = GetTarget();
+  Debugger &debugger = target.GetDebugger();
+
+  if (!debugger.GetCommandInterpreter().IsInteractive())
+    return;
+
   Status error;
 
   // Find msgbufp symbol (pointer to message buffer)
@@ -301,7 +308,7 @@ void ProcessFreeBSDKernel::ShowCrashInfo() {
   // Get the type information for struct msgbuf from DWARF
   TypeQuery query("msgbuf");
   TypeResults results;
-  GetTarget().GetImages().FindTypes(nullptr, query, results);
+  target.GetImages().FindTypes(nullptr, query, results);
 
   uint64_t offset_msg_ptr = 0;
   uint64_t offset_msg_size = 0;
@@ -376,26 +383,42 @@ void ProcessFreeBSDKernel::ShowCrashInfo() {
     return;
 
   // Print crash info at once using stream
-  lldb::StreamSP stream_sp = GetTarget().GetDebugger().GetAsyncOutputStream();
+  lldb::StreamSP stream_sp = debugger.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->PutCString("\nUnread portion of the kernel message buffer:\n");
+
+  // Read ring buffer in at most two chunks
+  if (rseq_pos < wseq_pos) {
+    // No wrap: read from rseq_pos to wseq_pos
+    size_t len = wseq_pos - rseq_pos;
+    std::string buf(len, '\0');
+    size_t bytes_read = ReadMemory(bufp + rseq_pos, &buf[0], len, error);
+    if (error.Success() && bytes_read > 0) {
+      buf.resize(bytes_read);
+      *stream_sp << buf;
+    }
+  } else {
+    // Wrap around: read from rseq_pos to end, then from start to wseq_pos
+    size_t len1 = size - rseq_pos;
+    std::string buf1(len1, '\0');
+    size_t bytes_read1 = ReadMemory(bufp + rseq_pos, &buf1[0], len1, error);
+    if (error.Success() && bytes_read1 > 0) {
+      buf1.resize(bytes_read1);
+      *stream_sp << buf1;
+    }
 
-    stream_sp->PutChar(c);
-    rseq_pos++;
-    if (rseq_pos >= size)
-      rseq_pos = 0;
+    if (wseq_pos > 0) {
+      std::string buf2(wseq_pos, '\0');
+      size_t bytes_read2 = ReadMemory(bufp, &buf2[0], wseq_pos, error);
+      if (error.Success() && bytes_read2 > 0) {
+        buf2.resize(bytes_read2);
+        *stream_sp << buf2;
+      }
+    }
   }
 
-  if (c != '\n')
-    stream_sp->PutChar('\n');
   stream_sp->PutChar('\n');
   stream_sp->Flush();
 }

>From 793e17cf81958ec6b7a33d643949c37a24ce3416 Mon Sep 17 00:00:00 2001
From: Minsoo Choo <minsoochoo0122 at proton.me>
Date: Tue, 10 Feb 2026 09:17:31 -0500
Subject: [PATCH 3/6] fixup! [lldb] [Process/FreeBSDKernel] Show crash info on
 start

Signed-off-by: Minsoo Choo <minsoochoo0122 at proton.me>
---
 .../FreeBSDKernel/ProcessFreeBSDKernel.cpp    | 22 +++++++++++++++----
 1 file changed, 18 insertions(+), 4 deletions(-)

diff --git a/lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.cpp b/lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.cpp
index 375eeb3d68852..6b685b6f5ae64 100644
--- a/lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.cpp
+++ b/lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.cpp
@@ -12,6 +12,8 @@
 #include "lldb/Interpreter/CommandInterpreter.h"
 #include "lldb/Symbol/Type.h"
 #include "lldb/Target/DynamicLoader.h"
+#include "lldb/Utility/LLDBLog.h"
+#include "lldb/Utility/Log.h"
 #include "lldb/Utility/StreamString.h"
 
 #include "Plugins/DynamicLoader/FreeBSD-Kernel/DynamicLoaderFreeBSDKernel.h"
@@ -321,6 +323,7 @@ void ProcessFreeBSDKernel::ShowCrashInfo() {
         results.GetTypeMap().GetTypeAtIndex(0)->GetForwardCompilerType();
 
     uint32_t num_fields = msgbuf_type.GetNumFields();
+    int field_found = 0;
     for (uint32_t i = 0; i < num_fields; i++) {
       std::string field_name;
       uint64_t field_offset = 0;
@@ -330,14 +333,25 @@ void ProcessFreeBSDKernel::ShowCrashInfo() {
       msgbuf_type.GetFieldAtIndex(i, field_name, &field_offset,
                                   &field_bitfield_bit_size, &field_is_bitfield);
 
-      if (field_name == "msg_ptr")
+      if (field_name == "msg_ptr") {
         offset_msg_ptr = field_offset / 8; // Convert bits to bytes
-      else if (field_name == "msg_size")
+        field_found++;
+      } else if (field_name == "msg_size") {
         offset_msg_size = field_offset / 8;
-      else if (field_name == "msg_wseq")
+        field_found++;
+      } else if (field_name == "msg_wseq") {
         offset_msg_wseq = field_offset / 8;
-      else if (field_name == "msg_rseq")
+        field_found++;
+      } else if (field_name == "msg_rseq") {
         offset_msg_rseq = field_offset / 8;
+        field_found++;
+      }
+    }
+
+    if (field_found != 4) {
+      LLDB_LOGF(GetLog(LLDBLog::Object),
+                "FreeBSDKernel: Could not find all required fields for msgbuf");
+      return;
     }
   } else {
     // Fallback: use hardcoded offsets based on struct layout

>From 66713a4c62fd58019a35ff6cfbceabcb658f2301 Mon Sep 17 00:00:00 2001
From: Minsoo Choo <minsoochoo0122 at proton.me>
Date: Thu, 12 Feb 2026 10:09:48 -0500
Subject: [PATCH 4/6] Update relnotes

Signed-off-by: Minsoo Choo <minsoochoo0122 at proton.me>
---
 llvm/docs/ReleaseNotes.md | 1 +
 1 file changed, 1 insertion(+)

diff --git a/llvm/docs/ReleaseNotes.md b/llvm/docs/ReleaseNotes.md
index 257d962ba8941..080801d4e31da 100644
--- a/llvm/docs/ReleaseNotes.md
+++ b/llvm/docs/ReleaseNotes.md
@@ -194,6 +194,7 @@ Changes to LLDB
 
 * The crashed thread is now automatically selected on start.
 * Threads are listed in incrmental order by pid then by tid.
+* Message saved in msgbufp is now printed on start.
 
 Changes to BOLT
 ---------------

>From cec43548d8d563188e61892fb90a090e7bd6826c Mon Sep 17 00:00:00 2001
From: Minsoo Choo <minsoochoo0122 at proton.me>
Date: Wed, 18 Feb 2026 15:32:58 -0500
Subject: [PATCH 5/6] fixup! [lldb] [Process/FreeBSDKernel] Show crash info on
 start

Signed-off-by: Minsoo Choo <minsoochoo0122 at proton.me>
---
 .../Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.cpp    | 4 ++--
 .../Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.h      | 2 +-
 llvm/docs/ReleaseNotes.md                                     | 2 +-
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.cpp b/lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.cpp
index dac9eb03d2d90..1eb67d7153aed 100644
--- a/lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.cpp
+++ b/lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.cpp
@@ -126,7 +126,7 @@ bool ProcessFreeBSDKernel::CanDebug(lldb::TargetSP target_sp,
 
 void ProcessFreeBSDKernel::RefreshStateAfterStop() {
   if (!m_displayed_crash_info) {
-    ShowCrashInfo();
+    PrintUnreadMessageBuffer();
     m_displayed_crash_info = true;
   }
 }
@@ -298,7 +298,7 @@ lldb::addr_t ProcessFreeBSDKernel::FindSymbol(const char *name) {
   return sym ? sym->GetLoadAddress(&GetTarget()) : LLDB_INVALID_ADDRESS;
 }
 
-void ProcessFreeBSDKernel::ShowCrashInfo() {
+void ProcessFreeBSDKernel::PrintUnreadMessageBuffer() {
   Target &target = GetTarget();
   Debugger &debugger = target.GetDebugger();
 
diff --git a/lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.h b/lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.h
index 7a17dd67f68c5..7c6f73fc82caa 100644
--- a/lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.h
+++ b/lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.h
@@ -51,7 +51,7 @@ class ProcessFreeBSDKernel : public lldb_private::PostMortemProcess {
   lldb::addr_t FindSymbol(const char *name);
 
 private:
-  void ShowCrashInfo();
+  void PrintUnreadMessageBuffer();
 
   bool m_displayed_crash_info = false;
 };
diff --git a/llvm/docs/ReleaseNotes.md b/llvm/docs/ReleaseNotes.md
index f9bf1846ebdcb..1ce9f225ab52e 100644
--- a/llvm/docs/ReleaseNotes.md
+++ b/llvm/docs/ReleaseNotes.md
@@ -201,7 +201,7 @@ Changes to LLDB
 
 * The crashed thread is now automatically selected on start.
 * Threads are listed in incrmental order by pid then by tid.
-* Message saved in msgbufp is now printed on start.
+* Unread kernel message saved in msgbufp is now printed on start.
 
 Changes to BOLT
 ---------------

>From 8e84a4a1ab73e559c659092ed23aa44392f42d77 Mon Sep 17 00:00:00 2001
From: Minsoo Choo <minsoochoo0122 at proton.me>
Date: Thu, 19 Feb 2026 06:45:23 -0500
Subject: [PATCH 6/6] fixup! [lldb] [Process/FreeBSDKernel] Show crash info on
 start

Signed-off-by: Minsoo Choo <minsoochoo0122 at proton.me>
---
 .../Process/FreeBSDKernel/CMakeLists.txt      | 12 ++++
 .../FreeBSDKernel/ProcessFreeBSDKernel.cpp    | 61 ++++++++++++++++---
 .../FreeBSDKernel/ProcessFreeBSDKernel.h      |  6 +-
 .../ProcessFreeBSDKernelProperties.td         |  8 +++
 llvm/docs/ReleaseNotes.md                     |  3 +-
 5 files changed, 77 insertions(+), 13 deletions(-)
 create mode 100644 lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernelProperties.td

diff --git a/lldb/source/Plugins/Process/FreeBSDKernel/CMakeLists.txt b/lldb/source/Plugins/Process/FreeBSDKernel/CMakeLists.txt
index c35b4def24e25..604e5d2dddd99 100644
--- a/lldb/source/Plugins/Process/FreeBSDKernel/CMakeLists.txt
+++ b/lldb/source/Plugins/Process/FreeBSDKernel/CMakeLists.txt
@@ -1,3 +1,11 @@
+lldb_tablegen(ProcessFreeBSDKernelProperties.inc -gen-lldb-property-defs
+  SOURCE ProcessFreeBSDKernelProperties.td
+  TARGET LLDBPluginProcessFreeBSDKernelPropertiesGen)
+
+lldb_tablegen(ProcessFreeBSDKernelPropertiesEnum.inc -gen-lldb-property-enum-defs
+  SOURCE ProcessFreeBSDKernelProperties.td
+  TARGET LLDBPluginProcessFreeBSDKernelPropertiesEnumGen)
+
 set(FBSDKERNEL_LIBS)
 if(FBSDVMCore_FOUND)
   list(APPEND FBSDKERNEL_LIBS fbsdvmcore)
@@ -25,3 +33,7 @@ add_lldb_library(lldbPluginProcessFreeBSDKernel PLUGIN
     lldbTarget
     ${FBSDKERNEL_LIBS}
   )
+
+add_dependencies(lldbPluginProcessFreeBSDKernel
+  LLDBPluginProcessFreeBSDKernelPropertiesGen
+  LLDBPluginProcessFreeBSDKernelPropertiesEnumGen)
diff --git a/lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.cpp b/lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.cpp
index 1eb67d7153aed..7c28b5c1315da 100644
--- a/lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.cpp
+++ b/lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.cpp
@@ -72,6 +72,37 @@ class ProcessFreeBSDKernelKVM : public ProcessFreeBSDKernel {
 
 } // namespace
 
+/// Code to handle the ProcessFreeBSDKernel settings
+
+#define LLDB_PROPERTIES_processfreebsdkernel
+#include "ProcessFreeBSDKernelProperties.inc"
+
+enum {
+#define LLDB_PROPERTIES_processfreebsdkernel
+#include "ProcessFreeBSDKernelPropertiesEnum.inc"
+};
+
+class PluginProperties : public Properties {
+public:
+  static llvm::StringRef GetSettingName() {
+    return ProcessFreeBSDKernel::GetPluginNameStatic();
+  }
+
+  PluginProperties() override = default;
+
+  ~ProcessFreeBSDKernelProperties() override = default;
+
+  bool GetPrintUnreadMessage() const {
+    const uint32_t idx = ePropertyPrintUnreadMessage;
+    return GetPropertyAtIndexAs<bool>(idx, true);
+  }
+};
+
+static PluginProperties &GetGlobalPluginProperties() {
+  static PluginProperties g_settings;
+  return g_settings;
+}
+
 ProcessFreeBSDKernel::ProcessFreeBSDKernel(lldb::TargetSP target_sp,
                                            ListenerSP listener_sp,
                                            const FileSpec &core_file)
@@ -109,10 +140,22 @@ void ProcessFreeBSDKernel::Initialize() {
 
   llvm::call_once(g_once_flag, []() {
     PluginManager::RegisterPlugin(GetPluginNameStatic(),
-                                  GetPluginDescriptionStatic(), CreateInstance);
+                                  GetPluginDescriptionStatic(), CreateInstance,
+                                  DebuggerInitialize);
   });
 }
 
+void ProcessFreeBSDKernel::DebuggerInitialize(Debugger &debugger) {
+  if (!PluginManager::GetSettingForProcessPlugin(
+          debugger, ProcessFreeBSDKernelProperties::GetSettingName())) {
+    const bool is_global_setting = true;
+    PluginManager::CreateSettingForProcessPlugin(
+        debugger, GetGlobalFreeBSDKernelProperties().GetValueProperties(),
+        "Properties for the FreeBSD kernel process plug-in.",
+        is_global_setting);
+  }
+}
+
 void ProcessFreeBSDKernel::Terminate() {
   PluginManager::UnregisterPlugin(ProcessFreeBSDKernel::CreateInstance);
 }
@@ -125,9 +168,9 @@ bool ProcessFreeBSDKernel::CanDebug(lldb::TargetSP target_sp,
 }
 
 void ProcessFreeBSDKernel::RefreshStateAfterStop() {
-  if (!m_displayed_crash_info) {
-    PrintUnreadMessageBuffer();
-    m_displayed_crash_info = true;
+  if (!m_printed_unread_message) {
+    PrintUnreadMessage();
+    m_printed_unread_message = true;
   }
 }
 
@@ -298,11 +341,8 @@ lldb::addr_t ProcessFreeBSDKernel::FindSymbol(const char *name) {
   return sym ? sym->GetLoadAddress(&GetTarget()) : LLDB_INVALID_ADDRESS;
 }
 
-void ProcessFreeBSDKernel::PrintUnreadMessageBuffer() {
-  Target &target = GetTarget();
-  Debugger &debugger = target.GetDebugger();
-
-  if (!debugger.GetCommandInterpreter().IsInteractive())
+void ProcessFreeBSDKernel::PrintUnreadMessage() {
+  if (!GetGlobalPluginProperties().GetPrintUnreadMessage())
     return;
 
   Status error;
@@ -320,6 +360,7 @@ void ProcessFreeBSDKernel::PrintUnreadMessageBuffer() {
   // Get the type information for struct msgbuf from DWARF
   TypeQuery query("msgbuf");
   TypeResults results;
+  Target &target = GetTarget();
   target.GetImages().FindTypes(nullptr, query, results);
 
   uint64_t offset_msg_ptr = 0;
@@ -407,7 +448,7 @@ void ProcessFreeBSDKernel::PrintUnreadMessageBuffer() {
     return;
 
   // Print crash info at once using stream
-  lldb::StreamSP stream_sp = debugger.GetAsyncOutputStream();
+  lldb::StreamSP stream_sp = target.GetDebugger().GetAsyncOutputStream();
   if (!stream_sp)
     return;
 
diff --git a/lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.h b/lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.h
index 7c6f73fc82caa..b2d77f3b789a0 100644
--- a/lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.h
+++ b/lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.h
@@ -23,6 +23,8 @@ class ProcessFreeBSDKernel : public lldb_private::PostMortemProcess {
 
   static void Initialize();
 
+  static void DebuggerInitialize(lldb_private::Debugger &debugger);
+
   static void Terminate();
 
   static llvm::StringRef GetPluginNameStatic() { return "freebsd-kernel"; }
@@ -51,9 +53,9 @@ class ProcessFreeBSDKernel : public lldb_private::PostMortemProcess {
   lldb::addr_t FindSymbol(const char *name);
 
 private:
-  void PrintUnreadMessageBuffer();
+  void PrintUnreadMessage();
 
-  bool m_displayed_crash_info = false;
+  bool m_printed_unread_message = false;
 };
 
 #endif // LLDB_SOURCE_PLUGINS_PROCESS_FREEBSDKERNEL_PROCESSFREEBSDKERNEL_H
diff --git a/lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernelProperties.td b/lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernelProperties.td
new file mode 100644
index 0000000000000..7313943e7c564
--- /dev/null
+++ b/lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernelProperties.td
@@ -0,0 +1,8 @@
+include "../../../../include/lldb/Core/PropertiesBase.td"
+
+let Definition = "processfreebsdkernel", Path = "plugin.process.freebsd-kernel" in {
+  def PrintUnreadMessage: Property<"print-unread-message", "Boolean">,
+    Global,
+    DefaultTrue,
+    Desc<"Print unread kernel message on start. Enabled by default.">;
+}
diff --git a/llvm/docs/ReleaseNotes.md b/llvm/docs/ReleaseNotes.md
index 1ce9f225ab52e..2981837620f51 100644
--- a/llvm/docs/ReleaseNotes.md
+++ b/llvm/docs/ReleaseNotes.md
@@ -201,7 +201,8 @@ Changes to LLDB
 
 * The crashed thread is now automatically selected on start.
 * Threads are listed in incrmental order by pid then by tid.
-* Unread kernel message saved in msgbufp is now printed on start.
+* Unread kernel messages saved in msgbufp are now printed when lldb starts. This information is printed only
+  when `plugin.process.freebsd-kernel.print-unread-message` is set to true.
 
 Changes to BOLT
 ---------------



More information about the llvm-commits mailing list