Skip to content

[lldb] Implement priority system for symbol locator plugin #144406

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
wants to merge 1 commit into from
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
3 changes: 2 additions & 1 deletion lldb/include/lldb/Core/PluginManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -431,7 +431,8 @@ class PluginManager {
SymbolLocatorDownloadObjectAndSymbolFile download_object_symbol_file =
nullptr,
SymbolLocatorFindSymbolFileInBundle find_symbol_file_in_bundle = nullptr,
DebuggerInitializeCallback debugger_init_callback = nullptr);
DebuggerInitializeCallback debugger_init_callback = nullptr,
SymbolLocatorGetPriority get_priority_callback = nullptr);

static bool UnregisterPlugin(SymbolLocatorCreateInstance create_callback);

Expand Down
3 changes: 3 additions & 0 deletions lldb/include/lldb/Symbol/SymbolLocator.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@

namespace lldb_private {

// Default priority for symbol locator plugins. Lower values are favored first.
static constexpr uint32_t kDefaultSymbolLocatorPriority = 2;

class SymbolLocator : public PluginInterface {
public:
SymbolLocator() = default;
Expand Down
1 change: 1 addition & 0 deletions lldb/include/lldb/lldb-private-interfaces.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ typedef std::optional<FileSpec> (*SymbolLocatorLocateExecutableSymbolFile)(
typedef bool (*SymbolLocatorDownloadObjectAndSymbolFile)(
ModuleSpec &module_spec, Status &error, bool force_lookup,
bool copy_executable);
typedef uint64_t (*SymbolLocatorGetPriority)();
using BreakpointHitCallback =
std::function<bool(void *baton, StoppointCallbackContext *context,
lldb::user_id_t break_id, lldb::user_id_t break_loc_id)>;
Expand Down
60 changes: 52 additions & 8 deletions lldb/source/Core/PluginManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "lldb/Host/HostInfo.h"
#include "lldb/Interpreter/OptionValueProperties.h"
#include "lldb/Symbol/SaveCoreOptions.h"
#include "lldb/Symbol/SymbolLocator.h"
#include "lldb/Target/Process.h"
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/Status.h"
Expand All @@ -25,6 +26,7 @@
#include <map>
#include <memory>
#include <mutex>
#include <queue>
#include <string>
#include <utility>
#include <vector>
Expand Down Expand Up @@ -323,6 +325,29 @@ template <typename Instance> class PluginInstances {
return enabled_instances;
}

// Return a priority queue of all enabled instances, ordered by priority
// (lower priority values = higher priority in queue)
template <typename PriorityGetter>
std::priority_queue<Instance, std::vector<Instance>,
std::function<bool(const Instance &, const Instance &)>>
GetPriorityQueue(PriorityGetter get_priority) {
// Create comparator that orders by priority (lower values = higher
// priority)
auto comparator = [get_priority](const Instance &a, const Instance &b) {
return get_priority(a) > get_priority(b); // Reverse for min-heap behavior
};

std::priority_queue<Instance, std::vector<Instance>,
std::function<bool(const Instance &, const Instance &)>>
pq(comparator);

for (const auto &instance : m_instances) {
if (instance.enabled)
pq.push(instance);
}
return pq;
}

const Instance *GetInstanceAtIndex(uint32_t idx) {
uint32_t count = 0;

Expand Down Expand Up @@ -1223,18 +1248,26 @@ struct SymbolLocatorInstance
SymbolLocatorLocateExecutableSymbolFile locate_executable_symbol_file,
SymbolLocatorDownloadObjectAndSymbolFile download_object_symbol_file,
SymbolLocatorFindSymbolFileInBundle find_symbol_file_in_bundle,
DebuggerInitializeCallback debugger_init_callback)
DebuggerInitializeCallback debugger_init_callback,
SymbolLocatorGetPriority get_priority_callback)
: PluginInstance<SymbolLocatorCreateInstance>(
name, description, create_callback, debugger_init_callback),
locate_executable_object_file(locate_executable_object_file),
locate_executable_symbol_file(locate_executable_symbol_file),
download_object_symbol_file(download_object_symbol_file),
find_symbol_file_in_bundle(find_symbol_file_in_bundle) {}
find_symbol_file_in_bundle(find_symbol_file_in_bundle),
get_priority_callback(get_priority_callback) {}

uint64_t GetPriority() const {
return get_priority_callback ? get_priority_callback()
: kDefaultSymbolLocatorPriority;
}

SymbolLocatorLocateExecutableObjectFile locate_executable_object_file;
SymbolLocatorLocateExecutableSymbolFile locate_executable_symbol_file;
SymbolLocatorDownloadObjectAndSymbolFile download_object_symbol_file;
SymbolLocatorFindSymbolFileInBundle find_symbol_file_in_bundle;
SymbolLocatorGetPriority get_priority_callback;
};
typedef PluginInstances<SymbolLocatorInstance> SymbolLocatorInstances;

Expand All @@ -1250,11 +1283,13 @@ bool PluginManager::RegisterPlugin(
SymbolLocatorLocateExecutableSymbolFile locate_executable_symbol_file,
SymbolLocatorDownloadObjectAndSymbolFile download_object_symbol_file,
SymbolLocatorFindSymbolFileInBundle find_symbol_file_in_bundle,
DebuggerInitializeCallback debugger_init_callback) {
DebuggerInitializeCallback debugger_init_callback,
SymbolLocatorGetPriority get_priority_callback) {
return GetSymbolLocatorInstances().RegisterPlugin(
name, description, create_callback, locate_executable_object_file,
locate_executable_symbol_file, download_object_symbol_file,
find_symbol_file_in_bundle, debugger_init_callback);
find_symbol_file_in_bundle, debugger_init_callback,
get_priority_callback);
}

