| 824 | } |
| 825 | |
| 826 | static std::string debug_resolve_binary( const std::string &binary, std::ostream &out ) |
| 827 | { |
| 828 | if( binary.find( '/' ) != std::string::npos ) { |
| 829 | // The easy case, where we have a path to the binary |
| 830 | return binary; |
| 831 | } |
| 832 | // If the binary name has no slashes then it was found via PATH |
| 833 | // lookup, and we need to do the same to pass the correct name |
| 834 | // to addr2line. An alternative would be to use /proc/self/exe, |
| 835 | // but that's Linux-specific. |
| 836 | // Obviously this will not work in all situations, but it will |
| 837 | // usually do the right thing. |
| 838 | const char *path = std::getenv( "PATH" ); |
| 839 | if( !path ) { |
| 840 | // Should be impossible, but I want to avoid segfaults |
| 841 | // in the crash handler. |
| 842 | out << " backtrace: PATH not set\n"; |
| 843 | return binary; |
| 844 | } |
| 845 | |
| 846 | std::string suffix = "/" + binary; |
| 847 | for( const std::string &path_elem : string_split( path, ':' ) ) { |
| 848 | if( path_elem.empty() ) { |
| 849 | continue; |
| 850 | } |
| 851 | std::string candidate = path_elem + suffix; |
| 852 | if( 0 == access( candidate.c_str(), X_OK ) ) { |
| 853 | return candidate; |
| 854 | } |
| 855 | } |
| 856 | |
| 857 | return binary; |
| 858 | } |
| 859 | |
| 860 | static cata::optional<uintptr_t> debug_compute_load_offset( |
| 861 | const std::string &binary, const std::string &symbol, |
no test coverage detected