0

次のコードを、ARM <-> DSP システムで実行されるより大きなプログラム (残念ながら共有できません) に統合しようとしています。

#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 を使用していることに注意してください。ただし、ハンドラーに新しいメモリを割り当てていないため、それと関係があるとは思えません。

では、セグメンテーション違反の考えられる原因について何か考えがある人はいますか?

4

1 に答える 1

1

SEGFAULT によって常に役立つのは、コアダンプです。

$ ulimit -c unlimited

アプリケーションを実行します。セグメンテーション違反の後、現在のディレクトリに「コア」ファイルが必要です。

GDB を使用してダンプします。

gdb <executable> -c <core-file>

セグメンテーション違反が発生した場所を確認できます。マルチスレッド アプリケーションを使用している場合は、gdb-console に次の行を記述します。

$ gdb thread apply all bt
于 2015-08-23T18:02:46.667 に答える