Skip to content

DynamicLoaderDarwin load images in parallel #110439

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
13 changes: 13 additions & 0 deletions lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,16 @@
lldb_tablegen(DynamicLoaderDarwinProperties.inc -gen-lldb-property-defs
SOURCE DynamicLoaderDarwinProperties.td
TARGET LLDBPluginDynamicLoaderDarwinPropertiesGen)

lldb_tablegen(DynamicLoaderDarwinPropertiesEnum.inc -gen-lldb-property-enum-defs
SOURCE DynamicLoaderDarwinProperties.td
TARGET LLDBPluginDynamicLoaderDarwinPropertiesEnumGen)

add_lldb_library(lldbPluginDynamicLoaderMacOSXDYLD PLUGIN
DynamicLoaderMacOSXDYLD.cpp
DynamicLoaderMacOS.cpp
DynamicLoaderDarwin.cpp
DynamicLoaderDarwinProperties.cpp

LINK_LIBS
lldbBreakpoint
Expand All @@ -16,3 +25,7 @@ add_lldb_library(lldbPluginDynamicLoaderMacOSXDYLD PLUGIN
Support
TargetParser
)

add_dependencies(lldbPluginDynamicLoaderMacOSXDYLD
LLDBPluginDynamicLoaderDarwinPropertiesGen
LLDBPluginDynamicLoaderDarwinPropertiesEnumGen)
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

#include "DynamicLoaderDarwin.h"

#include "DynamicLoaderDarwinProperties.h"
#include "lldb/Breakpoint/StoppointCallbackContext.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Module.h"
Expand All @@ -31,6 +32,7 @@
#include "lldb/Utility/LLDBLog.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/State.h"
#include "llvm/Support/ThreadPool.h"

#include "Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h"
#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
Expand Down Expand Up @@ -77,6 +79,17 @@ void DynamicLoaderDarwin::DidLaunch() {
SetNotificationBreakpoint();
}

void DynamicLoaderDarwin::CreateSettings(lldb_private::Debugger &debugger) {
if (!PluginManager::GetSettingForDynamicLoaderPlugin(
debugger, DynamicLoaderDarwinProperties::GetSettingName())) {
const bool is_global_setting = true;
PluginManager::CreateSettingForDynamicLoaderPlugin(
debugger,
DynamicLoaderDarwinProperties::GetGlobal().GetValueProperties(),
"Properties for the DynamicLoaderDarwin plug-in.", is_global_setting);
}
}

// Clear out the state of this class.
void DynamicLoaderDarwin::Clear(bool clear_process) {
std::lock_guard<std::recursive_mutex> guard(m_mutex);
Expand All @@ -88,7 +101,7 @@ void DynamicLoaderDarwin::Clear(bool clear_process) {
}

ModuleSP DynamicLoaderDarwin::FindTargetModuleForImageInfo(
ImageInfo &image_info, bool can_create, bool *did_create_ptr) {
const ImageInfo &image_info, bool can_create, bool *did_create_ptr) {
if (did_create_ptr)
*did_create_ptr = false;

Expand Down Expand Up @@ -642,6 +655,41 @@ ModuleSP DynamicLoaderDarwin::GetDYLDModule() {

void DynamicLoaderDarwin::ClearDYLDModule() { m_dyld_module_wp.reset(); }

template <typename InputIterator, typename ResultType>
static std::vector<ResultType> parallel_map(
llvm::ThreadPoolInterface &threadPool, InputIterator first,
InputIterator last,
llvm::function_ref<ResultType(
const typename std::iterator_traits<InputIterator>::value_type &)>
transform) {
const auto size = std::distance(first, last);
std::vector<ResultType> results(size);
if (size > 0) {
llvm::ThreadPoolTaskGroup taskGroup(threadPool);
auto it = first;
for (ssize_t i = 0; i < size; ++i, ++it) {
taskGroup.async([&, i, it]() { results[i] = transform(*it); });
}
taskGroup.wait();
}
return results;
}

template <typename InputIterator, typename ResultType>
static std::vector<ResultType>
map(InputIterator first, InputIterator last,
llvm::function_ref<ResultType(
const typename std::iterator_traits<InputIterator>::value_type &)>
transform) {
const auto size = std::distance(first, last);
std::vector<ResultType> results(size);
auto it = first;
for (ssize_t i = 0; i < size; ++i, ++it) {
results[i] = transform(*it);
}
return results;
}

bool DynamicLoaderDarwin::AddModulesUsingImageInfos(
ImageInfo::collection &image_infos) {
std::lock_guard<std::recursive_mutex> guard(m_mutex);
Expand All @@ -651,17 +699,28 @@ bool DynamicLoaderDarwin::AddModulesUsingImageInfos(
Target &target = m_process->GetTarget();
ModuleList &target_images = target.GetImages();

for (uint32_t idx = 0; idx < image_infos.size(); ++idx) {
auto ImageLoad = [this, log](const ImageInfo &image_info) {
if (log) {
LLDB_LOGF(log, "Adding new image at address=0x%16.16" PRIx64 ".",
image_infos[idx].address);
image_infos[idx].PutToLog(log);
image_info.address);
image_info.PutToLog(log);
}
return FindTargetModuleForImageInfo(image_info, true, nullptr);
};
bool is_parallel_load =
DynamicLoaderDarwinProperties::GetGlobal().GetEnableParallelImageLoad();
auto images =
is_parallel_load
? parallel_map<ImageInfo::collection::const_iterator, ModuleSP>(
Debugger::GetThreadPool(), image_infos.begin(),
image_infos.end(), ImageLoad)
: map<ImageInfo::collection::const_iterator, ModuleSP>(
image_infos.begin(), image_infos.end(), ImageLoad);

for (uint32_t idx = 0; idx < image_infos.size(); ++idx) {
m_dyld_image_infos.push_back(image_infos[idx]);

ModuleSP image_module_sp(
FindTargetModuleForImageInfo(image_infos[idx], true, nullptr));
ModuleSP image_module_sp = images[idx];

if (image_module_sp) {
ObjectFile *objfile = image_module_sp->GetObjectFile();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ class DynamicLoaderDarwin : public lldb_private::DynamicLoader {

std::optional<lldb_private::Address> GetStartAddress() override;

static void CreateSettings(lldb_private::Debugger &debugger);

protected:
void PrivateInitialize(lldb_private::Process *process);

Expand Down Expand Up @@ -174,7 +176,7 @@ class DynamicLoaderDarwin : public lldb_private::DynamicLoader {

bool UnloadModuleSections(lldb_private::Module *module, ImageInfo &info);

lldb::ModuleSP FindTargetModuleForImageInfo(ImageInfo &image_info,
lldb::ModuleSP FindTargetModuleForImageInfo(const ImageInfo &image_info,
bool can_create,
bool *did_create_ptr);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
//===-- DynamicLoaderDarwinProperties.cpp ---------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "DynamicLoaderDarwinProperties.h"

using namespace lldb_private;

#define LLDB_PROPERTIES_dynamicloaderdarwin_experimental
#include "DynamicLoaderDarwinProperties.inc"

enum {
#define LLDB_PROPERTIES_dynamicloaderdarwin_experimental
#include "DynamicLoaderDarwinPropertiesEnum.inc"
};

llvm::StringRef DynamicLoaderDarwinProperties::GetSettingName() {
static constexpr llvm::StringLiteral g_setting_name("darwin");
return g_setting_name;
}

DynamicLoaderDarwinProperties::ExperimentalProperties::ExperimentalProperties()
: Properties(std::make_shared<OptionValueProperties>(
GetExperimentalSettingsName())) {
m_collection_sp->Initialize(g_dynamicloaderdarwin_experimental_properties);
}

DynamicLoaderDarwinProperties::DynamicLoaderDarwinProperties()
: Properties(std::make_shared<OptionValueProperties>(GetSettingName())),
m_experimental_properties(std::make_unique<ExperimentalProperties>()) {
m_collection_sp->AppendProperty(
Properties::GetExperimentalSettingsName(),
"Experimental settings - setting these won't produce errors if the "
"setting is not present.",
true, m_experimental_properties->GetValueProperties());
}

bool DynamicLoaderDarwinProperties::GetEnableParallelImageLoad() const {
return m_experimental_properties->GetPropertyAtIndexAs<bool>(
ePropertyEnableParallelImageLoad,
g_dynamicloaderdarwin_experimental_properties
[ePropertyEnableParallelImageLoad]
.default_uint_value != 0);
}

DynamicLoaderDarwinProperties &DynamicLoaderDarwinProperties::GetGlobal() {
static DynamicLoaderDarwinProperties g_settings;
return g_settings;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
//===-- DynamicLoaderDarwinProperties.h -------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLDB_SOURCE_PLUGINS_DYNAMICLOADER_MACOSX_DYLD_DYNAMICLOADERDARWINPROPERTIES_H
#define LLDB_SOURCE_PLUGINS_DYNAMICLOADER_MACOSX_DYLD_DYNAMICLOADERDARWINPROPERTIES_H

#include "lldb/Core/UserSettingsController.h"

namespace lldb_private {

class DynamicLoaderDarwinProperties : public Properties {
public:
class ExperimentalProperties : public Properties {
public:
ExperimentalProperties();
};
static llvm::StringRef GetSettingName();
static DynamicLoaderDarwinProperties &GetGlobal();
DynamicLoaderDarwinProperties();
~DynamicLoaderDarwinProperties() override = default;
bool GetEnableParallelImageLoad() const;

private:
std::unique_ptr<ExperimentalProperties> m_experimental_properties;
};

} // namespace lldb_private

#endif // LLDB_SOURCE_PLUGINS_DYNAMICLOADER_MACOSX_DYLD_DYNAMICLOADERDARWINPROPERTIES_H
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
include "../../../../include/lldb/Core/PropertiesBase.td"

let Definition = "dynamicloaderdarwin_experimental" in {
def EnableParallelImageLoad: Property<"enable-parallel-image-load", "Boolean">,
Global,
DefaultTrue,
Desc<"Load images in parallel.">;
}
Original file line number Diff line number Diff line change
Expand Up @@ -1147,7 +1147,8 @@ bool DynamicLoaderMacOSXDYLD::IsFullyInitialized() {

void DynamicLoaderMacOSXDYLD::Initialize() {
PluginManager::RegisterPlugin(GetPluginNameStatic(),
GetPluginDescriptionStatic(), CreateInstance);
GetPluginDescriptionStatic(), CreateInstance,
DebuggerInitialize);
DynamicLoaderMacOS::Initialize();
}

Expand All @@ -1156,6 +1157,11 @@ void DynamicLoaderMacOSXDYLD::Terminate() {
PluginManager::UnregisterPlugin(CreateInstance);
}

void DynamicLoaderMacOSXDYLD::DebuggerInitialize(
lldb_private::Debugger &debugger) {
CreateSettings(debugger);
}

llvm::StringRef DynamicLoaderMacOSXDYLD::GetPluginDescriptionStatic() {
return "Dynamic loader plug-in that watches for shared library loads/unloads "
"in MacOSX user processes.";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ class DynamicLoaderMacOSXDYLD : public lldb_private::DynamicLoaderDarwin {
static lldb_private::DynamicLoader *
CreateInstance(lldb_private::Process *process, bool force);

static void DebuggerInitialize(lldb_private::Debugger &debugger);

/// Called after attaching a process.
///
/// Allow DynamicLoader plug-ins to execute some code after
Expand Down