2012-05-02 73 views
0

運行此代碼時出現seg-fault錯誤。我評論我在哪裏得到seg-fault(在handler()函數中)。我不確定,可能我是兩次包裝數據,這是爲什麼或者是什麼問題?它正確打印,直到「start_timer」方法。C中的Seg故障錯誤

#include <time.h> 
#include <stdio.h> 
#include <signal.h> 
#include <pthread.h> 
#include <unistd.h> 
#include <errno.h> 

typedef struct _data{ 
    char *name; 
}data; 

struct timer_list{ 
    void* timer_data; 
    unsigned long expires; 
    void (*function)(sigval_t); 
}; 

volatile long int second = 0; 

void handler(sigval_t val) 
{ 
    data *data_handler = val.sival_ptr; 
    printf("Handler: address of data: %p\n", data_handler); 
    printf("Handler: address of &data_handler->name: %p\n", &data_handler->name); 
    printf("Handler entered with value :%s\n", data_handler->name); `**//**SEG-FAULT HERE****` 
} 

void timer_handler(union sigval val) 
{ 
    printf(" ----- Seconds: %ld\n", ++second); 
} 

/* start timer with all we got as data is timer */ 
void start_timer(struct timer_list *timer) 
{ 
    printf("\nStart_timer...: Timer->data address: %p\n", timer->timer_data); 
    data *data_handler = timer->timer_data; 
    printf("Start_timer...: entered with value :%s\n", data_handler->name); 
    int Ret; 
    pthread_attr_t attr; 
    pthread_attr_init(&attr); 
    //pthread_t tid; 

    struct sched_param parm; 
    parm.sched_priority = 255; 
    pthread_attr_setschedparam(&attr, &parm); 

    struct sigevent sig; 
    sigval_t val; 
    val.sival_ptr = timer->timer_data; 
    sig.sigev_notify = SIGEV_THREAD; 
    sig.sigev_notify_function = timer->function; 
// sig.sigev_value.sival_int = val; 
    sig.sigev_value = val; 
    sig.sigev_notify_attributes = &attr; 

    data *data_handler1 = (data *)val.sival_ptr; 
    printf("From sigval...: handler_data address: %p\n", data_handler1); 
    printf("From sigval...: handler_data->name address: %p\n", &data_handler1->name); 
    printf("From sigval...: Handler entered with value :%s\n", data_handler1->name); 

//create a new timer. 
    timer_t timerid; 
    Ret = timer_create(CLOCK_REALTIME, &sig, &timerid); 
    if (Ret == 0) 
    { 
     struct itimerspec in, out; 
     in.it_value.tv_sec = timer->expires; 
     in.it_value.tv_nsec = 0; 
     in.it_interval.tv_sec = 0; 
     in.it_interval.tv_nsec = 0; 
    timer_settime(timerid, 0, &in, &out); 

    } 
} 

/* Start_timer_on: wrapping up data into one timer structure, and starting timer */ 
void start_timer_on(data timer_data, unsigned long expires) 
{ 
    struct timer_list *timer = (struct timer_list *)malloc(sizeof(struct timer_list)); //Problem was here ... forgot to use malloc 
    timer->timer_data = &timer_data; 
    printf("\nTimer->data address: %p\n", &timer_data); 
    timer->function = handler; 
    timer->expires = expires; 
    start_timer(timer); 
} 

/* Main */ 
void main() 
{ 
    data handler_data1 = {"Handler Data 1"}; 
    //data handler_data2 = {"Handler Data 2"}; 
    //void *data1 = &handler_data1; 
    //void *data2 = &handler_data2; 

    pthread_attr_t attr; 
    pthread_attr_init(&attr); 

    struct sched_param parm; 
    parm.sched_priority = 255; 
    pthread_attr_setschedparam(&attr, &parm); 

    struct sigevent sig; 
    sig.sigev_notify = SIGEV_THREAD; 
    sig.sigev_notify_function = timer_handler; 
    sig.sigev_notify_attributes = &attr; 

//create a new timer - clock. 
    timer_t timerid; 
    timer_create(CLOCK_REALTIME, &sig, &timerid); 


    struct itimerspec in, out; 
    in.it_value.tv_sec = 1; 
    in.it_value.tv_nsec = 0; 
    in.it_interval.tv_sec = 1; 
    in.it_interval.tv_nsec = 0; 
    printf("*** *** *** Main clock starts *** *** ***\n"); 
    timer_settime(timerid, 0, &in, &out); 
    printf("***** Start timer for data1 for 2 sec *****\n"); 
    start_timer_on(handler_data1, 2); 
// printf("***** Start timer for data1 for 5 sec *****\n"); 
// start_timer(data2, 5);  

    sleep(20); 
} 
+0

使用valgrind ... –

+1

使用調試器遍歷代碼,並查看內存訪問是否按照您認爲應該是的做法。 – Makoto

+1

分段錯誤意味着您嘗試訪問內存元素或將其保存到內存中,檢查代碼中的分配行,確保爲容器提供了正確的大小,並檢查是否保存到指針中一個不是有效內存地址的值。 –

回答

2

這可能是問題所在。在下面的代碼中,timer_data位於函數start_timer_on的本地。一旦函數退出,對象就會被銷燬。因此,在處理程序中訪問name時,它將會出現段錯誤。

void start_timer_on(data timer_data, unsigned long expires) 
{ 
    struct timer_list *timer; 
    timer->timer_data = &timer_data; 
    printf("\nTimer->data address: %p\n", &timer_data); 
    timer->function = handler; 
    timer->expires = expires; 
    start_timer(timer); 
} 

你應該使用void start_timer_on(data *timer_data, unsigned long expires),使數據不被釋放,直到main退出。

+1

一個相關的問題:變量'timer'永遠不會被初始化,不允許使用' - >'操作符去引用它 – bta

+0

真的..他是如何到達處理程序的!呃...... – deebee

+0

@ deebee hadler通過sigval_t獲取數據...如果你不知道定時器 - create_timer和timer_settimer,應該回復。 –