• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright Antony Polukhin, 2016-2020.
2 //
3 // Distributed under the Boost Software License, Version 1.0. (See
4 // accompanying file LICENSE_1_0.txt or copy at
5 // http://www.boost.org/LICENSE_1_0.txt)
6 
7 #ifndef BOOST_STACKTRACE_DETAIL_LOCATION_FROM_SYMBOL_HPP
8 #define BOOST_STACKTRACE_DETAIL_LOCATION_FROM_SYMBOL_HPP
9 
10 #include <boost/config.hpp>
11 #ifdef BOOST_HAS_PRAGMA_ONCE
12 #   pragma once
13 #endif
14 
15 #if !defined(BOOST_WINDOWS) && !defined(__CYGWIN__)
16 #   include <dlfcn.h>
17 #else
18 #   include <boost/winapi/dll.hpp>
19 #endif
20 
21 namespace boost { namespace stacktrace { namespace detail {
22 
23 #if !defined(BOOST_WINDOWS) && !defined(__CYGWIN__)
24 class location_from_symbol {
25     ::Dl_info dli_;
26 
27 public:
location_from_symbol(const void * addr)28     explicit location_from_symbol(const void* addr) BOOST_NOEXCEPT
29         : dli_()
30     {
31         if (!::dladdr(const_cast<void*>(addr), &dli_)) { // `dladdr` on Solaris accepts nonconst addresses
32             dli_.dli_fname = 0;
33         }
34     }
35 
empty() const36     bool empty() const BOOST_NOEXCEPT {
37         return !dli_.dli_fname;
38     }
39 
name() const40     const char* name() const BOOST_NOEXCEPT {
41         return dli_.dli_fname;
42     }
43 };
44 
45 class program_location {
46 public:
name() const47     const char* name() const BOOST_NOEXCEPT {
48         return 0;
49     }
50 };
51 
52 #else
53 
54 class location_from_symbol {
55     BOOST_STATIC_CONSTEXPR boost::winapi::DWORD_ DEFAULT_PATH_SIZE_ = 260;
56     char file_name_[DEFAULT_PATH_SIZE_];
57 
58 public:
59     explicit location_from_symbol(const void* addr) BOOST_NOEXCEPT {
60         file_name_[0] = '\0';
61 
62         boost::winapi::MEMORY_BASIC_INFORMATION_ mbi;
63         if (!boost::winapi::VirtualQuery(addr, &mbi, sizeof(mbi))) {
64             return;
65         }
66 
67         boost::winapi::HMODULE_ handle = reinterpret_cast<boost::winapi::HMODULE_>(mbi.AllocationBase);
68         if (!boost::winapi::GetModuleFileNameA(handle, file_name_, DEFAULT_PATH_SIZE_)) {
69             file_name_[0] = '\0';
70             return;
71         }
72     }
73 
74     bool empty() const BOOST_NOEXCEPT {
75         return file_name_[0] == '\0';
76     }
77 
78     const char* name() const BOOST_NOEXCEPT {
79         return file_name_;
80     }
81 };
82 
83 class program_location {
84     BOOST_STATIC_CONSTEXPR boost::winapi::DWORD_ DEFAULT_PATH_SIZE_ = 260;
85     char file_name_[DEFAULT_PATH_SIZE_];
86 
87 public:
88     program_location() BOOST_NOEXCEPT {
89         file_name_[0] = '\0';
90 
91         const boost::winapi::HMODULE_ handle = 0;
92         if (!boost::winapi::GetModuleFileNameA(handle, file_name_, DEFAULT_PATH_SIZE_)) {
93             file_name_[0] = '\0';
94         }
95     }
96 
97     const char* name() const BOOST_NOEXCEPT {
98         return file_name_[0] ? file_name_ : 0;
99     }
100 };
101 #endif
102 
103 }}} // namespace boost::stacktrace::detail
104 
105 #endif // BOOST_STACKTRACE_DETAIL_LOCATION_FROM_SYMBOL_HPP
106