================
@@ -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);
----------------
DavidSpickett wrote:

Why do we do this one byte at a time?

>From what I gather, this message buffer tells us the size of each message, so 
>we can we just try to read the whole message at once?

Maybe I am missing a corner case here.

https://github.com/llvm/llvm-project/pull/178027
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to