]>
Commit | Line | Data |
---|---|---|
1 | // Copyright 2014 Renato Tegon Forti, Antony Polukhin. | |
2 | // Copyright 2015-2017 Antony Polukhin. | |
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 | ||
17 | #include <exception> // std::set_terminate | |
18 | #include <signal.h> // ::signal | |
19 | ||
20 | // lib functions | |
21 | ||
22 | typedef float (lib_version_func)(); | |
23 | typedef void (say_hello_func) (); | |
24 | typedef int (increment) (int); | |
25 | ||
26 | // exe function | |
27 | extern "C" int BOOST_SYMBOL_EXPORT exef() { | |
28 | return 15; | |
29 | } | |
30 | ||
31 | ||
32 | extern "C" void BOOST_SYMBOL_EXPORT my_terminate_handler() { | |
33 | std::abort(); | |
34 | } | |
35 | ||
36 | extern "C" void BOOST_SYMBOL_EXPORT my_signal_handler(int) { | |
37 | std::abort(); | |
38 | } | |
39 | ||
40 | void internal_function() {} | |
41 | int internal_variable = 1; | |
42 | ||
43 | // Unit Tests | |
44 | int main(int argc, char* argv[]) { | |
45 | using namespace boost::dll; | |
46 | ||
47 | boost::filesystem::path shared_library_path = b2_workarounds::first_lib_from_argv(argc, argv); | |
48 | BOOST_TEST(shared_library_path.string().find("test_library") != std::string::npos); | |
49 | ||
50 | shared_library lib(shared_library_path); | |
51 | ||
52 | std::cout << std::endl; | |
53 | std::cout << "shared_library: " << shared_library_path << std::endl; | |
54 | std::cout << "symbol_location: " << symbol_location(lib.get<int>("integer_g")) << std::endl; | |
55 | std::cout << "lib.location(): " << lib.location() << std::endl; | |
56 | BOOST_TEST( | |
57 | symbol_location(lib.get<int>("integer_g")) == lib.location() | |
58 | ); | |
59 | ||
60 | BOOST_TEST( | |
61 | symbol_location(lib.get<say_hello_func>("say_hello")) == lib.location() | |
62 | ); | |
63 | ||
64 | BOOST_TEST( | |
65 | symbol_location(lib.get<lib_version_func>("lib_version")) == lib.location() | |
66 | ); | |
67 | ||
68 | BOOST_TEST( | |
69 | symbol_location(lib.get<const int>("const_integer_g")) == lib.location() | |
70 | ); | |
71 | ||
72 | // Checking that symbols are still available, after another load+unload of the library | |
73 | { shared_library sl2(shared_library_path); } | |
74 | ||
75 | BOOST_TEST( | |
76 | symbol_location(lib.get<int>("integer_g")) == lib.location() | |
77 | ); | |
78 | ||
79 | // Checking aliases | |
80 | BOOST_TEST( | |
81 | symbol_location(lib.get<std::size_t(*)(const std::vector<int>&)>("foo_bar")) == lib.location() | |
82 | ); | |
83 | BOOST_TEST( | |
84 | symbol_location(lib.get_alias<std::size_t(const std::vector<int>&)>("foo_bar")) == lib.location() | |
85 | ); | |
86 | ||
87 | ||
88 | BOOST_TEST( | |
89 | symbol_location(lib.get<std::size_t*>("foo_variable")) == lib.location() | |
90 | ); | |
91 | BOOST_TEST( | |
92 | symbol_location(lib.get_alias<std::size_t>("foo_variable")) == lib.location() | |
93 | ); | |
94 | ||
95 | { // self | |
96 | shared_library sl(program_location()); | |
97 | BOOST_TEST( | |
98 | (boost::filesystem::equivalent(symbol_location(sl.get<int(void)>("exef")), argv[0])) | |
99 | ); | |
100 | } | |
101 | ||
102 | { // self with error_code | |
103 | boost::system::error_code ec; | |
104 | shared_library sl(program_location(ec)); | |
105 | BOOST_TEST(!ec); | |
106 | ||
107 | BOOST_TEST( | |
108 | (boost::filesystem::equivalent(symbol_location(sl.get<int(void)>("exef"), ec), argv[0])) | |
109 | ); | |
110 | BOOST_TEST(!ec); | |
111 | ||
112 | symbol_location(&sl.get<int(void)>("exef"), ec); | |
113 | BOOST_TEST(ec); | |
114 | } | |
115 | ||
116 | std::cout << "\ninternal_function: " << symbol_location(internal_function); | |
117 | std::cout << "\nargv[0] : " << boost::filesystem::absolute(argv[0]); | |
118 | BOOST_TEST( | |
119 | (boost::filesystem::equivalent(symbol_location(internal_function), argv[0])) | |
120 | ); | |
121 | ||
122 | BOOST_TEST( | |
123 | (boost::filesystem::equivalent(symbol_location(internal_variable), argv[0])) | |
124 | ); | |
125 | ||
126 | ||
127 | BOOST_TEST( | |
128 | (boost::filesystem::equivalent(this_line_location(), argv[0])) | |
129 | ); | |
130 | ||
131 | { // this_line_location with error_code | |
132 | boost::system::error_code ec; | |
133 | BOOST_TEST( | |
134 | (boost::filesystem::equivalent(this_line_location(ec), argv[0])) | |
135 | ); | |
136 | BOOST_TEST(!ec); | |
137 | } | |
138 | ||
139 | BOOST_TEST( | |
140 | lib.get_alias<boost::filesystem::path()>("module_location_from_itself")() == lib.location() | |
141 | ); | |
142 | ||
143 | // Checking docs content | |
144 | std::cout << "\nsymbol_location(std::cerr); // " << symbol_location(std::cerr); | |
145 | std::cout << "\nsymbol_location(std::puts); // " << symbol_location(std::puts); | |
146 | ||
147 | std::set_terminate(&my_terminate_handler); | |
148 | BOOST_TEST((boost::filesystem::equivalent( | |
149 | symbol_location_ptr(std::set_terminate(0)), | |
150 | argv[0] | |
151 | ))); | |
152 | ||
153 | { | |
154 | boost::system::error_code ec; | |
155 | boost::filesystem::path p = symbol_location_ptr(std::set_terminate(0), ec); | |
156 | BOOST_TEST(ec || !p.empty()); | |
157 | } | |
158 | ||
159 | { | |
160 | boost::system::error_code ec; | |
161 | symbol_location(std::set_terminate(0), ec), | |
162 | BOOST_TEST(ec); | |
163 | } | |
164 | ||
165 | { | |
166 | std::set_terminate(&my_terminate_handler); | |
167 | boost::system::error_code ec; | |
168 | symbol_location(std::set_terminate(0), ec), | |
169 | BOOST_TEST(ec); | |
170 | } | |
171 | ||
172 | { | |
173 | boost::system::error_code ec; | |
174 | ::signal(SIGSEGV, &my_signal_handler); | |
175 | boost::filesystem::path p = symbol_location_ptr(::signal(SIGSEGV, SIG_DFL), ec); | |
176 | BOOST_TEST((boost::filesystem::equivalent( | |
177 | p, | |
178 | argv[0] | |
179 | )) || ec); | |
180 | } | |
181 | ||
182 | { | |
183 | ::signal(SIGSEGV, &my_signal_handler); | |
184 | boost::system::error_code ec; | |
185 | symbol_location(::signal(SIGSEGV, SIG_DFL), ec); | |
186 | BOOST_TEST(ec); | |
187 | } | |
188 | ||
189 | ||
190 | return boost::report_errors(); | |
191 | } | |
192 |