我想下面的代碼集成到一個更大的計劃(不幸的是,我不能共享)是在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,但我懷疑它與它有什麼關係,因爲我沒有在處理程序中分配任何新的內存。
那麼,有沒有人有任何關於分段故障的可能原因的想法?
'clock()'不是異步安全的。此外,在信號處理程序('keep_going')中修改的變量必須是原子類型或「volatile sig_atomic_t」類型。 – EOF
此外,'man sigaction:[...]如果在sa_flags中指定了SA_SIGINFO,則sa_sigaction(而不是sa_handler)指定signum的信號處理函數。這個函數接收信號編號作爲它的第一個參數,一個指向siginfo_t的指針作爲它的第二個參數和一個指向ucontext_t的指針(轉換爲void *)作爲它的第三個參數[...]'。 – EOF
謝謝。 我現在爲每個在sigaction手冊頁中定義的值分配正確的值。 它並沒有解決問題,但如果我沒有解決這個問題,它可能會構成一個問題。 無論如何,看起來問題是我在關鍵初始化部分之前啓動了定時器。 – Edwin