Ошибка сегмента при использовании std :: string на встроенной платформе Linux - PullRequest
5 голосов
/ 10 марта 2010

Я пару дней работал над проблемой, связанной с тем, что мое приложение работает на встроенной платформе Arm Linux. К сожалению, платформа не позволяет мне использовать какие-либо обычные полезные инструменты для нахождения точной проблемы. Когда тот же код выполняется на ПК под управлением Linux, я не получаю такой ошибки.

В приведенном ниже примере я могу надежно воспроизвести проблему, раскомментировав строку, список или векторные строки. Оставив закомментированные результаты, приложение работает до конца. Я ожидаю, что что-то портит кучу, но я не вижу что? Программа будет работать в течение нескольких секунд, прежде чем выдает ошибку сегментации.

Код скомпилирован с использованием кросс-компилятора arm-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 );
}

Ответы [ 4 ]

5 голосов
/ 10 марта 2010

Может быть, вы используете однопоточную версию стандартной библиотеки, включая операторы new и delete?

Эти объекты строятся в пределах охраны вашего мьютекса, но разрушаются за пределами этих границ, поэтому деструкторы могут наступать друг на друга. Одним из быстрых тестов было бы заключить скобки в область видимости {} вокруг объявления killer.

Подробнее см. в документации gcc .

0 голосов
/ 18 марта 2010

При разработке и отладке ошибок сегментации для встроенной платформы Arm Linux я часто добавляю код для печати стека backtrace из обработчика сигнала SIGSEGV. Возможно, реализация, которую я опишу здесь , может вам пригодиться.

Я строю со следующими параметрами gcc / g ++ (среди прочих):

arm-linux-g++ -Wall -pipe -rdynamic -fno-omit-frame-pointer test.cpp -o test
0 голосов
/ 18 марта 2010

Вы пробовали -Os и -O0?какой у тебя arm-linux-g ++ --version?

0 голосов
/ 10 марта 2010

Вы не говорите, что такое PTHREAD_MUTEX_INITIALIZER, но вы вызываете pthread_mutex_init для TestSeg :: _ logLock? Это возможно, если вы используете не инициализированный мьютекс, в котором стек и / или куча операций этих конструкторов мешают вашему мьютексу.

...