mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-26 09:30:24 +00:00
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:
parent
d783076a30
commit
252cb54310
Notes:
sideshowbarker
2024-07-18 17:32:25 +09:00
Author: https://github.com/awesomekling Commit: https://github.com/SerenityOS/serenity/commit/252cb543107
6 changed files with 60 additions and 75 deletions
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
|
|
@ -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())
|
||||
|
|
Loading…
Reference in a new issue