簡體   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