Closed xuezhulian closed 2 months ago
Please provide a detailed description of the problem. I am particularly interested in the monitors and flags used in the installation.
Additionally, even if we hook __cxa_throw, due to the dyld shared cache, some system libraries will still fail, resulting in some C++ stack traces being unobtainable. I am currently working on solving this issue, and once the solution is stable and reliable, I will discuss it with you further.
It looks like __attribute__ ((weak))
doesn't work with SPM, probably because of Clang modules. When only CocoaPods was used and a podspec was a single module, this attribute worked fine. It does work with SPM if you remove the attribute, but that can cause symbol duplicates, which isn't ideal. So, the only good method left for SPM seems to be a fishhook-like swap. Both @bamx23 and I are thinking of enabling this by default for C++. The latest update has made this solution more flexible, keeping up with Apple's constant changes to the Mach-O layout.
👍🏻 In fact, we've been using fishhook to replace __cxa_throw for quite some time now. Here's a suggestion: don't perform this operation at startup, as it might trigger the watchdog.
Here's a suggestion: don't perform this operation at startup, as it might trigger the watchdog.
We thought about moving it to a separate thread. Would that help with startup performance?
The approach I'm currently using involves an asynchronous thread with a delay. Fishhook frequently calls dyld's APIs, which use global locks. During the app startup process, loading dyld also involves these locks. Executing fishhook during this process might cause the main thread to wait for these locks.
For some reason, my checks show that accessing symbols and checking memory protection takes up most of the time.
Due to time constraints, I am unable to locate the previous watchdog stack trace. From what I remember, this issue has never been reproduced offline, and the lengthy duration is caused by the page fault.
@xuezhulian let's fix PR checks and merge
@GLinnik21 @bamx23 Thank you for your modification suggestions. It seems that the lint failure is due to a timeout, but I haven't found an option to retry.
@xuezhulian thanks for your contribution!
There are numerous C++ exceptions in the iOS system that are caught and then rethrown by the system, or caught and directly terminated. Therefore, obtaining a C++ crash stack trace on iOS is relatively troublesome. A common solution is to hook
__cxa_throw
.In KSCrash, there are two ways to implement the hook. When
g_cxaSwapEnabled
is true, a technique similar to fishhook or dyld interposing is used to implement the hook. At the same time,__cxa_throw
is also overridden. This method only works for the main executable file. When obtaining the stack trace in the hooked__cxa_throw
method, it is stored in a global variable and is not thread-local. When multiple crashes are triggered, incorrect stack traces may be obtained. Therefore, it is necessary to reduce method reentry for__cxa_throw
.For NSException, the stack trace can be obtained through system APIs, and it is not necessary to obtain it in
__cxa_throw
. Therefore, this filtering is valuable and also provides some performance optimization.