Skip to content
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

Add skeleton LLDBParser #424

Open
wants to merge 20 commits into
base: main
Choose a base branch
from
Open
Changes from 1 commit
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
Prev Previous commit
Next Next commit
Implement SymbolService::getLLDBTarget()
ttreyer committed Dec 19, 2023
commit 0c3dde852084ff49936b210d38f90e36bbe831d4
1 change: 1 addition & 0 deletions oi/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -17,6 +17,7 @@ add_library(symbol_service
SymbolService.cpp
)
target_link_libraries(symbol_service
LLDB
drgn_utils

Boost::headers
71 changes: 67 additions & 4 deletions oi/SymbolService.cpp
Original file line number Diff line number Diff line change
@@ -22,6 +22,7 @@
#include <cassert>
#include <cstring>
#include <fstream>
#include <lldb/API/LLDB.h>

#include "oi/DrgnUtils.h"
#include "oi/OIParser.h"
@@ -106,7 +107,8 @@ static bool isExecutableAddr(
return it != end(exeAddrs) && addr >= it->first;
}

SymbolService::SymbolService(pid_t pid) : target{pid} {
SymbolService::SymbolService(pid_t pid, Backend back)
: target{pid}, backend{back} {
// Update target processes memory map
LoadExecutableAddressRange(pid, executableAddrs);
if (!loadModules()) {
@@ -115,8 +117,8 @@ SymbolService::SymbolService(pid_t pid) : target{pid} {
}
}

SymbolService::SymbolService(fs::path executablePath)
: target{std::move(executablePath)} {
SymbolService::SymbolService(fs::path executablePath, Backend back)
: target{std::move(executablePath)}, backend{back} {
if (!loadModules()) {
throw std::runtime_error("Failed to load modules for executable " +
executablePath.string());
@@ -131,6 +133,15 @@ SymbolService::~SymbolService() {
if (prog != nullptr) {
drgn_program_destroy(prog);
}

if (lldbTarget) {
lldbDebugger.DeleteTarget(lldbTarget);
}

if (lldbDebugger) {
lldb::SBDebugger::Destroy(lldbDebugger);
lldb::SBDebugger::Terminate();
}
}

struct ModParams {
@@ -432,7 +443,12 @@ std::optional<std::string> SymbolService::locateBuildID() {

struct drgn_program* SymbolService::getDrgnProgram() {
if (hardDisableDrgn) {
LOG(ERROR) << "drgn is disabled, refusing to initialize";
LOG(ERROR) << "drgn/LLDB is disabled, refusing to initialize";
return nullptr;
}

if (backend != Backend::DRGN) {
LOG(ERROR) << "drgn is not the selected backend, refusing to initialize";
return nullptr;
}

@@ -484,6 +500,53 @@ struct drgn_program* SymbolService::getDrgnProgram() {
return prog;
}

lldb::SBTarget SymbolService::getLLDBTarget() {
if (hardDisableDrgn) {
LOG(ERROR) << "drgn/LLDB is disabled, refusing to initialize";
return lldb::SBTarget();
}

if (backend != Backend::LLDB) {
LOG(ERROR) << "LLDB is not the selected backend, refusing to initialize";
return lldb::SBTarget();
}

bool success = false;

lldb::SBDebugger::Initialize();
lldbDebugger = lldb::SBDebugger::Create(false);
BOOST_SCOPE_EXIT_ALL(&) {
if (!success) {
lldb::SBDebugger::Destroy(lldbDebugger);
lldb::SBDebugger::Terminate();
}
};

switch (target.index()) {
case 0: {
auto pid = std::get<pid_t>(target);
lldbTarget = lldbDebugger.FindTargetWithProcessID(pid);
if (!lldbTarget) {
LOG(ERROR) << "Failed to find target with PID " << pid;
return lldb::SBTarget();
}
break;
}
case 1: {
auto path = std::get<fs::path>(target);
lldbTarget = lldbDebugger.CreateTarget(path.c_str());
if (!lldbTarget) {
LOG(ERROR) << "Failed to create target from " << path;
return lldb::SBTarget();
}
break;
}
}

success = true;
return lldbTarget;
}

/*
* Although 'parseFormalParam' has an all-encompassing sounding name, its sole
* task is to extract the location information for this parameter if any exist.
12 changes: 10 additions & 2 deletions oi/SymbolService.h
Original file line number Diff line number Diff line change
@@ -16,6 +16,9 @@
#pragma once

#include <filesystem>
#include <lldb/API/SBDebugger.h>
#include <lldb/API/SBTarget.h>
#include <lldb/API/SBType.h>
#include <memory>
#include <optional>
#include <string>
@@ -38,14 +41,16 @@ struct SymbolInfo {
};

class SymbolService {
enum class Backend { DRGN, LLDB };
public:
SymbolService(pid_t);
SymbolService(std::filesystem::path);
SymbolService(pid_t, Backend = Backend::DRGN);
SymbolService(std::filesystem::path, Backend = Backend::DRGN);
SymbolService(const SymbolService&) = delete;
SymbolService& operator=(const SymbolService&) = delete;
~SymbolService();

struct drgn_program* getDrgnProgram();
lldb::SBTarget getLLDBTarget();

std::optional<std::string> locateBuildID();
std::optional<SymbolInfo> locateSymbol(const std::string&,
@@ -70,8 +75,11 @@ class SymbolService {

private:
std::variant<pid_t, std::filesystem::path> target;
Backend backend;
struct Dwfl* dwfl{nullptr};
struct drgn_program* prog{nullptr};
lldb::SBDebugger lldbDebugger{};
lldb::SBTarget lldbTarget{};

bool loadModules();
bool loadModulesFromPid(pid_t);