6

W poniższym kodzie, przy pierwszej iteracji otrzymuję wyjątek, aw drugim otrzymuję błąd segmentacji bez drukowania komunikatu o błędzie. Wygląda na wyjątek:Otrzymuję błąd segmentacji zamiast wyjątku

int i = 0; 
while(i++ < 10) 
{ 
    try { 
     cout << "Iteration: " << i << endl; 
     // Code... 
     cout << "OK" << endl; 
    } 
    catch(...) 
    { 
     cerr << "Error message" << endl; 
     continue; 
    } 
} 

Output: 
Iteration 1 
Error message 
Iteration 2 
Segmentation fault 

Czy to normalne, czy dzieje się coś naprawdę złego?

Jeśli to powinno być istotne, w tym bloku kodu zresetowałem połączenie MySQL, a wyjątek zostanie wygenerowany, gdy sprawdzę, czy połączenie jest zamknięte.

Dziękuję.


Platforma:
Linux - openSUSE 11.4
C++ - GCC 4.5.1
Intel Xeon

+2

błędów segmentacji. nie zostanie złapany przez "try-catch", zamiast tego należy użyć debuggera: –

+10

Jestem prawie pewny, że musi on znajdować się w twoim '// Code ...'. Nie można wykryć miejsc, w których wystąpił błąd. .. – kratenko

+0

Udało mi się zduplikować twoje wyjście, pisząc 'if (i == 1) throw 0; else i = * (int *) 0;' ale to nie jest to, co robi twój '// Code', czy jest to? –

Odpowiedz

16

Ponieważ błędy segmentu nie są spowodowane (bezpośrednio) oprogramowaniem, ale procesor wykrywa, że ​​próbujesz uzyskać dostęp do nieprawidłowej pamięci (lub uzyskać dostęp do pamięci w nieprawidłowy sposób - np. Zapis do pamięci chronionej przed zapisem, wykonanie pamięć, która nie powinna być wykonana, itp.), nie jest "chwytalna" z try/catch, która jest przeznaczona do przechwytywania oprogramowania, które zgłasza wyjątek. Oba są nazywane wyjątkami, ale pochodzą z różnych poziomów oprogramowania/sprzętu systemu.

Technicznie można złapać segfaulty z obsługą sygnału dla SIGSEGV. Jednak, jak wyjaśnia Ivaylo, zazwyczaj nie można po prostu "spróbować ponownie", jeśli dostaniesz segfault. Operator sygnału dla SIGSEGV jest dopuszczony do longjmp lub exit, ale nie powinien tylko powracać.

Więcej o sygnały o: http://www.alexonlinux.com/signal-handling-in-linux

Typowe wyjątków C++ (wynik throw) może być powtarzana bez problemu (oczywiście sam wyjątek mogą ponownie być wyrzucane oczywiście

5

Nie można złapać winy segmentacji takiego. Ten błąd jest zwykle nieodwracalny i nie jest obsługiwany przez zwykły try-catch. Oznacza to, że coś poszło nie tak, jak się wydaje, niewłaściwie stosu lub coś podobnego. Spróbuj użyć valgrind, aby wykryć przyczynę błędu segmentacji.

+4

Segfaulty występują również podczas usuwania odwołania do niepoprawnego wskaźnika (zerowy lub wskazujący inny obszar nieprzydzielony), co jest dość częstym błędem, niczym dramatycznym jak uszkodzenie stosu. – syam

1

Klauzule wychwytywania wyjątków wyrzucanych przez wyrażenia throw. W standardowym C++ (i we wszelkiej praktycznej implementacji C++) nie powodują błędów przechwytywania wykrytych przez system operacyjny lub sprzęt.Inaczej byłoby zbyt ciężko, aby napisać kod bezpieczny.