[debugger] Attach ELF symbols to LoadedModuleSymbols
Test: Unit tests pass
Change-Id: Ie5181d88967c2da5eafdcf2f93bcb5b063aa0630
diff --git a/bin/zxdb/client/breakpoint_impl_unittest.cc b/bin/zxdb/client/breakpoint_impl_unittest.cc
index a293339..1292ac9 100644
--- a/bin/zxdb/client/breakpoint_impl_unittest.cc
+++ b/bin/zxdb/client/breakpoint_impl_unittest.cc
@@ -6,6 +6,7 @@
#include "garnet/bin/zxdb/client/breakpoint_impl.h"
#include "garnet/bin/zxdb/client/process_impl.h"
+#include "garnet/bin/zxdb/client/process_observer.h"
#include "garnet/bin/zxdb/client/remote_api_test.h"
#include "garnet/bin/zxdb/client/session.h"
#include "garnet/bin/zxdb/client/target_impl.h"
@@ -49,10 +50,24 @@
FROM_HERE, [cb]() { cb(Err(), debug_ipc::RemoveBreakpointReply()); });
}
+ void SymbolTables(
+ const debug_ipc::SymbolTablesRequest& request,
+ std::function<void(const Err&, debug_ipc::SymbolTablesReply)> cb)
+ override {
+ MessageLoop::Current()->PostTask(
+ FROM_HERE, [cb]() { cb(Err(), debug_ipc::SymbolTablesReply()); });
+ }
+
std::vector<AddPair> adds;
std::vector<RemovePair> removes;
};
+class StopOnLoadModuleObserver : public ProcessObserver {
+ void DidLoadModuleSymbols(Process* process, LoadedModuleSymbols* module) {
+ MessageLoop::Current()->QuitNow();
+ }
+};
+
class BreakpointImplTest : public RemoteAPITest {
public:
BreakpointImplTest() = default;
@@ -148,6 +163,10 @@
modules.push_back(load1);
target->process()->OnModules(modules, std::vector<uint64_t>());
+ StopOnLoadModuleObserver observer;
+ target->process()->AddObserver(&observer);
+ MessageLoop::Current()->Run();
+
// That should have notified the breakpoint which should have added the two
// addresses to the backend.
ASSERT_FALSE(sink().adds.empty());
diff --git a/bin/zxdb/client/mock_remote_api.cc b/bin/zxdb/client/mock_remote_api.cc
index c875551..ab647ac 100644
--- a/bin/zxdb/client/mock_remote_api.cc
+++ b/bin/zxdb/client/mock_remote_api.cc
@@ -35,7 +35,7 @@
std::function<void(const Err&, debug_ipc::ThreadStatusReply)> cb) {
// Returns the canned response.
debug_ipc::MessageLoop::Current()->PostTask(
- FROM_HERE, [ cb, response = thread_status_reply_ ]() {
+ FROM_HERE, [cb, response = thread_status_reply_]() {
cb(Err(), std::move(response));
});
}
@@ -63,4 +63,11 @@
});
}
+void MockRemoteAPI::SymbolTables(
+ const debug_ipc::SymbolTablesRequest& request,
+ std::function<void(const Err&, debug_ipc::SymbolTablesReply)> cb) {
+ debug_ipc::MessageLoop::Current()->PostTask(
+ FROM_HERE, [cb]() { cb(Err(), debug_ipc::SymbolTablesReply()); });
+}
+
} // namespace zxdb
diff --git a/bin/zxdb/client/mock_remote_api.h b/bin/zxdb/client/mock_remote_api.h
index bea8a85..6c29409 100644
--- a/bin/zxdb/client/mock_remote_api.h
+++ b/bin/zxdb/client/mock_remote_api.h
@@ -67,6 +67,10 @@
const debug_ipc::WriteRegistersRequest& request,
std::function<void(const Err&, debug_ipc::WriteRegistersReply)> cb)
override;
+ void SymbolTables(
+ const debug_ipc::SymbolTablesRequest& request,
+ std::function<void(const Err&, debug_ipc::SymbolTablesReply)> cb)
+ override;
private:
debug_ipc::ThreadStatusReply thread_status_reply_;
diff --git a/bin/zxdb/client/process_impl.cc b/bin/zxdb/client/process_impl.cc
index 769e26a..5e2fea4 100644
--- a/bin/zxdb/client/process_impl.cc
+++ b/bin/zxdb/client/process_impl.cc
@@ -14,6 +14,7 @@
#include "garnet/bin/zxdb/client/target_impl.h"
#include "garnet/bin/zxdb/client/thread_impl.h"
#include "garnet/bin/zxdb/symbols/input_location.h"
+#include "garnet/bin/zxdb/symbols/loaded_module_symbols.h"
#include "garnet/public/lib/fxl/logging.h"
namespace zxdb {
@@ -55,7 +56,7 @@
debug_ipc::ModulesRequest request;
request.process_koid = koid_;
session()->remote_api()->Modules(
- request, [ process = weak_factory_.GetWeakPtr(), callback ](
+ request, [process = weak_factory_.GetWeakPtr(), callback](
const Err& err, debug_ipc::ModulesReply reply) {
if (process)
process->symbols_.SetModules(reply.modules);
@@ -94,7 +95,7 @@
debug_ipc::ThreadsRequest request;
request.process_koid = koid_;
session()->remote_api()->Threads(
- request, [ callback, process = weak_factory_.GetWeakPtr() ](
+ request, [callback, process = weak_factory_.GetWeakPtr()](
const Err& err, debug_ipc::ThreadsReply reply) {
if (process) {
process->UpdateThreads(reply.threads);
@@ -241,8 +242,22 @@
}
void ProcessImpl::DidLoadModuleSymbols(LoadedModuleSymbols* module) {
- for (auto& observer : observers())
- observer.DidLoadModuleSymbols(this, module);
+ debug_ipc::SymbolTablesRequest request;
+
+ request.process_koid = koid_;
+ request.base = module->load_address();
+ request.build_id = module->build_id();
+
+ session()->remote_api()->SymbolTables(
+ request,
+ [this, module](const Err& err, debug_ipc::SymbolTablesReply reply) {
+ if (!err.has_error()) {
+ module->SetElfSymbols(reply.symbols);
+ }
+
+ for (auto& observer : observers())
+ observer.DidLoadModuleSymbols(this, module);
+ });
}
void ProcessImpl::WillUnloadModuleSymbols(LoadedModuleSymbols* module) {
diff --git a/bin/zxdb/client/thread_controller_test.cc b/bin/zxdb/client/thread_controller_test.cc
index b8f6a6d..94be9e3 100644
--- a/bin/zxdb/client/thread_controller_test.cc
+++ b/bin/zxdb/client/thread_controller_test.cc
@@ -5,6 +5,7 @@
#include "garnet/bin/zxdb/client/thread_controller_test.h"
#include "garnet/bin/zxdb/client/process_impl.h"
+#include "garnet/bin/zxdb/client/process_observer.h"
#include "garnet/bin/zxdb/client/session.h"
#include "garnet/bin/zxdb/client/system.h"
#include "garnet/bin/zxdb/client/target_impl.h"
@@ -13,6 +14,12 @@
namespace zxdb {
+class StopOnLoadModuleObserver : public ProcessObserver {
+ void DidLoadModuleSymbols(Process* process, LoadedModuleSymbols* module) {
+ debug_ipc::MessageLoop::Current()->QuitNow();
+ }
+};
+
// static
const uint64_t ThreadControllerTest::kUnsymbolizedModuleAddress = 0x4000000;
@@ -51,6 +58,11 @@
TargetImpl* target = session().system_impl().GetTargetImpls()[0];
target->process()->OnModules(modules, std::vector<uint64_t>());
+
+ StopOnLoadModuleObserver observer;
+ target->process()->AddObserver(&observer);
+ debug_ipc::MessageLoop::Current()->Run();
+ target->process()->RemoveObserver(&observer);
}
std::unique_ptr<RemoteAPI> ThreadControllerTest::GetRemoteAPIImpl() {
diff --git a/bin/zxdb/symbols/loaded_module_symbols.cc b/bin/zxdb/symbols/loaded_module_symbols.cc
index 40b058c..6155dfa 100644
--- a/bin/zxdb/symbols/loaded_module_symbols.cc
+++ b/bin/zxdb/symbols/loaded_module_symbols.cc
@@ -8,9 +8,11 @@
namespace zxdb {
LoadedModuleSymbols::LoadedModuleSymbols(
- fxl::RefPtr<SystemSymbols::ModuleRef> module, uint64_t load_address)
+ fxl::RefPtr<SystemSymbols::ModuleRef> module, std::string build_id,
+ uint64_t load_address)
: module_(std::move(module)),
load_address_(load_address),
+ build_id_(std::move(build_id)),
symbol_context_(load_address) {}
LoadedModuleSymbols::~LoadedModuleSymbols() = default;
diff --git a/bin/zxdb/symbols/loaded_module_symbols.h b/bin/zxdb/symbols/loaded_module_symbols.h
index ffe102f..69f44f6 100644
--- a/bin/zxdb/symbols/loaded_module_symbols.h
+++ b/bin/zxdb/symbols/loaded_module_symbols.h
@@ -12,6 +12,7 @@
#include "garnet/bin/zxdb/symbols/location.h"
#include "garnet/bin/zxdb/symbols/resolve_options.h"
#include "garnet/bin/zxdb/symbols/system_symbols.h"
+#include "garnet/lib/debug_ipc/records.h"
#include "garnet/public/lib/fxl/macros.h"
namespace zxdb {
@@ -25,7 +26,7 @@
class LoadedModuleSymbols {
public:
LoadedModuleSymbols(fxl::RefPtr<SystemSymbols::ModuleRef> module,
- uint64_t load_address);
+ std::string build_id, uint64_t load_address);
~LoadedModuleSymbols();
// Returns the underlying ModuleSymbols object.
@@ -37,10 +38,23 @@
// Base address for the module.
uint64_t load_address() const { return load_address_; }
+ // Build ID for the module.
+ const std::string& build_id() const { return build_id_; }
+
+ // ELF Symbols for the module.
+ const std::vector<debug_ipc::ElfSymbol>& elf_symbols() const {
+ return elf_symbols_;
+ }
+
// Most functions in ModuleSymbols take a symbol context to convert between
// absolute addresses in memory to ones relative to the module load address.
const SymbolContext& symbol_context() const { return symbol_context_; }
+ // Set the elf symbols for the module.
+ void SetElfSymbols(std::vector<debug_ipc::ElfSymbol> symbols) {
+ elf_symbols_ = std::move(symbols);
+ }
+
// Converts the given InputLocation into one or more locations. If the
// location is an address, it will be be returned whether or not the address
// is inside this module (it will be symbolized if possible). If the input is
@@ -85,6 +99,8 @@
fxl::RefPtr<SystemSymbols::ModuleRef> module_;
uint64_t load_address_;
+ std::string build_id_;
+ std::vector<debug_ipc::ElfSymbol> elf_symbols_;
SymbolContext symbol_context_;
FXL_DISALLOW_COPY_AND_ASSIGN(LoadedModuleSymbols);
diff --git a/bin/zxdb/symbols/process_symbols.cc b/bin/zxdb/symbols/process_symbols.cc
index fd793e4..f2b4fd3 100644
--- a/bin/zxdb/symbols/process_symbols.cc
+++ b/bin/zxdb/symbols/process_symbols.cc
@@ -211,11 +211,12 @@
// Error, but it may be expected.
if (!ExpectSymbolsForName(module.name))
*symbol_load_err = Err();
- info.symbols = std::make_unique<LoadedModuleSymbols>(nullptr, module.base);
+ info.symbols = std::make_unique<LoadedModuleSymbols>(
+ nullptr, module.build_id, module.base);
} else {
// Success, make the LoadedModuleSymbols.
info.symbols = std::make_unique<LoadedModuleSymbols>(
- std::move(module_symbols), module.base);
+ std::move(module_symbols), module.build_id, module.base);
}
auto inserted_iter =
diff --git a/bin/zxdb/symbols/process_symbols_test_setup.cc b/bin/zxdb/symbols/process_symbols_test_setup.cc
index 5e6b135..32c2437 100644
--- a/bin/zxdb/symbols/process_symbols_test_setup.cc
+++ b/bin/zxdb/symbols/process_symbols_test_setup.cc
@@ -21,7 +21,8 @@
const std::string& name, const std::string& build_id, uint64_t base,
std::unique_ptr<ModuleSymbols> mod_sym) {
auto loaded = std::make_unique<LoadedModuleSymbols>(
- system_.InjectModuleForTesting(build_id, std::move(mod_sym)), base);
+ system_.InjectModuleForTesting(build_id, std::move(mod_sym)), build_id,
+ base);
process_.InjectModuleForTesting(name, build_id, std::move(loaded));
}