aboutsummaryrefslogtreecommitdiff
path: root/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp
diff options
context:
space:
mode:
authorrchamala <36907958+rchamala@users.noreply.github.com>2025-02-23 00:51:43 -0800
committerGitHub <noreply@github.com>2025-02-23 00:51:43 -0800
commit2ff3b18554b115b17d5085b9a4cd779eeafd278a (patch)
tree0d1e2a464c7ce490a706420ebe77f4acb2656b15 /lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp
parent0968df9c3a5562f6a8d9f7948065848f3a273b81 (diff)
downloadllvm-2ff3b18554b115b17d5085b9a4cd779eeafd278a.zip
llvm-2ff3b18554b115b17d5085b9a4cd779eeafd278a.tar.gz
llvm-2ff3b18554b115b17d5085b9a4cd779eeafd278a.tar.bz2
Allow option to ignore module load errors in ScriptedProcess (#127153)
Current state in scripted process expects [all the modules](https://github.com/llvm/llvm-project/blob/912b154f3a3f8c3cebf5cc5731fd8b0749762da5/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp#L498) passed into "get_loaded_images" to load successfully else none of them load. Even if a module loads fine, [but has already been appended](https://github.com/llvm/llvm-project/blob/912b154f3a3f8c3cebf5cc5731fd8b0749762da5/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp#L495) it still fails. This is restrictive and does not help our usecase. **Usecase**: We have a parent scripted process using coredump + tombstone. 1) Scripted process uses child elf-core process to read memory dump 2) Uses tombstones to pass thread names and modules. We do not know whether the modules will be successfully downloaded before creating the scripted process. We use [python module callbacks](https://github.com/llvm/llvm-project/blob/a57e58dbfaae0e86eb5cafeddf8b598f14b96e36/lldb/source/Target/Platform.cpp#L1593) to download a module from symbol server at LLDB load time when the scripted process is being created. The issue is that if one of the symbol is not found from the list specified in tombstone, none of the modules load in scripted process. Even if we ensure symbols are present in symbol server before creating the scripted process, if the load address is wrong or if the module is already appended, all module loads are skipped. **Solution**: Pass in a custom boolean option arg for every module from python scripted process plugin which will indicate whether to ignore the module load error. This will provide the flexibility to user for loading the successfully fetched modules into target while ignoring the failed ones --------- Co-authored-by: rchamala <rachamal@fb.com>
Diffstat (limited to 'lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp')
-rw-r--r--lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp64
1 files changed, 46 insertions, 18 deletions
diff --git a/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp b/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp
index d2111ce..6b371a1 100644
--- a/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp
+++ b/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp
@@ -25,6 +25,8 @@
#include "lldb/Utility/ScriptedMetadata.h"
#include "lldb/Utility/State.h"
+#include "Plugins/ObjectFile/Placeholder/ObjectFilePlaceholder.h"
+
#include <mutex>
LLDB_PLUGIN_DEFINE(ScriptedProcess)
@@ -165,7 +167,7 @@ Status ScriptedProcess::DoLoadCore() {
Status ScriptedProcess::DoLaunch(Module *exe_module,
ProcessLaunchInfo &launch_info) {
LLDB_LOGF(GetLog(LLDBLog::Process), "ScriptedProcess::%s launching process", __FUNCTION__);
-
+
/* MARK: This doesn't reflect how lldb actually launches a process.
In reality, it attaches to debugserver, then resume the process.
That's not true in all cases. If debugserver is remote, lldb
@@ -444,7 +446,6 @@ ScriptedProcess::GetLoadedDynamicLibrariesInfos() {
return error_with_message("Couldn't cast image object into dictionary.");
ModuleSpec module_spec;
- llvm::StringRef value;
bool has_path = dict->HasKey("path");
bool has_uuid = dict->HasKey("uuid");
@@ -453,22 +454,17 @@ ScriptedProcess::GetLoadedDynamicLibrariesInfos() {
if (!dict->HasKey("load_addr"))
return error_with_message("Dictionary is missing key 'load_addr'");
+ llvm::StringRef path = "";
if (has_path) {
- dict->GetValueForKeyAsString("path", value);
- module_spec.GetFileSpec().SetPath(value);
+ dict->GetValueForKeyAsString("path", path);
+ module_spec.GetFileSpec().SetPath(path);
}
+ llvm::StringRef uuid = "";
if (has_uuid) {
- dict->GetValueForKeyAsString("uuid", value);
- module_spec.GetUUID().SetFromStringRef(value);
+ dict->GetValueForKeyAsString("uuid", uuid);
+ module_spec.GetUUID().SetFromStringRef(uuid);
}
- module_spec.GetArchitecture() = target.GetArchitecture();
-
- ModuleSP module_sp =
- target.GetOrCreateModule(module_spec, true /* notify */);
-
- if (!module_sp)
- return error_with_message("Couldn't create or get module.");
lldb::addr_t load_addr = LLDB_INVALID_ADDRESS;
lldb::offset_t slide = LLDB_INVALID_OFFSET;
@@ -481,6 +477,27 @@ ScriptedProcess::GetLoadedDynamicLibrariesInfos() {
if (slide != LLDB_INVALID_OFFSET)
load_addr += slide;
+ module_spec.GetArchitecture() = target.GetArchitecture();
+
+ ModuleSP module_sp =
+ target.GetOrCreateModule(module_spec, true /* notify */);
+
+ bool is_placeholder_module = false;
+
+ if (!module_sp) {
+ // Create a placeholder module
+ LLDB_LOGF(
+ GetLog(LLDBLog::Process),
+ "ScriptedProcess::%s unable to locate the matching "
+ "object file path %s, creating a placeholder module at 0x%" PRIx64,
+ __FUNCTION__, path.str().c_str(), load_addr);
+
+ module_sp = Module::CreateModuleFromObjectFile<ObjectFilePlaceholder>(
+ module_spec, load_addr, module_spec.GetFileSpec().MemorySize());
+
+ is_placeholder_module = true;
+ }
+
bool changed = false;
module_sp->SetLoadAddress(target, load_addr, false /*=value_is_offset*/,
changed);
@@ -488,16 +505,27 @@ ScriptedProcess::GetLoadedDynamicLibrariesInfos() {
if (!changed && !module_sp->GetObjectFile())
return error_with_message("Couldn't set the load address for module.");
- dict->GetValueForKeyAsString("path", value);
- FileSpec objfile(value);
+ FileSpec objfile(path);
module_sp->SetFileSpecAndObjectName(objfile, objfile.GetFilename());
+ if (is_placeholder_module) {
+ target.GetImages().AppendIfNeeded(module_sp, true /*notify=*/);
+ return true;
+ }
+
return module_list.AppendIfNeeded(module_sp);
};
- if (!loaded_images_sp->ForEach(reload_image))
- return ScriptedInterface::ErrorWithMessage<StructuredData::ObjectSP>(
- LLVM_PRETTY_FUNCTION, "Couldn't reload all images.", error);
+ size_t loaded_images_size = loaded_images_sp->GetSize();
+ bool print_error = true;
+ for (size_t idx = 0; idx < loaded_images_size; idx++) {
+ const auto &loaded_image = loaded_images_sp->GetItemAtIndex(idx);
+ if (!reload_image(loaded_image.get()) && print_error) {
+ print_error = false;
+ ScriptedInterface::ErrorWithMessage<StructuredData::ObjectSP>(
+ LLVM_PRETTY_FUNCTION, "Couldn't reload all images.", error);
+ }
+ }
target.ModulesDidLoad(module_list);