C中的段错误错误

时间:2012-05-02 23:29:19

标签: c timer segmentation-fault signals void-pointers

运行此代码时出现seg-fault。我评论了我在哪里得到了seg-fault(在handler()函数中)。我不确定,可能是我将数据包装两次,这就是为什么或者问题是什么?它正确打印直到“start_timer”方法。

#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);
}  

1 个答案:

答案 0 :(得分: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退出之前不会释放数据。