У меня есть приложение, связанное с libpthread. Ядром приложения являются два FIFO, совместно используемые четырьмя потоками (два потока на один FIFO, то есть;). Класс FIFO синхронизируется с использованием мьютексов pthread и хранит указатели на большие классы (содержащие буферы размером около 4 КБ), размещенные внутри статической памяти, с использованием перегруженных операторов new и delete (здесь динамического выделения нет).
Сама программа обычно работает нормально, но время от времени происходит сбой без видимой причины. Проблема в том, что я не могу отладить 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 "положить-между-каждой-строкой-и-увидеть-где-то-это-segfaults-плюс-запомнить-pids-и-вещи" кажется, что во время usleep происходит сбой (?).
Понятия не имею, что еще может быть не так. Он может работать в течение часа или около того, а затем внезапно отключиться от сети без видимой причины.
Кто-нибудь сталкивался с подобной проблемой?