Skip to content

Commit 0c3dde8

Browse files
committed
Implement SymbolService::getLLDBTarget()
1 parent 1d752ca commit 0c3dde8

File tree

3 files changed

+78
-6
lines changed

3 files changed

+78
-6
lines changed

oi/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ add_library(symbol_service
1717
SymbolService.cpp
1818
)
1919
target_link_libraries(symbol_service
20+
LLDB
2021
drgn_utils
2122

2223
Boost::headers

oi/SymbolService.cpp

Lines changed: 67 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include <cassert>
2323
#include <cstring>
2424
#include <fstream>
25+
#include <lldb/API/LLDB.h>
2526

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

109-
SymbolService::SymbolService(pid_t pid) : target{pid} {
110+
SymbolService::SymbolService(pid_t pid, Backend back)
111+
: target{pid}, backend{back} {
110112
// Update target processes memory map
111113
LoadExecutableAddressRange(pid, executableAddrs);
112114
if (!loadModules()) {
@@ -115,8 +117,8 @@ SymbolService::SymbolService(pid_t pid) : target{pid} {
115117
}
116118
}
117119

118-
SymbolService::SymbolService(fs::path executablePath)
119-
: target{std::move(executablePath)} {
120+
SymbolService::SymbolService(fs::path executablePath, Backend back)
121+
: target{std::move(executablePath)}, backend{back} {
120122
if (!loadModules()) {
121123
throw std::runtime_error("Failed to load modules for executable " +
122124
executablePath.string());
@@ -131,6 +133,15 @@ SymbolService::~SymbolService() {
131133
if (prog != nullptr) {
132134
drgn_program_destroy(prog);
133135
}
136+
137+
if (lldbTarget) {
138+
lldbDebugger.DeleteTarget(lldbTarget);
139+
}
140+
141+
if (lldbDebugger) {
142+
lldb::SBDebugger::Destroy(lldbDebugger);
143+
lldb::SBDebugger::Terminate();
144+
}
134145
}
135146

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

433444
struct drgn_program* SymbolService::getDrgnProgram() {
434445
if (hardDisableDrgn) {
435-
LOG(ERROR) << "drgn is disabled, refusing to initialize";
446+
LOG(ERROR) << "drgn/LLDB is disabled, refusing to initialize";
447+
return nullptr;
448+
}
449+
450+
if (backend != Backend::DRGN) {
451+
LOG(ERROR) << "drgn is not the selected backend, refusing to initialize";
436452
return nullptr;
437453
}
438454

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

503+
lldb::SBTarget SymbolService::getLLDBTarget() {
504+
if (hardDisableDrgn) {
505+
LOG(ERROR) << "drgn/LLDB is disabled, refusing to initialize";
506+
return lldb::SBTarget();
507+
}
508+
509+
if (backend != Backend::LLDB) {
510+
LOG(ERROR) << "LLDB is not the selected backend, refusing to initialize";
511+
return lldb::SBTarget();
512+
}
513+
514+
bool success = false;
515+
516+
lldb::SBDebugger::Initialize();
517+
lldbDebugger = lldb::SBDebugger::Create(false);
518+
BOOST_SCOPE_EXIT_ALL(&) {
519+
if (!success) {
520+
lldb::SBDebugger::Destroy(lldbDebugger);
521+
lldb::SBDebugger::Terminate();
522+
}
523+
};
524+
525+
switch (target.index()) {
526+
case 0: {
527+
auto pid = std::get<pid_t>(target);
528+
lldbTarget = lldbDebugger.FindTargetWithProcessID(pid);
529+
if (!lldbTarget) {
530+
LOG(ERROR) << "Failed to find target with PID " << pid;
531+
return lldb::SBTarget();
532+
}
533+
break;
534+
}
535+
case 1: {
536+
auto path = std::get<fs::path>(target);
537+
lldbTarget = lldbDebugger.CreateTarget(path.c_str());
538+
if (!lldbTarget) {
539+
LOG(ERROR) << "Failed to create target from " << path;
540+
return lldb::SBTarget();
541+
}
542+
break;
543+
}
544+
}
545+
546+
success = true;
547+
return lldbTarget;
548+
}
549+
487550
/*
488551
* Although 'parseFormalParam' has an all-encompassing sounding name, its sole
489552
* task is to extract the location information for this parameter if any exist.

oi/SymbolService.h

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@
1616
#pragma once
1717

1818
#include <filesystem>
19+
#include <lldb/API/SBDebugger.h>
20+
#include <lldb/API/SBTarget.h>
21+
#include <lldb/API/SBType.h>
1922
#include <memory>
2023
#include <optional>
2124
#include <string>
@@ -38,14 +41,16 @@ struct SymbolInfo {
3841
};
3942

4043
class SymbolService {
44+
enum class Backend { DRGN, LLDB };
4145
public:
42-
SymbolService(pid_t);
43-
SymbolService(std::filesystem::path);
46+
SymbolService(pid_t, Backend = Backend::DRGN);
47+
SymbolService(std::filesystem::path, Backend = Backend::DRGN);
4448
SymbolService(const SymbolService&) = delete;
4549
SymbolService& operator=(const SymbolService&) = delete;
4650
~SymbolService();
4751

4852
struct drgn_program* getDrgnProgram();
53+
lldb::SBTarget getLLDBTarget();
4954

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

7176
private:
7277
std::variant<pid_t, std::filesystem::path> target;
78+
Backend backend;
7379
struct Dwfl* dwfl{nullptr};
7480
struct drgn_program* prog{nullptr};
81+
lldb::SBDebugger lldbDebugger{};
82+
lldb::SBTarget lldbTarget{};
7583

7684
bool loadModules();
7785
bool loadModulesFromPid(pid_t);

0 commit comments

Comments
 (0)