[lldb][Process/FreeBSDKernel] Print unread message buffer on start#178027
[lldb][Process/FreeBSDKernel] Print unread message buffer on start#178027
Conversation
|
Thank you for submitting a Pull Request (PR) to the LLVM Project! This PR will be automatically labeled and the relevant teams will be notified. If you wish to, you can add reviewers by using the "Reviewers" section on this page. If this is not working for you, it is probably because you do not have write permissions for the repository. In which case you can instead tag reviewers by name in a comment by using If you have received no comments on your PR for a week, you can request a review by "ping"ing the PR by adding a comment “Ping”. The common courtesy "ping" rate is once a week. Please remember that you are asking for valuable time from other developers. If you have further questions, they may be answered by the LLVM GitHub User Guide. You can also ask questions in a comment on this PR, on the LLVM Discord or on the forums. |
|
@llvm/pr-subscribers-lldb Author: Minsoo Choo (mchoo7) ChangesThis is equivalent of kgdb_dmesg() in fbsd-kvm.c in FreeBSD kgdb(1) port. Crash info isn't printed in batch mode. Full diff: https://github.com/llvm/llvm-project/pull/178027.diff 2 Files Affected:
diff --git a/lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.cpp b/lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.cpp
index d209e5b5384f3..8a9fc0231a927 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"
@@ -247,6 +250,8 @@ bool ProcessFreeBSDKernel::DoUpdateThreadList(ThreadList &old_thread_list,
new_thread_list.AddThread(thread_sp);
}
}
+
+ ShowCrashInfo();
} else {
const uint32_t num_threads = old_thread_list.GetSize(false);
for (uint32_t i = 0; i < num_threads; ++i)
@@ -273,6 +278,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 - this is a pointer to struct msgbuf
+ lldb::addr_t msgbufp_addr = FindSymbol("msgbufp");
+ if (msgbufp_addr == LLDB_INVALID_ADDRESS)
+ return;
+
+ // Read the pointer value (msgbufp is a pointer variable)
+ 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;
+
+ // Get the debugger's async output 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 06c9d062441e5..ba9e7f929ad43 100644
--- a/lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.h
+++ b/lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.h
@@ -49,6 +49,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
|
|
I think I need some time to take a look at how FreeBSD's coredump work on this. |
|
Honestly I'm not sure if |
873feb6 to
9d93dd3
Compare
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@proton.me>
|
I guess this is the best I can: |
Other RefreshStateAfterStop end up calling something on a thread list, so RefreshStateAfterStop does make more sense I think. |
lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.cpp
Outdated
Show resolved
Hide resolved
lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.cpp
Outdated
Show resolved
Hide resolved
lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.cpp
Outdated
Show resolved
Hide resolved
Signed-off-by: Minsoo Choo <minsoochoo0122@proton.me>
This needs to be implemented - or you can decide not to do it. Since @aokblast said they would look at this, let's see what they say and wait for them to review. |
Line 293 implements this and I tested it with On the other hand, it makes more sense create a dedicated setting (e.g. |
DavidSpickett
left a comment
There was a problem hiding this comment.
I don't care whether the message is printed all the time or not, but the code and documentation need to be consistent with whatever you choose to do.
lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.h
Outdated
Show resolved
Hide resolved
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
6d8dbfb to
2553882
Compare
Signed-off-by: Minsoo Choo <minsoochoo0122@proton.me>
DavidSpickett
left a comment
There was a problem hiding this comment.
LGTM
I see @aokblast commented a few weeks ago. Leave this open for a few days, in case they still want to do so.
🐧 Linux x64 Test Results
✅ The build succeeded and all tests passed. |
lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.cpp
Outdated
Show resolved
Hide resolved
Signed-off-by: Minsoo Choo <minsoochoo0122@proton.me>
|
@mchoo7 Congratulations on having your first Pull Request (PR) merged into the LLVM Project! Your changes will be combined with recent changes from other authors, then tested by our build bots. If there is a problem with a build, you may receive a report in an email or a comment on this PR. Please check whether problems have been caused by your change specifically, as the builds can include changes from many authors. It is not uncommon for your change to be included in a build that fails due to someone else's changes, or infrastructure issues. How to do this, and the rest of the post-merge process, is covered in detail here. If your change does cause a problem, it may be reverted, or you can revert it yourself. This is a normal part of LLVM development. You can fix your changes and open a new PR to merge them again. If you don't get any reports, no action is required from you. Your changes are working as expected, well done! |
) `debugger.GetCommandInterpreter().IsInteractive()` doesn't necessarily mean that the debugger is running without `-b` or `--batch` flag. This caused an issue where the message isn't printed in any case. Remove the check so the message is always printed for now. Fixes: 9d9c7fc (#178027) Signed-off-by: Minsoo Choo <minsoochoo0122@proton.me>
…#187981) `debugger.GetCommandInterpreter().IsInteractive()` doesn't necessarily mean that the debugger is running without `-b` or `--batch` flag. This caused an issue where the message isn't printed in any case. Remove the check so the message is always printed for now. Fixes: 9d9c7fc (llvm#178027) Signed-off-by: Minsoo Choo <minsoochoo0122@proton.me>
This is equivalent of kgdb_dmesg() in fbsd-kvm.c in FreeBSD kgdb(1) port. Unread kernel messages is only printed in interactive mode (i.e. not in batch mode) to mimic KGDB's behaviour.
Example output: