LibSymbolication+SystemMonitor+bt: Move symbolication back in-process

Process-separated symbolication was cute, but ultimately the threat
model is kinda silly. We're already *running* the binary, but we're
afraid to parse its symbol table? :^)

This commit makes SystemMonitor and bt do symbolication in-process.
SymbolServer and the symbol user will be removed separately.
This commit is contained in:
Andreas Kling 2021-05-22 18:23:51 +02:00
parent d783076a30
commit 252cb54310
Notes: sideshowbarker 2024-07-18 17:32:25 +09:00
6 changed files with 60 additions and 75 deletions

View file

@ -45,7 +45,7 @@ void ThreadStackWidget::set_ids(pid_t pid, pid_t tid)
void ThreadStackWidget::refresh()
{
auto symbols = SymbolClient::symbolicate_thread(m_pid, m_tid);
auto symbols = Symbolication::symbolicate_thread(m_pid, m_tid);
StringBuilder builder;

View file

@ -140,6 +140,11 @@ int main(int argc, char** argv)
return 1;
}
if (unveil("/usr/lib", "r") < 0) {
perror("unveil");
return 1;
}
if (unveil("/bin/Profiler", "rx") < 0) {
perror("unveil");
return 1;

View file

@ -2,10 +2,5 @@ set(SOURCES
Client.cpp
)
set(GENERATED_SOURCES
../../Services/SymbolServer/SymbolClientEndpoint.h
../../Services/SymbolServer/SymbolServerEndpoint.h
)
serenity_lib(LibSymbolication symbolclient)
target_link_libraries(LibSymbolication LibIPC)
target_link_libraries(LibSymbolication LibDebug)

View file

@ -7,38 +7,63 @@
#include <AK/JsonArray.h>
#include <AK/JsonObject.h>
#include <AK/JsonValue.h>
#include <AK/MappedFile.h>
#include <LibCore/File.h>
#include <LibDebug/DebugInfo.h>
#include <LibSymbolication/Client.h>
namespace SymbolClient {
namespace Symbolication {
Client::Client()
: IPC::ServerConnection<SymbolClientEndpoint, SymbolServerEndpoint>(*this, "/tmp/portal/symbol")
{
handshake();
}
struct CachedELF {
NonnullRefPtr<MappedFile> mapped_file;
Debug::DebugInfo debug_info;
};
void Client::handshake()
{
greet();
}
static HashMap<String, OwnPtr<CachedELF>> s_cache;
void Client::dummy()
Optional<Symbol> symbolicate(String const& path, u32 address)
{
}
if (!s_cache.contains(path)) {
auto mapped_file = MappedFile::map(path);
if (mapped_file.is_error()) {
dbgln("Failed to map {}: {}", path, mapped_file.error().string());
s_cache.set(path, {});
return {};
}
auto elf = make<ELF::Image>(mapped_file.value()->bytes());
if (!elf->is_valid()) {
dbgln("ELF not valid: {}", path);
s_cache.set(path, {});
{};
}
Debug::DebugInfo debug_info(move(elf));
auto cached_elf = make<CachedELF>(mapped_file.release_value(), move(debug_info));
s_cache.set(path, move(cached_elf));
}
Optional<Symbol> Client::symbolicate(const String& path, FlatPtr address)
{
auto response = IPCProxy::symbolicate(path, address);
if (!response.success())
auto it = s_cache.find(path);
VERIFY(it != s_cache.end());
auto& cached_elf = it->value;
if (!cached_elf)
return {};
u32 offset = 0;
auto symbol = cached_elf->debug_info.elf().symbolicate(address, &offset);
auto source_position = cached_elf->debug_info.get_source_position(address);
String filename;
u32 line_number = 0;
if (source_position.has_value()) {
filename = source_position.value().file_path;
line_number = source_position.value().line_number;
}
return Symbol {
.address = address,
.name = response.name(),
.offset = response.offset(),
.filename = response.filename(),
.line_number = response.line()
.name = move(symbol),
.offset = offset,
.filename = move(filename),
.line_number = line_number
};
}
@ -61,7 +86,6 @@ Vector<Symbol> symbolicate_thread(pid_t pid, pid_t tid)
.is_relative = false });
{
auto stack_path = String::formatted("/proc/{}/stacks/{}", pid, tid);
auto file_or_error = Core::File::open(stack_path, Core::OpenMode::ReadOnly);
if (file_or_error.is_error()) {
@ -121,8 +145,6 @@ Vector<Symbol> symbolicate_thread(pid_t pid, pid_t tid)
}
}
auto client = SymbolClient::Client::construct();
Vector<Symbol> symbols;
for (auto address : stack) {
@ -145,7 +167,7 @@ Vector<Symbol> symbolicate_thread(pid_t pid, pid_t tid)
else
adjusted_address = address;
auto result = client->symbolicate(found_region->path, adjusted_address);
auto result = symbolicate(found_region->path, adjusted_address);
if (!result.has_value()) {
symbols.append(Symbol {
.address = address,

View file

@ -6,11 +6,9 @@
#pragma once
#include <LibIPC/ServerConnection.h>
#include <SymbolServer/SymbolClientEndpoint.h>
#include <SymbolServer/SymbolServerEndpoint.h>
#include <AK/String.h>
namespace SymbolClient {
namespace Symbolication {
struct Symbol {
FlatPtr address { 0 };
@ -21,21 +19,6 @@ struct Symbol {
};
Vector<Symbol> symbolicate_thread(pid_t pid, pid_t tid);
class Client
: public IPC::ServerConnection<SymbolClientEndpoint, SymbolServerEndpoint>
, public SymbolClientEndpoint {
C_OBJECT(Client);
public:
virtual void handshake() override;
Optional<Symbol> symbolicate(const String& path, FlatPtr address);
private:
Client();
virtual void dummy() override;
};
Optional<Symbol> symbolicate(String const& path, FlatPtr address);
}

View file

@ -10,34 +10,14 @@
#include <LibCore/EventLoop.h>
#include <LibCore/File.h>
#include <LibSymbolication/Client.h>
#include <unistd.h>
int main(int argc, char** argv)
{
if (pledge("stdio rpath unix fattr", nullptr) < 0) {
if (pledge("stdio rpath", nullptr) < 0) {
perror("pledge");
return 1;
}
if (unveil("/proc", "r") < 0) {
perror("unveil");
return 1;
}
if (unveil("/tmp/portal/symbol", "rw") < 0) {
perror("unveil");
return 1;
}
if (unveil("/usr/src", "b") < 0) {
perror("unveil");
return 1;
}
if (unveil(nullptr, nullptr) < 0) {
perror("unveil");
return 1;
}
char hostname[256];
if (gethostname(hostname, sizeof(hostname)) < 0) {
perror("gethostname");
@ -48,7 +28,7 @@ int main(int argc, char** argv)
pid_t pid = 0;
args_parser.add_positional_argument(pid, "PID", "pid");
args_parser.parse(argc, argv);
Core::EventLoop loop;
Core::EventLoop loop(Core::EventLoop::MakeInspectable::No);
Core::DirIterator iterator(String::formatted("/proc/{}/stacks", pid), Core::DirIterator::SkipDots);
if (iterator.has_error()) {
@ -59,7 +39,7 @@ int main(int argc, char** argv)
while (iterator.has_next()) {
pid_t tid = iterator.next_path().to_int().value();
outln("tid: {}", tid);
auto symbols = SymbolClient::symbolicate_thread(pid, tid);
auto symbols = Symbolication::symbolicate_thread(pid, tid);
for (auto& symbol : symbols) {
out("{:p} ", symbol.address);
if (!symbol.name.is_empty())