簡體   English   中英

為什么用memset()初始化sigint變量有助於防止Seg Faults?

[英]Why does initializing a sigint variable with memset() help prevent Seg Faults?

背景:

struct sigaction用於為處理中斷的小型C程序設置處理程序。 在完成第二個處理程序的實現后收到“Segmentation fault(core dumped)”錯誤消息時出現問題。 我以完全相同的方式設置兩個處理程序。 第一個中斷處理程序工作正常而沒有初始化sigaction結構,但是,當我完成第二個處理程序的實現時,我收到了seg錯誤錯誤。

題:

為什么用memset()初始化sigaction結構有助於修復錯誤?

碼:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include <signal.h>
#include <string.h>

#define ALARMSECONDS    3
int numSigints = 5;

/* Handler function that prints out the current time on a SIGALRM interrupt. */
static void hdl(int signum)
{
    time_t currTime;
    time(&currTime);
    printf("\ncurrent time is %s", ctime(&currTime));
    alarm(ALARMSECONDS);//re-arm the alarm

}

/* Handler function that captures SIGINT interrupts 5 times before 
   actually exiting. Makes use of global variable to keep track of
   number of times the interrupt was sent.
 */
static void sigint_hdl(int signum)
{

    numSigints -= 1;    

    if(numSigints == 0)
    {
      printf("\nFinal Control-c caught. Exiting.\n");
      exit(1);
    } 
    else
    {
      printf("\nControl-c caught. %d more before program is ended.\n", 
        numSigints);
    }   
}

/* Periodically prints out the current time in Unix date format using 
   sigaction interrupt handling.   
*/
int main(int argc, char *argv[])
{

    //
    // vars
    //
    struct sigaction act;
    struct sigaction sigint_act;

    memset(&act, '\0', sizeof(act));//TODO Why does this fix SEGFAULT???

    //
    // intro
    //
    printf("Date will be printed every 3 seconds.\n");
    printf("Enter ^C 5 times to end the program.\n");

    //
    // set alarm to go off in 3 seconds
    //
    alarm(ALARMSECONDS);

    //
    // set handler of the sigaction to 'hdl' function defined above
    //
    act.sa_handler = hdl;
    sigint_act.sa_handler = sigint_hdl;

    //
    // activate sigaction
    //
    if(sigaction(SIGALRM, &act, NULL) < 0)
    {
      perror("sigaction -- SIGALRM");
      return 1;
    }

    if(sigaction(SIGINT, &sigint_act, NULL) < 0)
    {
      perror("sigaction -- SIGINT");
      return 1;
    }

    //
    // infinite loop
    //
    while(1) {
    }

    return 0;
}

sigaction結構中有許多字段。 將它們全部設為零會將它們設置為默認值。

如果它們不是零,則它們將以系統調用文檔中描述的任何方式進行解釋。 一個例子是兩個字段sa_masksa_sigaction 並且根據sa_mask的值,將調用sa_sigaction處理程序而不是您的代碼安裝的預期信號處理程序。 並且由於你沒有初始化指針,它將有一些垃圾值,並且將嘗試不僅僅取消引用,而是通過垃圾指針調用函數。

因此,如果您未能初始化結構,則會得到未定義的行為。 有時它會工作,有時它不會以神秘的方式,例如崩潰。

通過將整個結構清除為零,您可以確保將發生默認行為,並通過它們對結構所做的任何非默認設置進行修改。

獲得的經驗:始終清除並初始化傳遞給庫函數的所有結構。

暫無
暫無

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

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