Я работал в течение нескольких дней над проблемой со своим приложением, работающим на встроенной Руке платформа Linux. К сожалению, платформа устраняет меня от использования любого из обычных полезных инструментов для нахождения точной проблемы. Когда тот же код выполняется на ПК, запускающем Linux, я не получаю такой ошибки.
В образце ниже, я могу надежно воспроизвести проблему путем некомментария строки, списка или векторных строк. Отъезд их прокомментировал результаты в приложении, работающем к завершению. Я ожидаю, что что-то повреждает "кучу", но я не вижу что? Программа будет работать в течение нескольких секунд прежде, чем дать отказ сегментации.
Код компилируется с помощью кросс-компилятора Linux руки:
arm-linux-g++ -Wall -otest fault.cpp -ldl -lpthread
arm-linux-strip test
Любые идеи значительно ценятся.
#include <stdio.h>
#include <vector>
#include <list>
#include <string>
using namespace std;
/////////////////////////////////////////////////////////////////////////////
class TestSeg
{
static pthread_mutex_t _logLock;
public:
TestSeg()
{
}
~TestSeg()
{
}
static void* TestThread( void *arg )
{
int i = 0;
while ( i++ < 10000 )
{
printf( "%d\n", i );
WriteBad( "Function" );
}
pthread_exit( NULL );
}
static void WriteBad( const char* sFunction )
{
pthread_mutex_lock( &_logLock );
printf( "%s\n", sFunction );
//string sKiller; // <----------------------------------Bad
//list<char> killer; // <----------------------------------Bad
//vector<char> killer; // <----------------------------------Bad
pthread_mutex_unlock( &_logLock );
return;
}
void RunTest()
{
int threads = 100;
pthread_t _rx_thread[threads];
for ( int i = 0 ; i < threads ; i++ )
{
pthread_create( &_rx_thread[i], NULL, TestThread, NULL );
}
for ( int i = 0 ; i < threads ; i++ )
{
pthread_join( _rx_thread[i], NULL );
}
}
};
pthread_mutex_t TestSeg::_logLock = PTHREAD_MUTEX_INITIALIZER;
int main( int argc, char *argv[] )
{
TestSeg seg;
seg.RunTest();
pthread_exit( NULL );
}
Возможно, вы используете однопоточную версию стандартной библиотеки, включая операторы new
и delete
?
Эти объекты создаются в пределах защиты вашего мьютекса, но уничтожаются вне этих пределов, поэтому деструкторы могут наступать друг на друга. Одним из быстрых тестов будет размещение скобок {}
вокруг объявления killer
.
Подробнее см. в документации gcc.
Вы не говорите, что такое PTHREAD_MUTEX_INITIALIZER, но вызываете ли вы pthread_mutex_init в TestSeg :: _ logLock? Это возможно, если вы используете неинициализированный мьютекс, когда операции стека и / или кучи из этих конструкторов мешают вашему мьютексу.
При разработке и отладке ошибок сегментации для встроенной платформы Arm Linux я часто добавляю код для печати стека трассировки из SIGSEGV
обработчик сигналов. Возможно, реализация, которую я описываю здесь , может быть вам полезна.
Я использую следующие параметры gcc / g ++ (среди прочих):
arm-linux-g++ -Wall -pipe -rdynamic -fno-omit-frame-pointer test.cpp -o test
Вы пробовали -Os и -O0? какова ваша версия arm-linux-g ++?