| 248 | } |
| 249 | |
| 250 | void PProfService::growth( |
| 251 | ::google::protobuf::RpcController* controller_base, |
| 252 | const ::brpc::ProfileRequest* /*request*/, |
| 253 | ::brpc::ProfileResponse* /*response*/, |
| 254 | ::google::protobuf::Closure* done) { |
| 255 | ClosureGuard done_guard(done); |
| 256 | Controller* cntl = static_cast<Controller*>(controller_base); |
| 257 | MallocExtension* malloc_ext = MallocExtension::instance(); |
| 258 | if (malloc_ext == NULL) { |
| 259 | cntl->SetFailed(ENOMETHOD, "%s, to enable growth profiler, check out " |
| 260 | "docs/cn/heap_profiler.md", |
| 261 | berror(ENOMETHOD)); |
| 262 | return; |
| 263 | } |
| 264 | // Log requester |
| 265 | std::ostringstream client_info; |
| 266 | client_info << cntl->remote_side(); |
| 267 | if (cntl->auth_context()) { |
| 268 | client_info << "(auth=" << cntl->auth_context()->user() << ')'; |
| 269 | } else { |
| 270 | client_info << "(no auth)"; |
| 271 | } |
| 272 | LOG(INFO) << client_info.str() << " requests for growth profile"; |
| 273 | |
| 274 | std::string obj; |
| 275 | malloc_ext->GetHeapGrowthStacks(&obj); |
| 276 | cntl->http_response().set_content_type("text/plain"); |
| 277 | cntl->response_attachment().append(obj); |
| 278 | } |
| 279 | |
| 280 | typedef std::map<uintptr_t, std::string> SymbolMap; |
| 281 | struct LibInfo { |