0

I'm trying to integrate the following piece of code into a bigger program (Which unfortunately, I cannot share) that runs on an ARM<->DSP system:

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

#define CLOCKID CLOCK_REALTIME
#define SIG SIGUSR1

timer_t timerid;

int i = 0;
int sec = 0;

volatile int keep_going = 1;

clock_t curr_time = 0, t_old = 0;

static void handler(int sig)
{
    curr_time = clock();
    if ((curr_time - t_old)/CLOCKS_PER_SEC >= 10.)
    keep_going = 0;
}

int main(int argc, char *argv[])
{
    struct sigevent sev;
    struct itimerspec its;
    long long freq_nanosecs;
    sigset_t mask;
    struct sigaction sa;
    memset(&sa, 0, sizeof sa);

    // Timer settings
    printf("Establishing handler for signal %d\n", SIG);
    sa.sa_flags = SA_SIGINFO;
    sa.sa_handler = handler;
    sigemptyset(&sa.sa_mask);
    sigaction(SIG, &sa, NULL);

    sev.sigev_notify = SIGEV_SIGNAL;
    sev.sigev_signo = SIG;
    sev.sigev_value.sival_ptr = &timerid;
    timer_create(CLOCKID, &sev, &timerid);

    /* Start the timer */
    its.it_value.tv_sec = 0;
    its.it_value.tv_nsec = 1000;
    its.it_interval.tv_sec = its.it_value.tv_sec;
    its.it_interval.tv_nsec = its.it_value.tv_nsec;

    timer_settime(timerid, 0, &its, NULL);
    t_old = clock();
    while(keep_going);
    printf("%f sec passed..\n", (double)(curr_time - t_old)/CLOCKS_PER_SEC);
    exit(EXIT_SUCCESS);
}

As you can see, this is a very simple code, and when running it by itself on the system, it works fine. The while loop here is only for demonstration, and can be ignored. The handler and initialization steps are the same.

The problems started when I tried to integrate it with the bigger program - Suddenly, I get segmentation fault if I set a timer interval shorter than 10ms.

I tried to reduce the operations in the handler to a simple line, 'curr_time = 0', thinking it might have something to do with floating point operations in the handler, but it didn't help.

It should be noted that I use contiguous memory allocation API for ARM<->DSP shared memory buffers, though I doubt it has anything to do with it, as I don't allocate any new memory in the handler.

So, does anyone have any idea about possible causes for the segmentation fault?

ytm
  • 461
  • 1
  • 5
  • 16
  • 1
    `clock()` is not async-safe. Also, a variable that is modified in a signal-handler (`keep_going`) has to be atomic or of type `volatile sig_atomic_t`. – EOF Aug 23 '15 at 17:52
  • 1
    Furthermore, `man sigaction: [...]If SA_SIGINFO is specified in sa_flags, then sa_sigaction (instead of sa_handler) specifies the signal-handling function for signum. This function receives the signal number as its first argument, a pointer to a siginfo_t as its second argument and a pointer to a ucontext_t (cast to void *) as its third argument.[...]`. – EOF Aug 23 '15 at 18:01
  • Thanks. I now assigned the correct values per the defined in the sigaction man page. It didn't solve the problem, but it may have posed as one if I hadn't fixed that. Anyway, it appears that the problem was that I started the timer before a critical initialization section. – ytm Aug 24 '15 at 19:18

1 Answers1

1

always helpful by SEGFAULT is a core-dump:

$ ulimit -c unlimited

Now run your application, after a segfault there must be a "core"-file in your current directory.

Now use GDB to dump:

gdb <executable> -c <core-file>

you can see where you got a segfault now. If you have multi-thread application, write this line in gdb-console

$ gdb thread apply all bt
arash javanmard
  • 1,362
  • 2
  • 17
  • 37
  • Thanks, as I wrote in the post above, I eventually managed to solve the problem. There's a new one now, though, but that's beyond my original question. – ytm Aug 24 '15 at 19:24