File indexing completed on 2025-01-18 09:52:30
0001
0002
0003
0004
0005
0006
0007 #ifndef BOOST_STACKTRACE_DETAIL_ADDR_BASE_HPP
0008 #define BOOST_STACKTRACE_DETAIL_ADDR_BASE_HPP
0009
0010 #include <boost/config.hpp>
0011 #ifdef BOOST_HAS_PRAGMA_ONCE
0012 # pragma once
0013 #endif
0014
0015 #include <fstream>
0016 #include <sstream>
0017 #include <cstdint>
0018 #include <cstdlib>
0019
0020 namespace boost { namespace stacktrace { namespace detail {
0021
0022 struct mapping_entry_t {
0023 uintptr_t start = 0;
0024 uintptr_t end = 0;
0025 uintptr_t offset_from_base = 0;
0026
0027 inline bool contains_addr(const void* addr) const {
0028 uintptr_t addr_uint = reinterpret_cast<uintptr_t>(addr);
0029 return addr_uint >= start && addr_uint < end;
0030 }
0031 };
0032
0033 inline uintptr_t hex_str_to_int(const std::string& str) {
0034 uintptr_t out;
0035 std::stringstream ss;
0036 ss << std::hex << str;
0037 ss >> out;
0038 if(ss.eof() && !ss.fail()) {
0039 return out;
0040 } else {
0041 throw std::invalid_argument(std::string("can't convert '") + str + "' to hex");
0042 }
0043 }
0044
0045
0046
0047
0048
0049
0050
0051 inline mapping_entry_t parse_proc_maps_line(const std::string& line) {
0052 std::string mapping_range_str, permissions_str, offset_from_base_str;
0053 std::istringstream line_stream(line);
0054 if(!std::getline(line_stream, mapping_range_str, ' ') ||
0055 !std::getline(line_stream, permissions_str, ' ') ||
0056 !std::getline(line_stream, offset_from_base_str, ' ')) {
0057 return mapping_entry_t{};
0058 }
0059 std::string mapping_start_str, mapping_end_str;
0060 std::istringstream mapping_range_stream(mapping_range_str);
0061 if(!std::getline(mapping_range_stream, mapping_start_str, '-') ||
0062 !std::getline(mapping_range_stream, mapping_end_str)) {
0063 return mapping_entry_t{};
0064 }
0065 mapping_entry_t mapping{};
0066 try {
0067 mapping.start = hex_str_to_int(mapping_start_str);
0068 mapping.end = hex_str_to_int(mapping_end_str);
0069 mapping.offset_from_base = hex_str_to_int(offset_from_base_str);
0070 return mapping;
0071 } catch(std::invalid_argument& e) {
0072 return mapping_entry_t{};
0073 }
0074 }
0075
0076 inline uintptr_t get_own_proc_addr_base(const void* addr) {
0077 std::ifstream maps_file("/proc/self/maps");
0078 for (std::string line; std::getline(maps_file, line); ) {
0079 const mapping_entry_t mapping = parse_proc_maps_line(line);
0080 if (mapping.contains_addr(addr)) {
0081 return mapping.start - mapping.offset_from_base;
0082 }
0083 }
0084 return 0;
0085 }
0086
0087 }}}
0088
0089 #endif