我有一个libpthread链接的应用程序。该应用程序的核心是由四个线程共享的两个FIFO(每个FIFO两个线程;)。使用pthread互斥锁同步FIFO类,它使用重载的new和delete运算符(这里没有动态分配)存储指向静态内存中分配的大类(包含大小约为4kb的缓冲区)的指针。
程序本身通常可以正常工作,但不时会出现段错误。问题是,我无法正确调试段错误,因为我正在使用旧的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;
};
但它没有改变,回溯看起来一样......
在一些老式的学习之间 - 每个行 - 并且看到 - 在哪里 - 段错误 - 再加上记住 - 并且 - 并且有什么东西的调试会话之后,似乎它在usleep(?)期间会出现段错误。
我不知道还有什么可能是错的。它可以工作一个小时左右,然后突然发生段落故障。
有没有人遇到过类似的问题?
答案 0 :(得分:1)
从我的answer到 How to generate a stacktrace when my gcc C++ app crashes :
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.
这可以解释为什么您难以通过信号处理程序的回溯确定segfault的位置。我的answer还包含此限制的解决方法。
如果您想了解您的应用程序实际上是如何在内存中布局的(即0x80.....
地址),您应该能够从gcc生成 map 文件。这通常通过-Wl,-Map,output.map
完成,它将-Map output.map
传递给链接器。
答案 1 :(得分:0)
您可以在平台上访问Helgrind吗?它是一个Valgrind工具,用于检测POSIX线程错误,例如在退出时保持互斥锁的比赛和线程。