|
34 | 34 | //! object being thrown, and to decide whether it should be caught at that stack
|
35 | 35 | //! frame. Once the handler frame has been identified, cleanup phase begins.
|
36 | 36 | //!
|
37 |
| -//! In the cleanup phase, personality routines invoke cleanup code associated |
38 |
| -//! with their stack frames (i.e. destructors). Once stack has been unwound down |
39 |
| -//! to the handler frame level, unwinding stops and the last personality routine |
40 |
| -//! transfers control to its catch block. |
| 37 | +//! In the cleanup phase, the unwinder invokes each personality routine again. |
| 38 | +//! This time it decides which (if any) cleanup code needs to be run for |
| 39 | +//! the current stack frame. If so, the control is transferred to a special branch |
| 40 | +//! in the function body, the "landing pad", which invokes destructors, frees memory, |
| 41 | +//! etc. At the end of the landing pad, control is transferred back to the unwinder |
| 42 | +//! and unwinding resumes. |
41 | 43 | //!
|
42 |
| -//! ## Frame unwind info registration |
| 44 | +//! Once stack has been unwound down to the handler frame level, unwinding stops |
| 45 | +//! and the last personality routine transfers control to the catch block. |
43 | 46 | //!
|
44 |
| -//! Each module has its own frame unwind info section (usually ".eh_frame"), and |
45 |
| -//! unwinder needs to know about all of them in order for unwinding to be able to |
46 |
| -//! cross module boundaries. |
| 47 | +//! ## `eh_personality` and `eh_unwind_resume` |
47 | 48 | //!
|
48 |
| -//! On some platforms, like Linux, this is achieved by dynamically enumerating |
49 |
| -//! currently loaded modules via the dl_iterate_phdr() API and finding all |
50 |
| -//! .eh_frame sections. |
| 49 | +//! These language items are used by the compiler when generating unwind info. |
| 50 | +//! The first one is the personality routine described above. The second one |
| 51 | +//! allows compilation target to customize the process of resuming unwind at the |
| 52 | +//! end of the landing pads. `eh_unwind_resume` is used only if `custom_unwind_resume` |
| 53 | +//! flag in the target options is set. |
51 | 54 | //!
|
52 |
| -//! Others, like Windows, require modules to actively register their unwind info |
53 |
| -//! sections by calling __register_frame_info() API at startup. In the latter |
54 |
| -//! case it is essential that there is only one copy of the unwinder runtime in |
55 |
| -//! the process. This is usually achieved by linking to the dynamic version of |
56 |
| -//! the unwind runtime. |
| 55 | +//! ## Frame unwind info registration |
57 | 56 | //!
|
58 |
| -//! Currently Rust uses unwind runtime provided by libgcc. |
| 57 | +//! Each module's image contains a frame unwind info section (usually ".eh_frame"). |
| 58 | +//! When a module is loaded/unloaded into the process, the unwinder must be informed |
| 59 | +//! about the location of this section in memory. The methods of achieving that vary |
| 60 | +//! by the platform. |
| 61 | +//! On some (e.g. Linux), the unwinder can discover unwind info sections on its own |
| 62 | +//! (by dynamically enumerating currently loaded modules via the dl_iterate_phdr() API |
| 63 | +//! and finding their ".eh_frame" sections); |
| 64 | +//! Others, like Windows, require modules to actively register their unwind info |
| 65 | +//! sections via unwinder API (see `rust_eh_register_frames`/`rust_eh_unregister_frames`). |
59 | 66 |
|
60 | 67 | #![allow(dead_code)]
|
61 | 68 | #![allow(unused_imports)]
|
|
0 commit comments