2016-12-22 4 views
1

erhalten Im folgenden Code handle ich SIGSEGV-Signal und behebe die Fehlerbedingung durch Minimierung der gebundenen Variable. Ich denke, wann immer der Signal-Handler zurückkehrt, startet er den Befehl neu, während dem das Signal aufgetreten ist. Es ist undefiniertes Verhalten pro C und POSIX-Standards in Signal-Handler minimierte ich die gebundene Variable, aber immer noch SIGSEGV bekommen und in EndlosschleifeFehlerzustand ist weiterhin behoben, SIGSEGV wird in C

Nicht sicher zu gehen, wo ich falsch

#include <stdio.h> 
#include <signal.h> 
#include <stdlib.h> 

void SIG_segfault_handler(int); 
static int bound = 5800000; 

int main(int argc,char *argv[]) 
{ 
    signal(SIGSEGV,SIG_segfault_handler); 
    puts("This is the driver code for experimenting with signal"); 
    int *array = malloc(50); 
    *(array+ 23) = 78; 
    puts("-------------------------------------------------------------------------------------"); 
    *(array + bound) = 100; 
    printf("Data: %d , %d \n",*(array + 23),*(array + bound)); 

    puts("Initialiazed array with 50 bytes.. \n End of driver code. "); 
    //free(array); 
    return 0; 
} 

void SIG_segfault_handler(int signum) 
{ 
    puts("This is segmentation fault.. cannot continue with the memory operation.. aborting"); 
    puts("Signal SIGSEGV is handled by the program"); 
    puts("Fixing the error conditions.."); 
    bound = 2; 
} 
+1

'puts()' ist nicht async-signalsicher und kann nicht sicher von einem Signalhandler aufgerufen werden. ** Nur ** async-signal-sichere Funktionen können von einem Signal-Handler aufgerufen werden. Siehe http://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_04 –

+0

Es gibt keine Garantie, dass der Befehl neu gestartet wird, wenn Sie von einem Signalhandler zurückkehren. Wenn überhaupt, würde ich das Gegenteil erwarten. Aber wirklich, Sie können sich nicht darauf verlassen. –

+0

Fazit: Dieser Code wird nie funktionieren, es gibt keine Möglichkeit, es zu beheben. Eine Segmentierungsverletzung zu bekommen ist wie ein rohes Ei zu zerbrechen: Es gibt keine Möglichkeit, die Teile danach abzuholen. (Die einzige Lösung ist, die Segmentierungsverletzung nicht zu haben/das Ei überhaupt zu brechen.) –

Antwort

0

werde. Die Rückkehr von einem Signalhandler von SIGSEGV ist nicht erlaubt.

Siehe 7.14.1.1 The signal function:

Wenn ein Signal auftritt, und FUNC weist auf eine Funktion ist es Implementierung definiert, ob das Äquivalent des Signals (SIG, SIG_DFL); wird ausgeführt oder die Implementierung verhindert, dass einige implementationsdefinierte Sätze von Signalen (zumindest einschließlich sig) auftreten, bis die Stromsignalverarbeitung abgeschlossen ist; Im Fall von SIGILL kann die Implementierung alternativ definieren, dass keine Aktion ausgeführt wird. Dann das Äquivalent von (* func) (sig); wird ausgeführt. Wenn und wenn die Funktion zurückkehrt, wenn der Wert von sig SIGFPE, SIGILL, SIGSEGV oder irgendein anderer implementierungsdefinierter Wert ist, der einer rechnerischen Ausnahme entspricht, ist das Verhalten undefiniert; andernfalls wird das Programm die Ausführung an dem Punkt fortsetzen, an dem es unterbrochen wurde.

Nach dem Ausführen des Signalhandlers startet die Ausführung den gleichen Befehl neu, der SIGSEGV verursacht hat. Das bedeutet, wenn Sie das Array überlaufen (was SIGSEGV verursacht), wird erneut ausgeführt, nachdem vom Signal-Handler zurückgegeben wurde. Dies sollte die Endlosschleife erklären.

Außerdem sollten Sie nicht puts() von einem Signal Signal Handler aufrufen; Sie dürfen nur innerhalb eines Signalhandlers async-signalsichere Funktionen aufrufen. Eine Liste der async-signalsicheren Funktionen finden Sie unter POSIX manual.

Die Verwendung von signal() wird auch aufgrund unterschiedlicher Semantiken, die von verschiedenen Implementierungen bereitgestellt werden, nicht empfohlen. Aus diesem Grund (unter anderem) wird empfohlen, sigaction() zum Installieren von Signalhandlern zu verwenden.

Verwandte Themen