bool PluginManager::UnregisterPlugin(
Expand All @@ -1270,8 +1305,13 @@ PluginManager::GetSymbolLocatorCreateCallbackAtIndex(uint32_t idx) {
ModuleSpec
PluginManager::LocateExecutableObjectFile(const ModuleSpec &module_spec,
StatisticsMap &map) {
auto instances = GetSymbolLocatorInstances().GetSnapshot();
for (auto &instance : instances) {
auto pq = GetSymbolLocatorInstances().GetPriorityQueue(
[](const auto &instance) { return instance.GetPriority(); });

while (!pq.empty()) {
auto instance = pq.top();
pq.pop();

if (instance.locate_executable_object_file) {
StatsDuration time;
std::optional<ModuleSpec> result;
Expand All @@ -1290,8 +1330,12 @@ PluginManager::LocateExecutableObjectFile(const ModuleSpec &module_spec,
FileSpec PluginManager::LocateExecutableSymbolFile(
const ModuleSpec &module_spec, const FileSpecList &default_search_paths,
StatisticsMap &map) {
auto instances = GetSymbolLocatorInstances().GetSnapshot();
for (auto &instance : instances) {
auto pq = GetSymbolLocatorInstances().GetPriorityQueue(
[](const auto &instance) { return instance.GetPriority(); });

while (!pq.empty()) {
auto instance = pq.top();
pq.pop();
if (instance.locate_executable_symbol_file) {
StatsDuration time;
std::optional<FileSpec> result;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,16 @@ class PluginProperties : public Properties {
}
}

uint32_t GetPriority() const {
std::optional<uint32_t> priority =
m_collection_sp->GetPropertyAtIndexAs<uint64_t>(ePropertyPriority);
if (priority && *priority >= 0) {
return priority.value();
} else {
return kDefaultSymbolLocatorPriority;
}
}

private:
void ServerURLsChangedCallback() {
m_server_urls = GetDebugInfoDURLs();
Expand All @@ -103,6 +113,13 @@ static PluginProperties &GetGlobalPluginProperties() {
return g_settings;
}

static uint64_t GetDebuginfodPriority() {
// Grab LLDB's Debuginfod overrides from the
// plugin.symbol-locator.debuginfod.* settings.
PluginProperties &plugin_props = GetGlobalPluginProperties();
return plugin_props.GetPriority();
}

SymbolLocatorDebuginfod::SymbolLocatorDebuginfod() : SymbolLocator() {}

void SymbolLocatorDebuginfod::Initialize() {
Expand All @@ -112,7 +129,8 @@ void SymbolLocatorDebuginfod::Initialize() {
PluginManager::RegisterPlugin(
GetPluginNameStatic(), GetPluginDescriptionStatic(), CreateInstance,
LocateExecutableObjectFile, LocateExecutableSymbolFile, nullptr,
nullptr, SymbolLocatorDebuginfod::DebuggerInitialize);
nullptr, SymbolLocatorDebuginfod::DebuggerInitialize,
GetDebuginfodPriority);
llvm::HTTPClient::initialize();
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,7 @@ let Definition = "symbollocatordebuginfod" in {
def Timeout : Property<"timeout", "UInt64">,
DefaultUnsignedValue<0>,
Desc<"Timeout (in seconds) for requests made to a DEBUGINFOD server. A value of zero means we use the debuginfod default timeout: DEBUGINFOD_TIMEOUT if the environment variable is set and 90 seconds otherwise.">;
def Priority : Property<"priority", "UInt64">,
DefaultUnsignedValue<2>,
Desc<"The priority order for this symbol locator plugin when multiple symbol locators are available. Lower values indicate higher priority. The default symbol locator priority is 2">;
}
Loading