summaryrefslogtreecommitdiff
path: root/lldb/source
diff options
context:
space:
mode:
authorJason Molenda <jason@molenda.com>2021-08-11 13:37:31 -0700
committerJason Molenda <jason@molenda.com>2021-08-11 13:37:31 -0700
commit8c31efeed6007bade1e4ddda2ceccab311661cbc (patch)
tree377dbb83efe5a2daef75ec6fb11c1454edd352cf /lldb/source
parent7f3c3d7aa491ddd761ba821519ef795c90292947 (diff)
Add the ability to process save-core stack-memory-only corefiles
Add a field to the qMemoryRegionInfo packet where the remote stub can describe the type of memory -- heap, stack. Keep track of memory regions that are stack memory in lldb. Add a new "--style stack" to process save-core to request that only stack memory be included in the corefile. Differential Revision: https://reviews.llvm.org/D107625
Diffstat (limited to 'lldb/source')
-rw-r--r--lldb/source/Commands/CommandObjectProcess.cpp13
-rw-r--r--lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp52
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp13
3 files changed, 57 insertions, 21 deletions
diff --git a/lldb/source/Commands/CommandObjectProcess.cpp b/lldb/source/Commands/CommandObjectProcess.cpp
index 1a8ed021b9f0..c65b661f9cfc 100644
--- a/lldb/source/Commands/CommandObjectProcess.cpp
+++ b/lldb/source/Commands/CommandObjectProcess.cpp
@@ -1166,7 +1166,9 @@ protected:
static constexpr OptionEnumValueElement g_corefile_save_style[] = {
{eSaveCoreFull, "full", "Create a core file with all memory saved"},
{eSaveCoreDirtyOnly, "modified-memory",
- "Create a corefile with only modified memory saved"}};
+ "Create a corefile with only modified memory saved"},
+ {eSaveCoreStackOnly, "stack",
+ "Create a corefile with only stack memory saved"}};
static constexpr OptionEnumValues SaveCoreStyles() {
return OptionEnumValues(g_corefile_save_style);
@@ -1237,11 +1239,12 @@ protected:
Status error =
PluginManager::SaveCore(process_sp, output_file, corefile_style);
if (error.Success()) {
- if (corefile_style == SaveCoreStyle::eSaveCoreDirtyOnly) {
+ if (corefile_style == SaveCoreStyle::eSaveCoreDirtyOnly ||
+ corefile_style == SaveCoreStyle::eSaveCoreStackOnly) {
result.AppendMessageWithFormat(
- "\nModified-memory only corefile "
- "created. This corefile may not show \n"
- "library/framework/app binaries "
+ "\nModified-memory or stack-memory only corefile "
+ "created. This corefile may \n"
+ "not show library/framework/app binaries "
"on a different system, or when \n"
"those binaries have "
"been updated/modified. Copies are not included\n"
diff --git a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
index ce5324943171..decccc494bc0 100644
--- a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
+++ b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
@@ -6342,13 +6342,17 @@ struct segment_vmaddr {
// are some multiple passes over the image list while calculating
// everything.
-static offset_t
-CreateAllImageInfosPayload(const lldb::ProcessSP &process_sp,
- offset_t initial_file_offset,
- StreamString &all_image_infos_payload) {
+static offset_t CreateAllImageInfosPayload(
+ const lldb::ProcessSP &process_sp, offset_t initial_file_offset,
+ StreamString &all_image_infos_payload, SaveCoreStyle core_style) {
Target &target = process_sp->GetTarget();
- const ModuleList &modules = target.GetImages();
- size_t modules_count = modules.GetSize();
+ ModuleList modules = target.GetImages();
+
+ // stack-only corefiles have no reason to include binaries that
+ // are not executing; we're trying to make the smallest corefile
+ // we can, so leave the rest out.
+ if (core_style == SaveCoreStyle::eSaveCoreStackOnly)
+ modules.Clear();
std::set<std::string> executing_uuids;
ThreadList &thread_list(process_sp->GetThreadList());
@@ -6363,10 +6367,12 @@ CreateAllImageInfosPayload(const lldb::ProcessSP &process_sp,
UUID uuid = module_sp->GetUUID();
if (uuid.IsValid()) {
executing_uuids.insert(uuid.GetAsString());
+ modules.AppendIfNeeded(module_sp);
}
}
}
}
+ size_t modules_count = modules.GetSize();
struct all_image_infos_header infos;
infos.version = 1;
@@ -6508,12 +6514,9 @@ bool ObjectFileMachO::SaveCore(const lldb::ProcessSP &process_sp,
if (!process_sp)
return false;
- // For Mach-O, we can only create full corefiles or dirty-page-only
- // corefiles. The default is dirty-page-only.
- if (core_style != SaveCoreStyle::eSaveCoreFull) {
+ // Default on macOS is to create a dirty-memory-only corefile.
+ if (core_style == SaveCoreStyle::eSaveCoreUnspecified) {
core_style = SaveCoreStyle::eSaveCoreDirtyOnly;
- } else {
- core_style = SaveCoreStyle::eSaveCoreFull;
}
Target &target = process_sp->GetTarget();
@@ -6568,13 +6571,23 @@ bool ObjectFileMachO::SaveCore(const lldb::ProcessSP &process_sp,
if (size == 0)
break;
- if (prot != 0) {
+ bool include_this_region = true;
+ bool dirty_pages_only = false;
+ if (core_style == SaveCoreStyle::eSaveCoreStackOnly) {
+ dirty_pages_only = true;
+ if (range_info.IsStackMemory() != MemoryRegionInfo::eYes) {
+ include_this_region = false;
+ }
+ }
+ if (core_style == SaveCoreStyle::eSaveCoreDirtyOnly) {
+ dirty_pages_only = true;
+ }
+
+ if (prot != 0 && include_this_region) {
addr_t pagesize = range_info.GetPageSize();
const llvm::Optional<std::vector<addr_t>> &dirty_page_list =
range_info.GetDirtyPageList();
- if (core_style == SaveCoreStyle::eSaveCoreDirtyOnly &&
- dirty_page_list.hasValue()) {
- core_style = SaveCoreStyle::eSaveCoreDirtyOnly;
+ if (dirty_pages_only && dirty_page_list.hasValue()) {
for (addr_t dirtypage : dirty_page_list.getValue()) {
page_object obj;
obj.addr = dirtypage;
@@ -6617,6 +6630,12 @@ bool ObjectFileMachO::SaveCore(const lldb::ProcessSP &process_sp,
last_obj = obj;
}
+ // If we only ended up with one contiguous memory segment
+ if (combined_page_objects.size() == 0 &&
+ last_obj.addr != LLDB_INVALID_ADDRESS) {
+ combined_page_objects.push_back(last_obj);
+ }
+
for (page_object obj : combined_page_objects) {
uint32_t cmd_type = LC_SEGMENT_64;
uint32_t segment_size = sizeof(llvm::MachO::segment_command_64);
@@ -6767,7 +6786,8 @@ bool ObjectFileMachO::SaveCore(const lldb::ProcessSP &process_sp,
all_image_infos_lcnote_up->name = "all image infos";
all_image_infos_lcnote_up->payload_file_offset = file_offset;
file_offset = CreateAllImageInfosPayload(
- process_sp, file_offset, all_image_infos_lcnote_up->payload);
+ process_sp, file_offset, all_image_infos_lcnote_up->payload,
+ core_style);
lc_notes.push_back(std::move(all_image_infos_lcnote_up));
// Add LC_NOTE load commands
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
index ee8c7c66573d..e898a08641dc 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
@@ -1572,6 +1572,19 @@ Status GDBRemoteCommunicationClient::GetMemoryRegionInfo(
}
}
}
+ } else if (name.equals("type")) {
+ std::string comma_sep_str = value.str();
+ size_t comma_pos;
+ while ((comma_pos = comma_sep_str.find(',')) != std::string::npos) {
+ comma_sep_str[comma_pos] = '\0';
+ if (comma_sep_str == "stack") {
+ region_info.SetIsStackMemory(MemoryRegionInfo::eYes);
+ }
+ }
+ // handle final (or only) type of "stack"
+ if (comma_sep_str == "stack") {
+ region_info.SetIsStackMemory(MemoryRegionInfo::eYes);
+ }
} else if (name.equals("error")) {
StringExtractorGDBRemote error_extractor(value);
std::string error_string;