Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
92348b2
[lldb][Mach-O] Allow "process metadata" LC_NOTE to supply registers
jasonmolenda Jun 18, 2025
6f57048
remove debug print
jasonmolenda Jun 18, 2025
1ddbda4
appease clang format
jasonmolenda Jun 18, 2025
ce289ab
Update lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
jasonmolenda Jun 25, 2025
1c8819d
ws fix
jasonmolenda Jun 25, 2025
0721824
Update lldb/source/Plugins/Process/mach-core/RegisterContextUnifiedCo…
jasonmolenda Jun 25, 2025
3a0a555
Update lldb/source/Plugins/Process/mach-core/RegisterContextUnifiedCo…
jasonmolenda Jun 25, 2025
89317d8
Update lldb/source/Plugins/Process/mach-core/RegisterContextUnifiedCo…
jasonmolenda Jun 25, 2025
7c2bfc6
Update lldb/source/Plugins/Process/mach-core/RegisterContextUnifiedCo…
jasonmolenda Jun 25, 2025
dbc414b
Merge branch 'main' into lc_note-metadata-register-additions
jasonmolenda Jun 25, 2025
2a41c88
Add two tests with invalid process metadata in the corefile.
jasonmolenda Jun 25, 2025
eecd470
Check that the per-thread JSON is a dictionary
jasonmolenda Jun 26, 2025
3c69582
Do a pass over RegisterContextUnifiedCore::RegisterContextUnifiedCore
jasonmolenda Jun 26, 2025
be740fe
Update lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
jasonmolenda Jun 27, 2025
cae9dac
Update lldb/source/Plugins/Process/mach-core/RegisterContextUnifiedCo…
jasonmolenda Jun 27, 2025
eac8d49
Update lldb/source/Plugins/Process/mach-core/ThreadMachCore.cpp
jasonmolenda Jun 27, 2025
cdd6f1d
Update lldb/source/Plugins/Process/mach-core/RegisterContextUnifiedCo…
jasonmolenda Jun 27, 2025
c29ffe6
reflow comment
jasonmolenda Jun 27, 2025
8213628
Update lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h
jasonmolenda Jun 27, 2025
6da9489
Take another pass at the comments where the
jasonmolenda Jun 28, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 15 additions & 2 deletions lldb/include/lldb/Symbol/ObjectFile.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "lldb/Utility/Endian.h"
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/FileSpecList.h"
#include "lldb/Utility/StructuredData.h"
#include "lldb/Utility/UUID.h"
#include "lldb/lldb-private.h"
#include "llvm/Support/Threading.h"
Expand Down Expand Up @@ -544,9 +545,9 @@ class ObjectFile : public std::enable_shared_from_this<ObjectFile>,
return false;
}

/// Get metadata about threads from the corefile.
/// Get metadata about thread ids from the corefile.
///
/// The corefile may have metadata (e.g. a Mach-O "thread extrainfo"
/// The corefile may have metadata (e.g. a Mach-O "process metadata"
/// LC_NOTE) which for the threads in the process; this method tries
/// to retrieve them.
///
Expand All @@ -568,6 +569,18 @@ class ObjectFile : public std::enable_shared_from_this<ObjectFile>,
return false;
}

/// Get process metadata from the corefile in a StructuredData dictionary.
///
/// The corefile may have notes (e.g. a Mach-O "process metadata" LC_NOTE)
/// which provide metadata about the process and threads in a JSON or
/// similar format.
///
/// \return
/// A StructuredData object with the metadata in the note, if there is
/// one. An empty shared pointer is returned if not metadata is found,
/// or a problem parsing it.
virtual StructuredData::ObjectSP GetCorefileProcessMetadata() { return {}; }

virtual lldb::RegisterContextSP
GetThreadContextAtIndex(uint32_t idx, lldb_private::Thread &thread) {
return lldb::RegisterContextSP();
Expand Down
64 changes: 44 additions & 20 deletions lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5794,27 +5794,8 @@ bool ObjectFileMachO::GetCorefileThreadExtraInfos(
std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());

Log *log(GetLog(LLDBLog::Object | LLDBLog::Process | LLDBLog::Thread));
auto lc_notes = FindLC_NOTEByName("process metadata");
for (auto lc_note : lc_notes) {
offset_t payload_offset = std::get<0>(lc_note);
offset_t strsize = std::get<1>(lc_note);
std::string buf(strsize, '\0');
if (m_data.CopyData(payload_offset, strsize, buf.data()) != strsize) {
LLDB_LOGF(log,
"Unable to read %" PRIu64
" bytes of 'process metadata' LC_NOTE JSON contents",
strsize);
return false;
}
while (buf.back() == '\0')
buf.resize(buf.size() - 1);
StructuredData::ObjectSP object_sp = StructuredData::ParseJSON(buf);
if (StructuredData::ObjectSP object_sp = GetCorefileProcessMetadata()) {
StructuredData::Dictionary *dict = object_sp->GetAsDictionary();
if (!dict) {
LLDB_LOGF(log, "Unable to read 'process metadata' LC_NOTE, did not "
"get a dictionary.");
return false;
}
StructuredData::Array *threads;
if (!dict->GetValueForKeyAsArray("threads", threads) || !threads) {
LLDB_LOGF(log,
Expand Down Expand Up @@ -5857,6 +5838,49 @@ bool ObjectFileMachO::GetCorefileThreadExtraInfos(
return false;
}

StructuredData::ObjectSP ObjectFileMachO::GetCorefileProcessMetadata() {
ModuleSP module_sp(GetModule());
if (!module_sp)
return {};

Log *log(GetLog(LLDBLog::Object | LLDBLog::Process | LLDBLog::Thread));
std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
auto lc_notes = FindLC_NOTEByName("process metadata");
if (lc_notes.size() == 0)
return {};

if (lc_notes.size() > 1)
LLDB_LOGF(
log,
"Multiple 'process metadata' LC_NOTEs found, only using the first.");

auto [payload_offset, strsize] = lc_notes[0];
std::string buf(strsize, '\0');
if (m_data.CopyData(payload_offset, strsize, buf.data()) != strsize) {
LLDB_LOGF(log,
"Unable to read %" PRIu64
" bytes of 'process metadata' LC_NOTE JSON contents",
strsize);
return {};
}
while (buf.back() == '\0')
buf.resize(buf.size() - 1);
StructuredData::ObjectSP object_sp = StructuredData::ParseJSON(buf);
if (!object_sp) {
LLDB_LOGF(log, "Unable to read 'process metadata' LC_NOTE, did not "
"parse as valid JSON.");
Comment on lines +5870 to +5871
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need to change anything, but another way to handle this is to make this function return an Expected<StructuredData::ObjectSP> and do the logging on the caller side. The advantage of that is that if you can do better than logging, it's easy to percolate the error up, while now it never leaves the function.

return {};
}
StructuredData::Dictionary *dict = object_sp->GetAsDictionary();
if (!dict) {
LLDB_LOGF(log, "Unable to read 'process metadata' LC_NOTE, did not "
"get a dictionary.");
return {};
}

return object_sp;
}

lldb::RegisterContextSP
ObjectFileMachO::GetThreadContextAtIndex(uint32_t idx,
lldb_private::Thread &thread) {
Expand Down
2 changes: 2 additions & 0 deletions lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,8 @@ class ObjectFileMachO : public lldb_private::ObjectFile {

bool GetCorefileThreadExtraInfos(std::vector<lldb::tid_t> &tids) override;

lldb_private::StructuredData::ObjectSP GetCorefileProcessMetadata() override;

bool LoadCoreFileImages(lldb_private::Process &process) override;

lldb::RegisterContextSP
Expand Down
1 change: 1 addition & 0 deletions lldb/source/Plugins/Process/mach-core/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
add_lldb_library(lldbPluginProcessMachCore PLUGIN
ProcessMachCore.cpp
ThreadMachCore.cpp
RegisterContextUnifiedCore.cpp

LINK_COMPONENTS
Support
Expand Down
Loading
Loading