Add shared library warmup
This commit is contained in:
parent
7c49e64ba6
commit
a6a64b5671
@ -423,6 +423,10 @@ namespace cpptrace {
|
|||||||
`safe_generate_raw_trace` will just produce an empty trace and if object information can't be resolved in a signal-safe
|
`safe_generate_raw_trace` will just produce an empty trace and if object information can't be resolved in a signal-safe
|
||||||
way then `get_minimal_object_frame` will not populate fields beyond the `raw_address`.
|
way then `get_minimal_object_frame` will not populate fields beyond the `raw_address`.
|
||||||
|
|
||||||
|
**Another big note:** Calls to shared objects can be lazy-loaded where the first call to the shared object invokes
|
||||||
|
non-signal-safe functions such as `malloc()`. To avoid this, call these routines in `main()` ahead of a signal handler
|
||||||
|
to "warm up" the library.
|
||||||
|
|
||||||
Because signal-safe tracing is an involved process, I have written up a comprehensive overview of
|
Because signal-safe tracing is an involved process, I have written up a comprehensive overview of
|
||||||
what is involved at [signal-safe-tracing.md](signal-safe-tracing.md).
|
what is involved at [signal-safe-tracing.md](signal-safe-tracing.md).
|
||||||
|
|
||||||
|
|||||||
@ -80,6 +80,12 @@ Currently the only back-end that can unwind safely is libunwind. Currently, the
|
|||||||
information in a signal-safe manner is `_dl_find_object`, which doesn't exist on macos (or windows of course). If anyone
|
information in a signal-safe manner is `_dl_find_object`, which doesn't exist on macos (or windows of course). If anyone
|
||||||
knows ways to do these safely on other platforms, I'd be much appreciative.
|
knows ways to do these safely on other platforms, I'd be much appreciative.
|
||||||
|
|
||||||
|
# A pitfall to be aware of
|
||||||
|
|
||||||
|
Calls to functions in shared objects can be lazy-loaded where the first call to the shared object invokes
|
||||||
|
non-signal-safe functions such as `malloc()`. To avoid this, call these safe cpptrace routines in `main()` ahead of a
|
||||||
|
signal handler to "warm up" the library.
|
||||||
|
|
||||||
# Signal-Safe Tracing With `fork()` + `exec()`
|
# Signal-Safe Tracing With `fork()` + `exec()`
|
||||||
|
|
||||||
Of the three strategies, `fork()` + `exec()`, is the most technically involved and the only way to resolve while the
|
Of the three strategies, `fork()` + `exec()`, is the most technically involved and the only way to resolve while the
|
||||||
@ -96,6 +102,8 @@ The main program handles most of the complexity for tracing from signal handlers
|
|||||||
- Resolving raw frame pointers to minimal object frames
|
- Resolving raw frame pointers to minimal object frames
|
||||||
- Sending that info to the other process
|
- Sending that info to the other process
|
||||||
|
|
||||||
|
Also note: A warmup for the library is done in main.
|
||||||
|
|
||||||
A basic implementation is as follows:
|
A basic implementation is as follows:
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
@ -155,7 +163,16 @@ void handler(int signo, siginfo_t* info, void* context) {
|
|||||||
_exit(1);
|
_exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void warmup_cpptrace() {
|
||||||
|
// This is done for any dynamic-loading shenanigans
|
||||||
|
cpptrace::frame_ptr buffer[10];
|
||||||
|
std::size_t count = cpptrace::safe_generate_raw_trace(buffer, 10);
|
||||||
|
cpptrace::minimal_object_frame frame;
|
||||||
|
cpptrace::get_minimal_object_frame(buffer[0], &frame);
|
||||||
|
}
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
|
warmup_cpptrace();
|
||||||
// Setup signal handler
|
// Setup signal handler
|
||||||
struct sigaction action = { 0 };
|
struct sigaction action = { 0 };
|
||||||
action.sa_flags = 0;
|
action.sa_flags = 0;
|
||||||
|
|||||||
@ -65,9 +65,17 @@ void handler(int signo, siginfo_t* info, void* context) {
|
|||||||
_exit(1);
|
_exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void warmup_cpptrace() {
|
||||||
|
cpptrace::frame_ptr buffer[10];
|
||||||
|
std::size_t count = cpptrace::safe_generate_raw_trace(buffer, 10);
|
||||||
|
cpptrace::minimal_object_frame frame;
|
||||||
|
cpptrace::get_minimal_object_frame(buffer[0], &frame);
|
||||||
|
}
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
cpptrace::absorb_trace_exceptions(false);
|
cpptrace::absorb_trace_exceptions(false);
|
||||||
cpptrace::register_terminate_handler();
|
cpptrace::register_terminate_handler();
|
||||||
|
warmup_cpptrace();
|
||||||
|
|
||||||
struct sigaction action = { 0 };
|
struct sigaction action = { 0 };
|
||||||
action.sa_flags = 0;
|
action.sa_flags = 0;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user