繁体   English   中英

C ++ libpthread程序segfaults(原因不明)

[英]C++ libpthread program segfaults for unknown reason

我有一个libpthread链接的应用程序。 该应用程序的核心是由四个线程共享的两个FIFO(每个FIFO有两个线程;即;)。 FIFO类使用pthread互斥锁进行同步,并且使用重载的new和delete运算符(此处没有动态分配)存储指向静态存储器内分配的大类(包含约4kb大小的缓冲区)的指针。

该程序本身通常可以正常运行,但是有时会出现段错误,没有明显的原因。 问题是,当我在具有旧版Linux内核(2.4.29)和g ++(gcc版本egcs-2.91.66 19990314 / Linux(egcs-1.1.x)的嵌入式系统上工作时,无法正确调试segfaults。 2版))。

系统上没有gdb,而且我无法在其他地方运行该应用程序(它也是特定于硬件的)。

我使用-g和-rdynamic标志编译了应用程序,但是当我检查核心文件(仅十六进制地址)时,外部gdb不会告诉我任何信息-仍然可以在捕获SIGSEGV之后从程序中打印回溯-看起来总是这样:

Backtrace for process with pid: 6279
-========================================-
[0x8065707]
[0x806557a]
/lib/libc.so.6(sigaction+0x268) [0x400bfc68]
[0x8067bb9]
[0x8067b72]
[0x8067b25]
[0x8068429]
[0x8056cd4]
/lib/libpthread.so.0(pthread_detach+0x515) [0x40093b85]
/lib/libc.so.6(__clone+0x3a) [0x4015316a]
-========================================-
End of backtrace

所以它似乎指向libpthread ...

我通过valgrind运行了一些模块,但是我没有发现任何内存泄漏(因为我几乎没有使用任何动态分配)。

我认为互斥锁可能会引起一些麻烦(因为它们每秒被锁定/解锁大约200次),所以我切换了简单的互斥锁类:

class AGMutex {

    public:

        AGMutex( void ) {
            pthread_mutex_init( &mutex1, NULL );
        }

        ~AGMutex( void ) {
            pthread_mutex_destroy( &mutex1 );
        }

        void lock( void ) {
            pthread_mutex_lock( &mutex1 );
        }

        void unlock( void ) {
            pthread_mutex_unlock( &mutex1 );
        }

    private:

        pthread_mutex_t mutex1;

};

到虚拟互斥体类:

class AGMutex {

    public:

        AGMutex( void ) : mutex1( false ) {
        }

        ~AGMutex( void ) {
        }

        volatile void lock( void ) {
            if ( mutex1 ) {
                while ( mutex1 ) {
                    usleep( 1 );
                }
            }
            mutex1 = true;
        }

        volatile void unlock( void ) {
            mutex1 = false;
        }

    private:

        volatile bool mutex1;

};

但是它什么都没改变,回溯看起来也一样……

在每条线之间进行一些古老的选择之后,看到它出现段错误并记住pids和东西的调试会话,似乎它在休眠状态下出现段错误(?)。

我不知道还有什么可能是错的。 它可以工作一个小时左右,然后突然在没有明显原因的情况下出现段错误。

有人遇到过类似的问题吗?

从我对我的gcc C ++应用程序崩溃时如何生成stacktrace的 回答

The first two entries in the stack frame chain when you get into the 
    signal handler contain a return address inside the signal handler and
    one inside sigaction() in libc.  The stack frame of the last function
    called before the signal (which is the location of the fault) is lost.

这可以解释为什么您难以通过信号处理程序的回溯来确定段故障的位置。 我的答案还包括针对此限制的解决方法。

如果您想查看应用程序在内存中的实际布局(即0x80.....地址),则应该能够从gcc生成映射文件。 这通常是通过-Wl,-Map,output.map ,该方法将-Map output.map传递给链接器。

您的工具链/跨工具链也可能具有objdumpnm的特定于硬件的版本,这可能有助于破译0x80.....地址。

您可以在平台上访问Helgrind吗? 这是一个Valgrind工具,用于检测POSIX线程错误,例如种族和线程在退出时持有互斥体。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM