From 45c4969d58080a6417d8cfeaf768b885ba8ec261 Mon Sep 17 00:00:00 2001 From: IronsDu Date: Fri, 10 Apr 2026 11:27:31 +0800 Subject: [PATCH] fix: make /pprof/symbol endpoint compatible with Go pprof symbolz protocol Go pprof sends addresses separated by '+' and expects tab-separated responses (0xaddr\tsymbol_name), but our endpoint only handled newline-separated input and returned space-separated output. This caused remote symbolization to fail when running pprof on Windows against a WSL profiler server. Co-Authored-By: Claude Opus 4.6 --- src/http_handlers.cpp | 39 +++++++++++++++++++++++++++++---------- 1 file changed, 29 insertions(+), 10 deletions(-) diff --git a/src/http_handlers.cpp b/src/http_handlers.cpp index c8b1702..065fe6b 100644 --- a/src/http_handlers.cpp +++ b/src/http_handlers.cpp @@ -454,15 +454,34 @@ HandlerResponse ProfilerHttpHandlers::handlePprofGrowth() { } HandlerResponse ProfilerHttpHandlers::handlePprofSymbol(const std::string& body) { - std::istringstream iss(body); - std::string address; - std::ostringstream result; - - while (std::getline(iss, address)) { - if (address.empty() || address[0] == '#') - continue; + // Go pprof (symbolz protocol) sends addresses separated by '+' + // and expects tab-separated response: "0xaddr\tsymbol_name\n" + // Also support newline-separated addresses for backward compatibility. + + std::vector addresses; + + // Split by '+' first (Go pprof format) + // If no '+' found, fall back to newline splitting + if (body.find('+') != std::string::npos) { + std::istringstream iss(body); + std::string addr; + while (std::getline(iss, addr, '+')) { + if (!addr.empty()) { + addresses.push_back(addr); + } + } + } else { + std::istringstream iss(body); + std::string addr; + while (std::getline(iss, addr)) { + if (!addr.empty() && addr[0] != '#') { + addresses.push_back(addr); + } + } + } - std::string original = address; + std::ostringstream result; + for (const auto& address : addresses) { std::string addr_str = address; if (addr_str.size() > 2 && addr_str[0] == '0' && addr_str[1] == 'x') { addr_str = addr_str.substr(2); @@ -471,9 +490,9 @@ HandlerResponse ProfilerHttpHandlers::handlePprofSymbol(const std::string& body) try { uintptr_t addr = std::stoull(addr_str, nullptr, 16); std::string symbol = profiler_.resolveSymbolWithBackward(reinterpret_cast(addr)); - result << original << " " << symbol << "\n"; + result << address << "\t" << symbol << "\n"; } catch (...) { - result << original << " " << original << "\n"; + result << address << "\t" << address << "\n"; } }