| 400 | } |
| 401 | |
| 402 | static void LoadSymbols() { |
| 403 | butil::Timer tm; |
| 404 | tm.start(); |
| 405 | butil::ScopedFILE fp(fopen("/proc/self/maps", "r")); |
| 406 | if (fp == NULL) { |
| 407 | return; |
| 408 | } |
| 409 | char* line = NULL; |
| 410 | size_t line_len = 0; |
| 411 | ssize_t nr = 0; |
| 412 | while ((nr = getline(&line, &line_len, fp.get())) != -1) { |
| 413 | butil::StringSplitter sp(line, line + nr, ' '); |
| 414 | if (sp == NULL) { |
| 415 | continue; |
| 416 | } |
| 417 | char* endptr; |
| 418 | uintptr_t start_addr = strtoull(sp.field(), &endptr, 16); |
| 419 | if (*endptr != '-') { |
| 420 | continue; |
| 421 | } |
| 422 | ++endptr; |
| 423 | uintptr_t end_addr = strtoull(endptr, &endptr, 16); |
| 424 | if (*endptr != ' ') { |
| 425 | continue; |
| 426 | } |
| 427 | ++sp; |
| 428 | // ..x. must be executable |
| 429 | if (sp == NULL || sp.length() != 4 || sp.field()[2] != 'x') { |
| 430 | continue; |
| 431 | } |
| 432 | ++sp; |
| 433 | if (sp == NULL) { |
| 434 | continue; |
| 435 | } |
| 436 | size_t offset = strtoull(sp.field(), &endptr, 16); |
| 437 | if (*endptr != ' ') { |
| 438 | continue; |
| 439 | } |
| 440 | //skip $4~$5 |
| 441 | for (int i = 0; i < 3; ++i) { |
| 442 | ++sp; |
| 443 | } |
| 444 | if (sp == NULL) { |
| 445 | continue; |
| 446 | } |
| 447 | size_t n = sp.length(); |
| 448 | if (sp.field()[n-1] == '\n') { |
| 449 | --n; |
| 450 | } |
| 451 | std::string path(sp.field(), n); |
| 452 | if (!HasExt(path, ".so") && !HasExt(path, ".dll") && |
| 453 | !HasExt(path, ".dylib") && !HasExt(path, ".bundle")) { |
| 454 | continue; |
| 455 | } |
| 456 | LibInfo info; |
| 457 | info.start_addr = start_addr; |
| 458 | info.end_addr = end_addr; |
| 459 | info.offset = offset; |
nothing calls this directly
no test coverage detected