]>
Commit | Line | Data |
---|---|---|
7c673cae | 1 | // Copyright 2014 Renato Tegon Forti, Antony Polukhin. |
20effc67 | 2 | // Copyright 2015-2020 Antony Polukhin. |
7c673cae FG |
3 | // |
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) | |
7 | ||
8 | // For more information, see http://www.boost.org | |
9 | ||
10 | #include "../example/b2_workarounds.hpp" | |
11 | #include <boost/dll.hpp> | |
12 | #include <boost/dll/runtime_symbol_info.hpp> | |
13 | #include <boost/filesystem/operations.hpp> | |
14 | ||
15 | #include <boost/core/lightweight_test.hpp> | |
16 | ||
11fdf7f2 TL |
17 | #include <boost/predef/os.h> |
18 | ||
19 | ||
20 | #include <cmath> | |
b32b8144 FG |
21 | #include <exception> // std::set_terminate |
22 | #include <signal.h> // ::signal | |
23 | ||
92f5a8d4 | 24 | // Makes global error variables dirty. Useful for preventing issues like https://github.com/boostorg/dll/issues/16 |
11fdf7f2 TL |
25 | void make_error_code_dirty() { |
26 | using namespace std; | |
92f5a8d4 | 27 | (void)log(-1.0); |
11fdf7f2 TL |
28 | |
29 | #if BOOST_OS_WINDOWS | |
30 | boost::winapi::WCHAR_ path_hldr[10]; | |
31 | int some_invalid_value_for_handle = 0xFF004242; | |
32 | boost::winapi::HMODULE_ some_invalid_handle; | |
33 | memcpy(&some_invalid_handle, &some_invalid_value_for_handle, sizeof(some_invalid_value_for_handle)); | |
34 | boost::winapi::GetModuleFileNameW(some_invalid_handle, path_hldr, 10); | |
35 | #endif | |
36 | } | |
37 | ||
38 | ||
39 | ||
7c673cae FG |
40 | // lib functions |
41 | ||
42 | typedef float (lib_version_func)(); | |
43 | typedef void (say_hello_func) (); | |
44 | typedef int (increment) (int); | |
45 | ||
46 | // exe function | |
47 | extern "C" int BOOST_SYMBOL_EXPORT exef() { | |
48 | return 15; | |
49 | } | |
50 | ||
b32b8144 FG |
51 | |
52 | extern "C" void BOOST_SYMBOL_EXPORT my_terminate_handler() { | |
53 | std::abort(); | |
54 | } | |
55 | ||
56 | extern "C" void BOOST_SYMBOL_EXPORT my_signal_handler(int) { | |
57 | std::abort(); | |
58 | } | |
59 | ||
7c673cae FG |
60 | void internal_function() {} |
61 | int internal_variable = 1; | |
62 | ||
63 | // Unit Tests | |
64 | int main(int argc, char* argv[]) { | |
65 | using namespace boost::dll; | |
66 | ||
92f5a8d4 | 67 | boost::dll::fs::path shared_library_path = b2_workarounds::first_lib_from_argv(argc, argv); |
7c673cae FG |
68 | BOOST_TEST(shared_library_path.string().find("test_library") != std::string::npos); |
69 | ||
11fdf7f2 TL |
70 | make_error_code_dirty(); |
71 | ||
7c673cae FG |
72 | shared_library lib(shared_library_path); |
73 | ||
74 | std::cout << std::endl; | |
75 | std::cout << "shared_library: " << shared_library_path << std::endl; | |
76 | std::cout << "symbol_location: " << symbol_location(lib.get<int>("integer_g")) << std::endl; | |
77 | std::cout << "lib.location(): " << lib.location() << std::endl; | |
78 | BOOST_TEST( | |
79 | symbol_location(lib.get<int>("integer_g")) == lib.location() | |
80 | ); | |
81 | ||
11fdf7f2 TL |
82 | make_error_code_dirty(); |
83 | ||
7c673cae FG |
84 | BOOST_TEST( |
85 | symbol_location(lib.get<say_hello_func>("say_hello")) == lib.location() | |
86 | ); | |
87 | ||
88 | BOOST_TEST( | |
89 | symbol_location(lib.get<lib_version_func>("lib_version")) == lib.location() | |
90 | ); | |
91 | ||
11fdf7f2 TL |
92 | make_error_code_dirty(); |
93 | ||
7c673cae FG |
94 | BOOST_TEST( |
95 | symbol_location(lib.get<const int>("const_integer_g")) == lib.location() | |
96 | ); | |
97 | ||
98 | // Checking that symbols are still available, after another load+unload of the library | |
99 | { shared_library sl2(shared_library_path); } | |
100 | ||
101 | BOOST_TEST( | |
102 | symbol_location(lib.get<int>("integer_g")) == lib.location() | |
103 | ); | |
104 | ||
11fdf7f2 TL |
105 | |
106 | make_error_code_dirty(); | |
107 | ||
7c673cae FG |
108 | // Checking aliases |
109 | BOOST_TEST( | |
110 | symbol_location(lib.get<std::size_t(*)(const std::vector<int>&)>("foo_bar")) == lib.location() | |
111 | ); | |
112 | BOOST_TEST( | |
113 | symbol_location(lib.get_alias<std::size_t(const std::vector<int>&)>("foo_bar")) == lib.location() | |
114 | ); | |
115 | ||
116 | ||
117 | BOOST_TEST( | |
118 | symbol_location(lib.get<std::size_t*>("foo_variable")) == lib.location() | |
119 | ); | |
120 | BOOST_TEST( | |
121 | symbol_location(lib.get_alias<std::size_t>("foo_variable")) == lib.location() | |
122 | ); | |
123 | ||
124 | { // self | |
11fdf7f2 TL |
125 | |
126 | make_error_code_dirty(); | |
127 | ||
7c673cae | 128 | shared_library sl(program_location()); |
11fdf7f2 TL |
129 | |
130 | make_error_code_dirty(); | |
131 | ||
7c673cae | 132 | BOOST_TEST( |
92f5a8d4 | 133 | (boost::dll::fs::equivalent(symbol_location(sl.get<int(void)>("exef")), argv[0])) |
7c673cae FG |
134 | ); |
135 | } | |
136 | ||
137 | { // self with error_code | |
92f5a8d4 | 138 | boost::dll::fs::error_code ec; |
7c673cae FG |
139 | shared_library sl(program_location(ec)); |
140 | BOOST_TEST(!ec); | |
141 | ||
142 | BOOST_TEST( | |
92f5a8d4 | 143 | (boost::dll::fs::equivalent(symbol_location(sl.get<int(void)>("exef"), ec), argv[0])) |
7c673cae FG |
144 | ); |
145 | BOOST_TEST(!ec); | |
146 | ||
147 | symbol_location(&sl.get<int(void)>("exef"), ec); | |
148 | BOOST_TEST(ec); | |
149 | } | |
150 | ||
151 | std::cout << "\ninternal_function: " << symbol_location(internal_function); | |
152 | std::cout << "\nargv[0] : " << boost::filesystem::absolute(argv[0]); | |
153 | BOOST_TEST( | |
92f5a8d4 | 154 | (boost::dll::fs::equivalent(symbol_location(internal_function), argv[0])) |
7c673cae FG |
155 | ); |
156 | ||
157 | BOOST_TEST( | |
92f5a8d4 | 158 | (boost::dll::fs::equivalent(symbol_location(internal_variable), argv[0])) |
7c673cae FG |
159 | ); |
160 | ||
11fdf7f2 | 161 | make_error_code_dirty(); |
7c673cae FG |
162 | |
163 | BOOST_TEST( | |
92f5a8d4 | 164 | (boost::dll::fs::equivalent(this_line_location(), argv[0])) |
7c673cae FG |
165 | ); |
166 | ||
167 | { // this_line_location with error_code | |
92f5a8d4 | 168 | boost::dll::fs::error_code ec; |
11fdf7f2 | 169 | make_error_code_dirty(); |
7c673cae | 170 | BOOST_TEST( |
92f5a8d4 | 171 | (boost::dll::fs::equivalent(this_line_location(ec), argv[0])) |
7c673cae FG |
172 | ); |
173 | BOOST_TEST(!ec); | |
174 | } | |
175 | ||
176 | BOOST_TEST( | |
92f5a8d4 | 177 | lib.get_alias<boost::dll::fs::path()>("module_location_from_itself")() == lib.location() |
7c673cae FG |
178 | ); |
179 | ||
180 | // Checking docs content | |
181 | std::cout << "\nsymbol_location(std::cerr); // " << symbol_location(std::cerr); | |
182 | std::cout << "\nsymbol_location(std::puts); // " << symbol_location(std::puts); | |
b32b8144 FG |
183 | |
184 | std::set_terminate(&my_terminate_handler); | |
92f5a8d4 | 185 | BOOST_TEST((boost::dll::fs::equivalent( |
b32b8144 FG |
186 | symbol_location_ptr(std::set_terminate(0)), |
187 | argv[0] | |
188 | ))); | |
189 | ||
190 | { | |
92f5a8d4 TL |
191 | boost::dll::fs::error_code ec; |
192 | boost::dll::fs::path p = symbol_location_ptr(std::set_terminate(0), ec); | |
b32b8144 FG |
193 | BOOST_TEST(ec || !p.empty()); |
194 | } | |
195 | ||
196 | { | |
92f5a8d4 | 197 | boost::dll::fs::error_code ec; |
b32b8144 FG |
198 | symbol_location(std::set_terminate(0), ec), |
199 | BOOST_TEST(ec); | |
200 | } | |
201 | ||
202 | { | |
203 | std::set_terminate(&my_terminate_handler); | |
92f5a8d4 | 204 | boost::dll::fs::error_code ec; |
11fdf7f2 | 205 | make_error_code_dirty(); |
b32b8144 FG |
206 | symbol_location(std::set_terminate(0), ec), |
207 | BOOST_TEST(ec); | |
208 | } | |
209 | ||
210 | { | |
92f5a8d4 | 211 | boost::dll::fs::error_code ec; |
b32b8144 | 212 | ::signal(SIGSEGV, &my_signal_handler); |
92f5a8d4 TL |
213 | boost::dll::fs::path p = symbol_location_ptr(::signal(SIGSEGV, SIG_DFL), ec); |
214 | BOOST_TEST((boost::dll::fs::equivalent( | |
b32b8144 FG |
215 | p, |
216 | argv[0] | |
217 | )) || ec); | |
218 | } | |
219 | ||
220 | { | |
221 | ::signal(SIGSEGV, &my_signal_handler); | |
92f5a8d4 | 222 | boost::dll::fs::error_code ec; |
11fdf7f2 | 223 | make_error_code_dirty(); |
b32b8144 FG |
224 | symbol_location(::signal(SIGSEGV, SIG_DFL), ec); |
225 | BOOST_TEST(ec); | |
226 | } | |
227 | ||
228 | ||
7c673cae FG |
229 | return boost::report_errors(); |
230 | } | |
231 |