簡體   English   中英

C的段錯誤處理程序僅調用一次

[英]segfault handler for C only called once

我正在編寫一個程序,該程序掃描進程內存並創建一個memchunk結構來表示內存塊的可訪問性。 此過程的副作用是學習如何處理信號,因為在此掃描過程中應該有許多段錯誤。 因此,我試圖引起許多段錯誤來了解信號,同時也了解一些有關虛擬內存的信息。 它在Linux平台上被編譯為32位程序。 我使用setjmplongjmp來重新輸入程序。

我的問題是我的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,這很奇怪,但是后來又無法處理。 我真的很感謝您的幫助。

在某些系統中,它不支持單個處理程序的重新分配。 我們必須在調用那個function_handler之后重新分配該句柄。

信號不可靠

這些早期版本的一個問題是,每次信號出現時,信號的操作都會重置為其默認值。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM