يبدو أنه لا يتم استدعاء وظيفة __cxa_throw في KSCrashMonitor_CPPException.c عند طرح استثناء C ++ في إطار عمل مضمن ، على سبيل المثال CrashLib في تطبيق Crash-Tester.
لم أتمكن من التوصل إلى حل لهذا. بالنسبة لي ، يبدو أن أي مكتبة مضمنة ستستخدم دائمًا __cxa_throw من libc ++ ، وليس التنفيذ في KSCrash.
بالإضافة إلى ذلك: عند طرح استثناء C ++ غير معالج في إطار عمل مضمن ، سوف يتعطل KSCrash أثناء الإبلاغ ، نظرًا لأن stackCursor-> advanceCursor سيساوي NULL في KSCrashReport.c: writeBacktrace ().
تحرير: المعلومات المضافة KSCrash تحطم أثناء الإبلاغ.
أي حظ مع هذا؟ أحاول دمج KSCrash في تطبيقي ، لكنني عالق بسبب الإطار المضمن.
يرجى إعلامي إذا كان لديك أي حل لهذا الغرض.
لا حظ ، ولا أعتقد أنه ممكن ، على الأقل ليس في حالة الاستخدام لدينا. هذا هو فهمي للوضع:
الطريقة التي يسجل بها KSCrash تتبع المكدس هي عن طريق إنشاء تطبيقه الخاص لـ __cxa_throw ، والذي يسمح بالوصول إلى المكدس قبل أن يتم التخلص منه بواسطة libc ++. يعمل هذا طالما أن KSCrash مرتبط بشكل ثابت برمز C ++ ، حيث سيجد الرابط ويستخدم __cxa_throw form KSCrash بدلاً من التنفيذ في libc ++. ولكن في حالة وجود إطار عمل مضمن يرتبط بـ libc ++ ، فسيتم استخدام تنفيذ __cxa_throw من libc ++ ، نظرًا لأن إطار العمل لا يعرف الكود في KSCrash. ربما يكون هناك حل بديل إذا كنت تتحكم في إطار العمل المضمن ، لكن هذا لن ينجح في حالة الاستخدام الخاصة بنا.
واسمحوا لي أن أعرف إذا وجدت حلا.
لدي سيطرة على الإطار المضمن. لكن لست متأكدًا من كيفية إصلاحه.
لقد جربت أيضًا PLCrashReporter ، نفس المشكلة معها.
هل هذا يعني أنه يجب بناء KSCrash بشكل مثالي كمكتبة ثابتة وربطها بالتطبيق ، على الأقل للقبض على استثناءات C ++ التي تم إلقاؤها في كود التطبيق؟
لكن هذا من شأنه أن يترك أي استثناءات تم إلقاؤها في أي مكتبة ديناميكية غير معلومة بواسطة KSCrash إذا فهمت تقرير الخطأ الخاص بك بشكل صحيح pdrtrifork ؟ إذا كنا نتحكم في libs الديناميكية المضمنة ، فهل يمكننا الربط في lib ثابت بكل منها باستخدام هذا __cxa_throw stub فقط ، والذي من شأنه أن يرجح إلى معالج KSCrash المشترك؟
هاه ، لذا عند التحقيق في هذا انتهى بي الأمر هنا http://stackoverflow.com/questions/36846628/conditionally-overriding-cxa-throw ، والذي تم افتتاحه بواسطة kstenerud الخاص بنا 😄
على أي حال ، يجب أن يمنع PR # 219 على الأقل التعطل أثناء الإبلاغ عن الأعطال.
kstenerud أعتقد أنه يجب إعادة تسمية هذه المشكلة إلى شيء مثل _ "تتبعات المكدس المفقودة لاستثناءات C ++ التي تم إلقاؤها من الصور غير المرتبطة بشكل ثابت بـ KSCrash" _. بقدر ما أستطيع أن أقول ، فإن تجاوز __cxa_throw
يعمل فقط في نفس الصورة مثل KSCrash ، لذلك:
سيؤثر الأخير على العملاء مثل sentry-swift
، https://docs.sentry.io/clients/cocoa/ ، والذي يدمج KSCrash كإطار عمل.
بعد مزيد من التحقيق ، يبدو أن تعليقي السابق كان غير صحيح:
أعتقد أنه يجب إعادة تسمية هذه المشكلة إلى شيء مثل _ "تتبعات المكدس المفقودة لاستثناءات C ++ التي تم إلقاؤها من الصور غير المرتبطة بشكل ثابت بـ KSCrash" _.
في حالة ربط KSCrash بالتطبيق الرئيسي كمكتبة ثابتة:
MyApplication
( main.o
، libKSCrash.a
)libDynamicLibrary.dylib
( lib.o
)/usr/lib/libc++abi.dylib
أي استثناءات يتم طرحها من MyApplication
ستدخل libKSCrash.a::__cxa_throw
. في الإضافات ، نظرًا لأن libKSCrash.a
يعلن __cxa_throw
كـ weak
، لا يفشل ربط MyApplication
إذا كان main.o
يمتلك __cxa_throw
تجاوز libDynamicLibrary.dylib
لن تؤدي إلى تشغيل libKSCrash.a::__cxa_throw
، وستنتهي في /usr/lib/libc++abi.dylib::__cxa_throw
.
في حالة ربط KSCrash بالتطبيق الرئيسي كمكتبة ديناميكية:
MyApplication
( main.o
)libKSCrash.dylib
/usr/lib/libc++abi.dylib
libDynamicLibrary.dylib
( lib.o
)/usr/lib/libc++abi.dylib
أي استثناءات يتم طرحها من MyApplication
ستدخل libKSCrash.dylib::__cxa_throw
، ولكن فقط إذا:
__cxa_throw
من libKSCrash.dylib
__cxa_throw
لم يتم تمييزه كـ weak
إذا تم تمييز __cxa_throw
كـ weak
( 0000000000002e90 (__TEXT,__text) weak external ___cxa_throw
) ، فعند ربط libKSCrash.dylib
يبدو الرابط وكأنه ينظر إلى /usr/lib/libc++abi.dylib
، ابحث عن غير - ضعيف __cxa_throw
، واستنتج أنه يجب تجاهل libKSCrash.dylib::__cxa_throw
. أثناء البحث عن رمز وقت التشغيل في وقت العرض من MyApplication
، ثم يتم تجاهل libKSCrash.dylib::__cxa_throw
.
يقودني هذا إلى الاعتقاد بأنه يجب إضافة السمة weak
بشكل مشروط فقط عند إنشاء KSCrash كمكتبة ثابتة.
كما هو الحال بالنسبة لحالة الاستخدام الأولى ، فإن أي استثناءات يتم طرحها من libDynamicLibrary.dylib
لن تؤدي إلى libKSCrash.dylib::__cxa_throw
، وستنتهي في /usr/lib/libc++abi.dylib::__cxa_throw
.
من المحتمل أن يتم إصلاح هذه المشكلة من خلال تصحيح وقت تشغيل منخفض المستوى للصور المحملة بمراجع غير محددة إلى __cxa_throw
. باستخدام تطبيق الاختبار المشار إليه في المقالة ، لقد تحققت من أن هذه التقنية تعمل بالفعل مقابل __cxa_throw
أيضًا.
أحاول التحقق من التعطل في إطار عمل في تطبيقي. عندما أحاول الحصول على سجل الأعطال ، أرى أن تتبع المكدس لا يظهر الانهيار الفعلي ، وبدلاً من ذلك يتعطل KSCrash.
هل هذه نفس المشكلة؟
الموضوع 0 تحطم:
0 libsystem_kernel.dylib 0x0000000181cc5348 0x181ca4000 + 136008 (__pthread_kill + 8)
1 libsystem_pthread.dylib 0x0000000181ddd7a4 0x181dd6000 + 30628 (+ 360)
2 libsystem_c.dylib 0x0000000181c34fd8 0x181bd2000 + 405464 (إحباط + 140)
3 libc ++ abi.dylib 0x0000000181698068 0x181696000 + 8296 (+ 132)
4 libc ++ abi.dylib 0x0000000181698210 0x181696000 + 8720 (+ 304)
5 libobjc.A.dylib 0x00000001816c0810 0x1816b8000 + 34832 (+ 124)
6 KSCrash 0x00000001054a0590 0x10549c000 + 17808 (kscm_cppexception_getAPI + 280)
7 libc ++ abi.dylib 0x00000001816b054c 0x181696000 + 107852 (+ 16)
8 libc ++ abi.dylib 0x00000001816b0158 0x181696000 + 106840 (__cxa_rethrow + 144)
9 libobjc.A.dylib 0x00000001816c06e8 0x1816b8000 + 34536 (objc_exception_rethrow + 44)
10 CoreFoundation 0x0000000182072344 0x18206a000 + 33604 (CFRunLoopRunSpecific + 544)
11 خدمات الرسومات 0x0000000183f03f84 0x183ef9000 + 44932 (GSEventRunModal + 100)
12 UIKit 0x000000018b61e880 0x18b5ab000 + 473216 (تطبيق UIAMain + 208)
torarnv مرحبًا ، هل يمكنك مشاركة العرض التوضيحي الناجح الخاص بك معنا؟ واجهت EXC_BAD_ACCESS عندما أحاول mach_hook
__cxa_throw.
void ter_handler(){
printf("custom handler\n");
}
void test(){
throw std::runtime_error("test function");
}
static void (*orig_throw)(void * thrown_exception, std::type_info *tinfo, void (*dest)(void *));
void hooked_throw(void * thrown_exception, std::type_info *tinfo, void (*dest)(void *)){
printf("hooked_throw...\n");
return orig_throw(thrown_exception, tinfo, dest);
}
int main(int argc, char * argv[])
{
<strong i="5">@autoreleasepool</strong> {
struct rebinding binds[1];
struct rebinding bind1 = {"__cxa_throw", (void *)hooked_throw, (void **)&orig_throw};
binds[0] = bind1;
rebind_symbols(binds, 1);
std::set_terminate(ter_handler);
try {
throw std::runtime_error("test error");
}
catch (...){
printf ("catch exception\n");
}
test();
}
}
جرب هذا ... حظا سعيدا
لقد واجهت حادثًا واحدًا مع KSCrash ،
كيفية حلها؟
لقد أنشأنا خطافًا ديناميكيًا تنفيذيًا للعلاقات العامة المذكور أعلاه بواسطة huakucha : # 375
التعليق الأكثر فائدة
بعد مزيد من التحقيق ، يبدو أن تعليقي السابق كان غير صحيح:
في حالة ربط KSCrash بالتطبيق الرئيسي كمكتبة ثابتة:
MyApplication
(main.o
،libKSCrash.a
)libDynamicLibrary.dylib
(lib.o
)/usr/lib/libc++abi.dylib
أي استثناءات يتم طرحها من
MyApplication
ستدخلlibKSCrash.a::__cxa_throw
. في الإضافات ، نظرًا لأنlibKSCrash.a
يعلن__cxa_throw
كـweak
، لا يفشل ربطMyApplication
إذا كانmain.o
يمتلك__cxa_throw
تجاوزlibDynamicLibrary.dylib
لن تؤدي إلى تشغيلlibKSCrash.a::__cxa_throw
، وستنتهي في/usr/lib/libc++abi.dylib::__cxa_throw
.في حالة ربط KSCrash بالتطبيق الرئيسي كمكتبة ديناميكية:
MyApplication
(main.o
)libKSCrash.dylib
/usr/lib/libc++abi.dylib
libDynamicLibrary.dylib
(lib.o
)/usr/lib/libc++abi.dylib
أي استثناءات يتم طرحها من
MyApplication
ستدخلlibKSCrash.dylib::__cxa_throw
، ولكن فقط إذا:__cxa_throw
منlibKSCrash.dylib
__cxa_throw
لم يتم تمييزه كـweak
إذا تم تمييز
__cxa_throw
كـweak
(0000000000002e90 (__TEXT,__text) weak external ___cxa_throw
) ، فعند ربطlibKSCrash.dylib
يبدو الرابط وكأنه ينظر إلى/usr/lib/libc++abi.dylib
، ابحث عن غير - ضعيف__cxa_throw
، واستنتج أنه يجب تجاهلlibKSCrash.dylib::__cxa_throw
. أثناء البحث عن رمز وقت التشغيل في وقت العرض منMyApplication
، ثم يتم تجاهلlibKSCrash.dylib::__cxa_throw
.يقودني هذا إلى الاعتقاد بأنه يجب إضافة السمة
weak
بشكل مشروط فقط عند إنشاء KSCrash كمكتبة ثابتة.كما هو الحال بالنسبة لحالة الاستخدام الأولى ، فإن أي استثناءات يتم طرحها من
libDynamicLibrary.dylib
لن تؤدي إلىlibKSCrash.dylib::__cxa_throw
، وستنتهي في/usr/lib/libc++abi.dylib::__cxa_throw
.من المحتمل أن يتم إصلاح هذه المشكلة من خلال تصحيح وقت تشغيل منخفض المستوى للصور المحملة بمراجع غير محددة إلى
__cxa_throw
. باستخدام تطبيق الاختبار المشار إليه في المقالة ، لقد تحققت من أن هذه التقنية تعمل بالفعل مقابل__cxa_throw
أيضًا.