0

このコードを実行すると、seg-fault が発生します。handler()seg-fault が発生している場所 (関数内) についてコメントしました。よくわかりませんが、データを2回ラップしている可能性があります。その理由または問題は何ですか? 「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);
}  
4

1 に答える 1

2

これが問題かもしれません。以下のコードでは、timer_dataは function に対してローカルですstart_timer_on。関数が終了するとすぐに、オブジェクトは破棄されます。そのため、in ハンドラーにアクセスするnameと、segfault が発生します。

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あります。

于 2012-05-02T23:47:23.543 に答える