diff --git a/Userland/Applications/SystemMonitor/ThreadStackWidget.cpp b/Userland/Applications/SystemMonitor/ThreadStackWidget.cpp index bf90976cb3..ddef47903b 100644 --- a/Userland/Applications/SystemMonitor/ThreadStackWidget.cpp +++ b/Userland/Applications/SystemMonitor/ThreadStackWidget.cpp @@ -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; diff --git a/Userland/Applications/SystemMonitor/main.cpp b/Userland/Applications/SystemMonitor/main.cpp index 68430a2d19..a50a2f5982 100644 --- a/Userland/Applications/SystemMonitor/main.cpp +++ b/Userland/Applications/SystemMonitor/main.cpp @@ -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; diff --git a/Userland/Libraries/LibSymbolication/CMakeLists.txt b/Userland/Libraries/LibSymbolication/CMakeLists.txt index 09f64acbae..b0428c304c 100644 --- a/Userland/Libraries/LibSymbolication/CMakeLists.txt +++ b/Userland/Libraries/LibSymbolication/CMakeLists.txt @@ -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) diff --git a/Userland/Libraries/LibSymbolication/Client.cpp b/Userland/Libraries/LibSymbolication/Client.cpp index 5d8bf405db..9dbe72473f 100644 --- a/Userland/Libraries/LibSymbolication/Client.cpp +++ b/Userland/Libraries/LibSymbolication/Client.cpp @@ -7,38 +7,63 @@ #include #include #include +#include #include +#include #include -namespace SymbolClient { +namespace Symbolication { -Client::Client() - : IPC::ServerConnection(*this, "/tmp/portal/symbol") -{ - handshake(); -} +struct CachedELF { + NonnullRefPtr mapped_file; + Debug::DebugInfo debug_info; +}; -void Client::handshake() -{ - greet(); -} +static HashMap> s_cache; -void Client::dummy() +Optional 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(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(mapped_file.release_value(), move(debug_info)); + s_cache.set(path, move(cached_elf)); + } -Optional 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 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 symbolicate_thread(pid_t pid, pid_t tid) } } - auto client = SymbolClient::Client::construct(); - Vector symbols; for (auto address : stack) { @@ -145,7 +167,7 @@ Vector 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, diff --git a/Userland/Libraries/LibSymbolication/Client.h b/Userland/Libraries/LibSymbolication/Client.h index b0e2390a43..f969de48a4 100644 --- a/Userland/Libraries/LibSymbolication/Client.h +++ b/Userland/Libraries/LibSymbolication/Client.h @@ -6,11 +6,9 @@ #pragma once -#include -#include -#include +#include -namespace SymbolClient { +namespace Symbolication { struct Symbol { FlatPtr address { 0 }; @@ -21,21 +19,6 @@ struct Symbol { }; Vector symbolicate_thread(pid_t pid, pid_t tid); - -class Client - : public IPC::ServerConnection - , public SymbolClientEndpoint { - C_OBJECT(Client); - -public: - virtual void handshake() override; - - Optional symbolicate(const String& path, FlatPtr address); - -private: - Client(); - - virtual void dummy() override; -}; +Optional symbolicate(String const& path, FlatPtr address); } diff --git a/Userland/Utilities/bt.cpp b/Userland/Utilities/bt.cpp index 399b7823e2..1893d1d41e 100644 --- a/Userland/Utilities/bt.cpp +++ b/Userland/Utilities/bt.cpp @@ -10,34 +10,14 @@ #include #include #include +#include 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())