2009-03-05 10 views
3

OSX Carbon uygulamasında C'den segmentasyon hatalarını nasıl verimli bir şekilde yakalayabilir ve kullanabilirim?OSX'de Karbon C uygulaması için istisna sarıcısı

Arka plan: Bir OSX Carbon uygulaması yapıyorum. Üçüncü taraflardan bir kütüphane işlevi çağırmalıyım. İş parçacığı sorunları nedeniyle, bu işlev bazen çökebilir, genellikle kendisini bir iş parçacığından güncelleştirir, ve içten eski bir işaretçi veya başka birinden sorguladığımda işlenir. Bu fonksiyon benim için kara bir kutu. İşlevi çağırmak istiyorum ama çöktü ve alternatif bir geri dönüş sağladıysa "yakalamak" mümkün. Windows'da, basit Visual C ve Intel C derleyicinin __try {} ve __except öğelerini kullanabilirim.

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

OSX için aynı türde bir çakıcı yakalamaya çalışıyorum. Çok büyük bir uygulamada saf C kullanıyorum. Fonksiyonu saniyede milyonlarca kez çağırıyorum, bu yüzden verimlilik de çok önemli. (Etkileyici Windows __try() havai ölçülemeyecek küçük!)

İşte ile denemişlerdir ne:

1) C++ istisnalar. C++ istisnalarının segfault çökmelerini yakalayıp yakalamadığından emin değilim. Ve benim app şu anda C. Ben C++ yapmak için sarmalayıcılar ve #ifdefs deneyebilirsiniz ama bu uygulama için bir sürü iş, ve C++ istisnalar kaza yakalayacağını düşünmüyorum.

2) sinyal + setjump + longjmp. Bunun işe yarayacağını düşündüm ... bunun için tasarlandı. Ama SEGV hata işleyicimi kurdum [aslında her sinyal için ayarladım!] Ve hiç bir zaman çökme sırasında çağrılmadı. Yükseltmeyi (SEGV) ararken manuel olarak test edebilir (ve başarılı olabilir). Ama çöküşler aslında öyle görünmüyor. Düşüncelerim, CFM uygulamalarının tam BSD sinyallerine, sadece bir alt kümeye erişemeyeceğidir ve Mach uygulamaları Real Thing için gereklidir.

3) MPSetExceptionHandler. İyi belgelenmiş değil. Bir işleyici kurmaya teşebbüs ettim. Derlendi ve koştu, ancak segfault yakalamadı.

cevap

3

SIGBUS yerine SIGSEGV almıyor musunuz?

aşağıda hafıza konumu 0 yazmaya çalışıyorum neden olarak SIGBUS yakalar:

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 
+0

Evet. Anahtarın her türden HER istisna yakalamak olduğunu düşünüyorum! – SPWorley