Major reliability improvement for logging stack traces#287
Major reliability improvement for logging stack traces#287
Conversation
1. set_unexpected is supposed to be removed in c++17 2. Need to unwind through the signal trampoline 3. iOS will not allow signal handling in app store, probably
No std, no snprintf, almost nothing is allowed inside a signal handler
It now gets caught in the abort handler
|
|
||
| [[noreturn]] static void sig_handler(int signo, siginfo_t* info, void* context) { | ||
| const char* name = strsignal(signo); | ||
| violation_type() = name ? name : "Signal " + to_string(signo); |
There was a problem hiding this comment.
Ugh, how did this get back in here.....this is not going to be allowed! I need to change this to use write_to_and_stderr
|
|
||
| crash_handler_immediate(info, context); | ||
|
|
||
| signal(signo, SIG_DFL); |
There was a problem hiding this comment.
Need to consider saving the original handler. It might not be SIG_DFL!
| #include "betterassert.hh" | ||
|
|
||
| namespace fleece { | ||
| Backtrace::frameInfo getFrame(const void* addr, bool stack_top) { |
There was a problem hiding this comment.
I'd rather this were a private static member of Backtrace than a standalone function.
| "_C_A_T_C_H____T_E_S_T_", | ||
| "Catch::TestInvokerAsFunction::invoke() const", |
There was a problem hiding this comment.
Have you checked that these names are still valid after we upgraded Catch2?
There was a problem hiding this comment.
I have not. Is there a method you used to determine them in the first place?
| } | ||
| } | ||
|
|
||
| char* unmangle(const char* function) { |
There was a problem hiding this comment.
Likewise, could this be a private static member of Backtrace?
There was a problem hiding this comment.
This was originally not even before my PR. Making it a private static member requires bringing the other Unmangle methods along with it. Is that the outcome you want?
Fleece/Support/Backtrace.hh
Outdated
| void* context = nullptr); | ||
|
|
||
| /// Captures a backtrace from the given starting point and returns a shared pointer to the instance. | ||
| [[nodiscard]] static std::shared_ptr<Backtrace> capture(void* from, unsigned maxFrames = 50, |
There was a problem hiding this comment.
What is from, here? I'm assuming a stack frame or PC address? This seems like too low-level a method to make public.
| [[nodiscard]] static std::shared_ptr<Backtrace> capture(void* from, unsigned maxFrames = 50, | ||
| void* context = nullptr); | ||
|
|
||
| static int raw_capture(void** buffer, int max, void* context = nullptr); |
There was a problem hiding this comment.
Likewise, is there a need to make this public?
There was a problem hiding this comment.
It needs to be callable from the signal handler, as well as from Backtrace itself.
This took many days of effort and so it's involved a lot with various stack unwinding and address retrieval mechanisms so I'll try to provide a high level summary here. Firstly to avoid a giant spaghetti of ifdef I broke out the implementation across several files that only get compiled on certain platforms:
backtrace_symbolsanddladdrsince the implementation on Apple is much more enhanced than the glibc linux counterpart (Most likely the compiler is more friendly about it when it emits machine code).StackWalk64API.Note that since we cannot use ostreams in signal handlers, I created a new crash log in the logs directory that a crash will be written to upon a signal. The existing logs are all buried inside of ofstream objects.