| 544 | } |
| 545 | |
| 546 | std::string |
| 547 | getBuildId(const std::string& filename) |
| 548 | { |
| 549 | if (elf_version(EV_CURRENT) == EV_NONE) { |
| 550 | LOG(ERROR) << "libelf library ELF version too old"; |
| 551 | return ""; |
| 552 | } |
| 553 | |
| 554 | if (!fs::exists(filename)) { |
| 555 | LOG(DEBUG) << filename << " does not exist"; |
| 556 | return ""; |
| 557 | } |
| 558 | |
| 559 | LOG(DEBUG) << "Trying to locate .PyRuntime data offset from program headers"; |
| 560 | file_unique_ptr file(fopen(filename.c_str(), "r"), fclose); |
| 561 | if (!file || fileno(file.get()) == -1) { |
| 562 | LOG(ERROR) << "Cannot open ELF file " << filename << " (" << std::strerror(errno) << ")"; |
| 563 | return ""; |
| 564 | } |
| 565 | const int fd = fileno(file.get()); |
| 566 | |
| 567 | elf_unique_ptr elf = elf_unique_ptr(elf_begin(fd, ELF_C_READ_MMAP, nullptr), elf_end); |
| 568 | if (!elf) { |
| 569 | LOG(ERROR) << "Cannot read ELF file " << filename; |
| 570 | return ""; |
| 571 | } |
| 572 | |
| 573 | Elf* the_elf = elf.get(); |
| 574 | |
| 575 | const void* build_idp = nullptr; |
| 576 | ssize_t elf_build_id_len = dwelf_elf_gnu_build_id(the_elf, &build_idp); |
| 577 | if (elf_build_id_len <= 0) { |
| 578 | return ""; |
| 579 | } |
| 580 | return buildIdPtrToString(reinterpret_cast<const unsigned char*>(build_idp), elf_build_id_len); |
| 581 | } |
| 582 | |
| 583 | } // namespace pystack |
no test coverage detected