C ++程序的libpthread为发生段错误原因不明(C++ libpthread program

2019-10-19 22:24发布

我有一个的libpthread链接的应用程序。 应用程序的核心是由四个线程共享两个FIFO(每一个FIFO是两个线程)。 该FIFO类使用并行线程互斥和同步使用它重载new和delete运算符(在这里没有动态分配)存储指针大类(含约4KB大小的缓冲区)内静态存储器分配。

该程序本身通常工作正常,但不时也出现segfaults因为没有明显的理由。 问题是,我无法正常调试段错误,因为我工作在嵌入式系统上使用旧的Linux内核(2.4.29)和g ++(gcc版本EGCS-2.91.66 19990314 / Linux操作系统(EGCS-1.1。 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;

};

但什么都没有改变,并回溯看起来是一样的...

经过一番oldchool把-COUT之间,每一个线和观望,在那里,它-段错误加记得最的PID-和东西似乎它usleep期间出现segfaults调试会话(?)。

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

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

Answer 1:

从我的回答对如何产生一个堆栈跟踪当我的gcc C ++应用程序崩溃

    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给链接器。

你也可以有一个特定的硬件版本objdump的或纳米与工具链/交叉工具链,可能是破译你有帮助的0x80.....地址。



Answer 2:

你可以访问Helgrind你的平台上? 这是检测POSIX线程的错误,如种族和线程,当他们退出持有互斥锁一个Valgrind的工具。



文章来源: C++ libpthread program segfaults for unknown reason