Skip to content

Commit 9089e42

Browse files
IronsDuclaude
andauthored
fix: make /pprof/symbol endpoint compatible with Go pprof symbolz protocol (#40)
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 <noreply@anthropic.com>
1 parent ce0338f commit 9089e42

1 file changed

Lines changed: 29 additions & 10 deletions

File tree

src/http_handlers.cpp

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -454,15 +454,34 @@ HandlerResponse ProfilerHttpHandlers::handlePprofGrowth() {
454454
}
455455

456456
HandlerResponse ProfilerHttpHandlers::handlePprofSymbol(const std::string& body) {
457-
std::istringstream iss(body);
458-
std::string address;
459-
std::ostringstream result;
460-
461-
while (std::getline(iss, address)) {
462-
if (address.empty() || address[0] == '#')
463-
continue;
457+
// Go pprof (symbolz protocol) sends addresses separated by '+'
458+
// and expects tab-separated response: "0xaddr\tsymbol_name\n"
459+
// Also support newline-separated addresses for backward compatibility.
460+
461+
std::vector<std::string> addresses;
462+
463+
// Split by '+' first (Go pprof format)
464+
// If no '+' found, fall back to newline splitting
465+
if (body.find('+') != std::string::npos) {
466+
std::istringstream iss(body);
467+
std::string addr;
468+
while (std::getline(iss, addr, '+')) {
469+
if (!addr.empty()) {
470+
addresses.push_back(addr);
471+
}
472+
}
473+
} else {
474+
std::istringstream iss(body);
475+
std::string addr;
476+
while (std::getline(iss, addr)) {
477+
if (!addr.empty() && addr[0] != '#') {
478+
addresses.push_back(addr);
479+
}
480+
}
481+
}
464482

465-
std::string original = address;
483+
std::ostringstream result;
484+
for (const auto& address : addresses) {
466485
std::string addr_str = address;
467486
if (addr_str.size() > 2 && addr_str[0] == '0' && addr_str[1] == 'x') {
468487
addr_str = addr_str.substr(2);
@@ -471,9 +490,9 @@ HandlerResponse ProfilerHttpHandlers::handlePprofSymbol(const std::string& body)
471490
try {
472491
uintptr_t addr = std::stoull(addr_str, nullptr, 16);
473492
std::string symbol = profiler_.resolveSymbolWithBackward(reinterpret_cast<void*>(addr));
474-
result << original << " " << symbol << "\n";
493+
result << address << "\t" << symbol << "\n";
475494
} catch (...) {
476-
result << original << " " << original << "\n";
495+
result << address << "\t" << address << "\n";
477496
}
478497
}
479498

0 commit comments

Comments
 (0)