سؤال

وكيف يمكنني كفاءة التقاط ومعالجة أخطاء تجزئة من C في تطبيق OSX الكربون؟

والخلفية: وأنا على صنع تطبيق OSX الكربون. ولا بد لي من استدعاء دالة مكتبة من طرف ثالث. بسبب خيوط القضايا، يمكن الدالة تحطم أحيانا، عادة لأنه بتحديث نفسها من موضوع واحد، وانها حصلت على بعض مؤشر قديمة داخليا أو معالجة وأنا الاستعلام عليه من آخر. وظيفة هو الصندوق الأسود بالنسبة لي. أريد أن أكون قادرة على استدعاء الدالة ولكن أن تكون قادرة على "اللحاق" إذا كان قد تحطمت وتوفير عائد بديلة. في ويندوز، يمكنني استخدام Visual C بسيط وإنتل C __try البرمجي {} و__except.

/* Working Windows Example */
__try { x=DangerousFunction(y);}
__except(EXCEPTION_EXECUTE_HANDLER) {x=0.0;} /* whups, func crashed! */

واني اسعى الى تقديم نفس النوع من تحطم لافت للOSX. أنا أستخدم النقي C على تطبيق واسع جدا. أدعو ملايين وظيفة من مرة في الثانية الواحدة، وبالتالي كفاءة مهمة جدا جدا. (مثير للإعجاب، والنفقات العامة ويندوز __try () صغير بما لا يقاس!)

وهنا هو ما كنت قد جربت:

1) استثناءات C ++. أنا لست متأكدا مما اذا كان استثناءات C ++ صيد تعطل segfault. وبلدي التطبيق هو حاليا C. يمكن أن أحاول مغلفة و#ifdefs لجعلها C ++ ولكن هذا هو الكثير من العمل للتطبيق، وأنا لا أعتقد أن الاستثناءات C ++ قبض على الحادث.

2) إشارة + setjump + longjmp. أعتقد أن هذا من شأنه العمل ... انها ما صمم من أجله. ولكن أقوم بإعداد معالج الأخطاء SEGV [في الحقيقة أنا إعداده لكل إشارة!]، وهذا يدعى أبدا أثناء الحادث. يمكنني اختبار يدويا (والنجاح) عند استدعاء رفع (SEGV). ولكن تعطل لا يبدو أن يطلق عليه في الواقع. أفكاري هي أن التطبيقات CFM لا يستطيعون الوصول إلى إشارات BSD كاملة، مجموعة فرعية فقط، وضرورية أن تطبيقات ماك لشيء حقيقي.

و3) MPSetExceptionHandler. يتم توثيقها جيدا. حاولت أن وضع المعالج. انها جمعت وركض، ولكن لم قبض على segfault.

هل كانت مفيدة؟

المحلول

هل أنت متأكد من أنك لا تحصل على SIGBUS بدلا ثم SIGSEGV؟

وويمسك أدناه SIGBUS الناجم عن محاولة الكتابة في ذاكرة المكان 0:

cristi:tmp diciu$ cat test.c

#include <signal.h>

static void sigac(int sig)
{
    printf("sig action here, signal is %d\n", sig);
    exit(1);
}

int main()
{
    (void)signal(SIGSEGV, sigac);
    (void)signal(SIGBUS, sigac);

    printf("Raising\n");
    strcpy(0, "aaksdjkajskd|");
}



cristi:tmp diciu$ ./a.out 
Raising
sig action here, signal is 10
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top