]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/dll/doc/missuses.qbk
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / dll / doc / missuses.qbk
1 [/
2 Copyright 2016 Antony Polukhin
3 Distributed under the Boost Software License, Version 1.0.
4 (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5 /]
6
7 [section Missuses]
8
9 [warning Typical errors and missuses are located in this section. Please read carefully, this will save a lot of debugging time!]
10
11 * [*Issue:] Program crashes on `delete` or `free()`.
12 * [*Fix:] Your plugin and program must use the same Standard C++ and C libraries, both must be linked dynamically. For Visual Studio use [@https://msdn.microsoft.com/library/2kzt1wy3%28v=vs.110%29.aspx /MD or /MDd compiler switches].
13
14 [pre
15 ]
16
17
18 * [*Issue:] Program crashes in `catch(...)` block.
19 * [*Example:]
20 ```
21 try {
22 auto f = dll::import<int()>(path_to_pugin, "function");
23 f();
24 // `f` goes out of scope
25 } catch (const std::exception& e) {
26 std::cerr << e.what();
27 }
28 ```
29 * [*Fix:] Exception was generated inside the plugin, so it refers to the exception code in plugin. When `f` goes out of scope, the plugin gets unloaded and the reference to the exception code is broken. Any attempt to use the exception variable may use the dangling reference, leading to a segmentation fault. Fix your code:
30 ```
31 auto f = dll::import<int()>(path_to_pugin, "function");
32 try {
33 f();
34 // `f` goes out of scope
35 } catch (const std::exception& e) {
36 std::cerr << e.what();
37 }
38 ```
39
40 [pre
41 ]
42
43 * [*Issue:] Thread local storage seems to be corrupted.
44 * [*Fix:] Some platforms have no out-of-the-box support for plugins that use TLS, for example [@https://support.microsoft.com/en-us/kb/118816 Windows]. Use platform specific workarounds or just do not use TLS in plugins.
45
46 [pre
47 ]
48
49 * [*Issue:] Attempt to call a loaded function crashes or function returns incorrect result.
50 * [*Fix:] Boost.DLL does not guarantee ABI stability. If you compile plugin and program with different compilers or different compiler switches the function ABI may change and you'll end up with incorrect code.
51
52 [pre
53 ]
54
55 * [*Issue:] Program crashes after plugin unload.
56 * [*Example:]
57 ```
58 void foo() {
59 shared_ptr<int> p;
60 try {
61 auto f = dll::import<shared_ptr<int>()>(path_to_pugin, "function");
62 p = f();
63 // `f` goes out of scope
64 } catch (const std::exception& e) {
65 std::cerr << e.what();
66 }
67 std::cout << *p;
68 // crashes here
69 }
70
71 ```
72 * [*Fix:] In that particular example the problem is within `shared_ptr<int>`. It keeps a type erased deleter, code for that deleter is located in plugin. On destruction of `p`, `shared_ptr<int>` attempts to call that deleter, however the plugin was already unloaded and the code for deleter is not available any more.
73
74 * [*Rule of thumb:]: if your plugin method returns any C++ class variable, then make sure that the plugin is loaded until that variable and any of its copies are in scope.
75
76 * [*Typical classes that cause such errors are:]
77 * `any`
78 * `function`
79 * `shared_ptr`
80 * any container with polymorphic allocator
81 * `std::type_index`
82 * `std::type_info`
83 * `std::exception_ptr`
84 * `std::unique_ptr<Base>` holding a `Derived` type from plugin
85 * exception classes thrown from plugin
86
87 [pre
88 ]
89 [endsect]