1 // Copyright 2014 Renato Tegon Forti, Antony Polukhin.
2 // Copyright 2015-2016 Antony Polukhin.
4 // Distributed under the Boost Software License, Version 1.0.
5 // (See accompanying file LICENSE_1_0.txt
6 // or copy at http://www.boost.org/LICENSE_1_0.txt)
8 #ifndef BOOST_DLL_RUNTIME_SYMBOL_INFO_HPP
9 #define BOOST_DLL_RUNTIME_SYMBOL_INFO_HPP
11 #include <boost/config.hpp>
12 #include <boost/predef/os.h>
13 #include <boost/predef/compiler/visualc.h>
14 #include <boost/dll/detail/aggressive_ptr_cast.hpp>
16 # include <boost/detail/winapi/dll.hpp>
17 # include <boost/dll/detail/windows/path_from_handle.hpp>
20 # include <boost/dll/detail/posix/program_location_impl.hpp>
23 #ifdef BOOST_HAS_PRAGMA_ONCE
27 /// \file boost/dll/runtime_symbol_info.hpp
28 /// \brief Provides methods for getting acceptable by boost::dll::shared_library location of symbol, source line or program.
29 namespace boost { namespace dll {
33 inline boost::filesystem::path symbol_location_impl(const void* symbol, boost::system::error_code& ec) {
34 boost::filesystem::path ret;
36 boost::detail::winapi::MEMORY_BASIC_INFORMATION_ mbi;
37 if (!boost::detail::winapi::VirtualQuery(symbol, &mbi, sizeof(mbi))) {
38 ec = boost::dll::detail::last_error_code();
42 return boost::dll::detail::path_from_handle(reinterpret_cast<boost::detail::winapi::HMODULE_>(mbi.AllocationBase), ec);
45 inline boost::filesystem::path program_location_impl(boost::system::error_code& ec) {
46 return boost::dll::detail::path_from_handle(NULL, ec);
49 inline boost::filesystem::path symbol_location_impl(const void* symbol, boost::system::error_code& ec) {
50 boost::filesystem::path ret;
53 // Some of the libc headers miss `const` in `dladdr(const void*, Dl_info*)`
54 const int res = dladdr(const_cast<void*>(symbol), &info);
59 boost::dll::detail::reset_dlerror();
60 ec = boost::system::error_code(
61 boost::system::errc::bad_address,
62 boost::system::generic_category()
72 * On success returns full path and name of the binary object that holds symbol.
73 * \tparam T Type of the symbol, must not be explicitly specified.
74 * \param symbol Symbol which location is to be determined.
75 * \param ec Variable that will be set to the result of the operation.
76 * \return Path to the binary object that holds symbol or empty path in case error.
77 * \throws std::bad_alloc in case of insufficient memory. Overload that does not accept boost::system::error_code also throws boost::system::system_error.
85 * dll::symbol_location(var); // returns program location
86 * dll::symbol_location(foo); // returns program location
87 * dll::symbol_location(std::cerr); // returns location of libstdc++: "/usr/lib/x86_64-linux-gnu/libstdc++.so.6"
88 * dll::symbol_location(std::placeholders::_1); // returns location of libstdc++: "/usr/lib/x86_64-linux-gnu/libstdc++.so.6"
89 * dll::symbol_location(std::puts); // returns location of libc: "/lib/x86_64-linux-gnu/libc.so.6"
94 inline boost::filesystem::path symbol_location(const T& symbol, boost::system::error_code& ec) {
96 return boost::dll::detail::symbol_location_impl(
97 boost::dll::detail::aggressive_ptr_cast<const void*>(boost::addressof(symbol)),
102 #if BOOST_COMP_MSVC < BOOST_VERSION_NUMBER(14,0,0)
103 // Without this MSVC 7.1 fails with:
104 // ..\boost\dll\runtime_symbol_info.hpp(133) : error C2780: 'filesystem::path dll::symbol_location(const T &)' : expects 1 arguments - 2 provided
106 inline boost::filesystem::path symbol_location(const T& symbol, const char* /*workaround*/ = 0)
108 //! \overload symbol_location(const T& symbol, boost::system::error_code& ec)
110 inline boost::filesystem::path symbol_location(const T& symbol)
113 boost::filesystem::path ret;
114 boost::system::error_code ec;
115 ret = boost::dll::detail::symbol_location_impl(
116 boost::dll::detail::aggressive_ptr_cast<const void*>(boost::addressof(symbol)),
121 boost::dll::detail::report_error(ec, "boost::dll::symbol_location(const T& symbol) failed");
128 // We have anonymous namespace here to make sure that `this_line_location()` method is instantiated in
129 // current translation module and is not shadowed by instantiations from other modules.
134 * On success returns full path and name of the binary object that holds the current line of code
135 * (the line in which the `this_line_location()` method was called).
137 * \param ec Variable that will be set to the result of the operation.
138 * \throws std::bad_alloc in case of insufficient memory. Overload that does not accept boost::system::error_code also throws boost::system::system_error.
140 static inline boost::filesystem::path this_line_location(boost::system::error_code& ec) {
141 typedef boost::filesystem::path(func_t)(boost::system::error_code& );
142 func_t& f = this_line_location;
143 return boost::dll::symbol_location(f, ec);
146 //! \overload this_line_location(boost::system::error_code& ec)
147 static inline boost::filesystem::path this_line_location() {
148 boost::filesystem::path ret;
149 boost::system::error_code ec;
150 ret = this_line_location(ec);
153 boost::dll::detail::report_error(ec, "boost::dll::this_line_location() failed");
160 } // anonymous namespace
164 * On success returns full path and name of the currently running program (the one which contains the `main()` function).
166 * Return value can be used as a parameter for shared_library. See Tutorial "Linking plugin into the executable"
167 * for usage example. Flag '-rdynamic' must be used when linking the plugin into the executable
170 * \param ec Variable that will be set to the result of the operation.
171 * \throws std::bad_alloc in case of insufficient memory. Overload that does not accept boost::system::error_code also throws boost::system::system_error.
173 inline boost::filesystem::path program_location(boost::system::error_code& ec) {
175 return boost::dll::detail::program_location_impl(ec);
178 //! \overload program_location(boost::system::error_code& ec) {
179 inline boost::filesystem::path program_location() {
180 boost::filesystem::path ret;
181 boost::system::error_code ec;
182 ret = boost::dll::detail::program_location_impl(ec);
185 boost::dll::detail::report_error(ec, "boost::dll::program_location() failed");
191 }} // namespace boost::dll
193 #endif // BOOST_DLL_RUNTIME_SYMBOL_INFO_HPP