2015-01-30 3 views
0

Я пишу программу, которая сканирует память процесса и создает структуры memchunk для представления доступности блока памяти. Побочным эффектом этого процесса является научиться обрабатывать сигналы, так как во время этого сканирования должно быть много segfault. Таким образом, я пытаюсь заставить много segfaults узнать о сигналах, а также немного узнать о виртуальной памяти. Это скомпилировано как 32-битная программа на платформе Linux. Я использую setjmp и longjmp, чтобы повторно войти в мою программу.Обработчик segfault для C только один раз

Моя проблема заключается в том, что мой обработчик segfault вызывается только один раз, а обработчик segfault по умолчанию - базовый демпинг - вызывается на следующий segfault.

Вот мой обработчик:

static void hdl (int sig, siginfo_t *siginfo, void *unused){ 
    /* handler is called properly and can read curr_access */ 
    printf("-------------------\n"); 
    printf("handling segfault\n"); 
    printf("curr_access = %d\n", curr_access); 
    printf("-----------------\n"); 
    switch(curr_access){ 
     case -1: 
      longjmp(buf, 1); 
      break; 
     case 0: 
      longjmp(buf, 2); 
      break; 
     default: 
      printf("error in hdl\n");   
    } 
} 

Вот где я зарегистрировать

void set_hndlr(){ 
    printf("------------------\n"); 
    printf("setting handler\n"); 
    printf("-----------------\n"); 
    /* setting up signal handler */ 
    struct sigaction sa; 

    sa.sa_flags = SA_SIGINFO; 
    sigemptyset(&sa.sa_mask); 
    sa.sa_sigaction = hdl; 
    if (sigaction(SIGSEGV, &sa, NULL) == -1) 
     printf("error setting segfault hanld"); 
} 

здесь, где я "тест" область памяти:

switch(jmp_code){ 
    /* we haven't gone through testing yet */ 
    case 0: 
     test_boolean = 1; 
     break; 
    /* we've gone through testing and we segfaulted at read */ 
    case 1: 
     test_boolean = 0; 
     curr_access = -1; 
     break; 
    /* we've gone through testing and we segfaulted at write */ 
    case 2: 
     test_boolean = 0; 
     curr_access = 0; 
     break; 
    /* if we reach here then there is an error in program logic */ 
    default: 
     printf("error in programming logic regaurding jmp\n"); 
     exit(-2); 
} 
if(1 == test_boolean){ 
    /* not accessible */ 
    curr_access = -1; 
    printf("testing read\n"); 
    /*test read */ 
    curr_cont = *curr_addr; 
    curr_access = 0; 
    printf("readable\n"); 
    /*test write */ 
    *curr_addr = curr_cont; 
    curr_access = 1; 
    printf("read/write\n"); 
} 

Вот некоторые пример:

setting handler 

curr_addr = (nil) 
jmp_code = 0 
testing read 

handling segfault 
curr_access = -1 

jmp_code = 1 

base[0].RW = -1 
base[0].length = 4096 
base[0].start = (nil) 

curr_addr = 0x1000 
jmp_code = 0 
testing read 
Segmentation fault (core dumped) 

Странно, что я могу справиться с одним segfault просто отлично, но тогда он не справится снова. Я бы очень признателен за любую помощь.

ответ

2

В некоторых системах он не поддерживает повторное назначение синхронного обработчика. мы должны повторно назначить дескриптор после вызова этого function_handler.

недостоверные сигналы

Одна из проблем, с ранних версий является то, что действие для сигнала сброса на значения по умолчанию каждый раз, когда произошел сигнал.

int sig_int(); 
... 
signal(SIGINT, sig_int); 
... 
sig_int() 
{ 
    signal(SIGINT, sig_int); 
    ... 
}