2015-08-23 53 views
0

我想下面的代碼集成到一個更大的計劃(不幸的是,我不能共享)是在ARM上運行< - > DSP系統:分段故障使用Linux create_timer和sigaction的API時

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

正如你所看到的,這是一個非常簡單的代碼,當它在系統上自行運行時,它可以正常工作。 while循環僅用於演示,可以忽略。 處理程序和初始化步驟是相同的​​。

當我試圖將它與更大的程序集成時,問題就開始了 - 突然,如果我設置的定時器間隔短於10ms,則會出現分段錯誤。

我試圖將處理程序中的操作簡化爲'curr_time = 0',認爲它可能與處理程序中的浮點操作有關,但它沒有幫助。

應該指出,我使用ARM < - > DSP共享內存緩衝區的連續內存分配API,但我懷疑它與它有什麼關係,因爲我沒有在處理程序中分配任何新的內存。

那麼,有沒有人有任何關於分段故障的可能原因的想法?

+1

'clock()'不是異步安全的。此外,在信號處理程序('keep_going')中修改的變量必須是原子類型或「volatile sig_atomic_t」類型。 – EOF

+1

此外,'man sigaction:[...]如果在sa_flags中指定了SA_SIGINFO,則sa_sigaction(而不是sa_handler)指定signum的信號處理函數。這個函數接收信號編號作爲它的第一個參數,一個指向siginfo_t的指針作爲它的第二個參數和一個指向ucontext_t的指針(轉換爲void *)作爲它的第三個參數[...]'。 – EOF

+0

謝謝。 我現在爲每個在sigaction手冊頁中定義的值分配正確的值。 它並沒有解決問題,但如果我沒有解決這個問題,它可能會構成一個問題。 無論如何,看起來問題是我在關鍵初始化部分之前啓動了定時器。 – Edwin

回答

1

總是有益的段錯誤是一個核心轉儲:

$ ulimit -c unlimited 

現在運行你的應用程序,一個段錯誤之後,必須有在當前目錄下的「核心」 -file。

現在使用GDB轉儲:

gdb <executable> -c <core-file> 

你可以看到你有一個段錯誤了。 如果您有多線程應用程序,請將此行寫入gdb-console

$ gdb thread apply all bt 
+0

謝謝,正如我在上面的帖子中寫的,我最終設法解決了這個問題。 雖然現在有一個新的,但這超出了我原來的問題。 – Edwin