2010-03-09 5 views
5

Ich habe seit ein paar Tagen an einem Problem mit meiner Anwendung auf einer Embedded Arm Linux-Plattform gearbeitet. Leider schließt die Plattform mich von den üblichen nützlichen Tools aus, um das genaue Problem zu finden. Wenn derselbe Code auf dem PC mit Linux ausgeführt wird, erhalte ich keinen solchen Fehler.Seg Fault bei der Verwendung von std :: string auf einer Embedded-Linux-Plattform

In dem folgenden Beispiel kann ich das Problem zuverlässig reproduzieren, indem Sie die Zeichenfolge, die Liste oder die Vektorlinien auskommentieren. Sie haben die kommentierten Ergebnisse in der Anwendung zum Abschluss gebracht. Ich erwarte, dass etwas den Haufen verderbt, aber ich kann nicht sehen was? Das Programm wird einige Sekunden lang ausgeführt, bevor ein Segmentierungsfehler ausgegeben wird.

Der Code wird mit einem Arm-Linux-Cross-Compiler kompiliert:

arm-linux-g++ -Wall -otest fault.cpp -ldl -lpthread 
arm-linux-strip test 

Irgendwelche Ideen sehr geschätzt.

#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); 
} 
+0

Sie std überprüft haben :: string funktioniert ohne pThreads auf der Plattform? –

+1

Und versuchte, sagen wir, 2 Fäden statt 100? – indiv

+1

Ja, zu viele Threads sind eine wahrscheinliche Ursache für den Seg-Fehler. –

Antwort

5

Vielleicht verwenden Sie eine Singlethread-Version der Standardbibliothek, einschließlich der Operatoren new und delete?

Diese Objekte werden innerhalb der Wachen Ihres Mutex konstruiert, aber außerhalb dieser Grenzen zerstört, so dass die Destruktoren aufeinander treten könnten. Ein schneller Test wäre es, die Scoping-Klammern {} um die Deklaration killer zu setzen.

Weitere Informationen finden Sie unter the gcc documentation.

+0

Danke für den Hinweis Mark. Ich habe es mit den Scoping-Klammern versucht, und das Problem verschwindet.Ist das die empfohlene Art, Objekte in den Mutex-Wächtern zu deklarieren, oder habe ich etwas grundsätzlich falsch gemacht? Wenn "arm-linux-g ++ -v" aufgerufen wird, wird nur die Version angezeigt und überhaupt keine --enable-threads. Bedeutet das, dass ich die Single-Thread-Version verwende? Da ich den Cross-Compiler nicht ändern kann (der Provider unterstützt nur diesen), was ist meine beste Vorgehensweise? – Brad

+0

Welche Version liefert "arm-linux-g ++ -v"? Das Übergeben der '-v' Option druckt nur die Versionsnummer mit meinem gcc 2.95.2 Arm Cross-Compiler, aber die' -v' Option listet '--enable-threads = posix' mit meinem gcc 3.4.5 Arm Cross-Compiler auf . – jschmier

+0

Hi jschmier, Entschuldigung, ich war einige Zeit von dem Projekt weg und habe dieses Problem jetzt untersucht. Wie bei Ihnen, wird beim Passieren von -v nur die Versionsnummer ausgegeben. Leider bin ich auf die Verwendung des gcc 2.95.2 Arm Cross-Compilers beschränkt, da dies alles ist, was der Lieferant mit seiner eingebetteten Plattform unterstützt. Hatten Sie das gleiche Problem mit Ihrem Cross-Compiler? Wie hast du daran gearbeitet? Danke – Brad

0

Sie nicht sagen, was PTHREAD_MUTEX_INITIALIZER, sondern rufen Sie pthread_mutex_init auf testseg :: _ logLock? Wenn Sie einen unidentifizierten Mutex verwenden, ist es möglich, dass Stapel- und/oder Heap-Operationen dieser Konstruktoren Ihren Mutex beeinträchtigen.

+0

'PTHREAD_MUTEX_INITIALIZER' ist die Standardmethode, um POSIX-Mutex statisch zu initialisieren, ohne' pthread_mutex_init (3) 'aufzurufen. –

0

Haben Sie -Os und -O0 versucht? Was ist dein Arm-Linux-g ++ - Version?

0

Beim Entwickeln und Debuggen von Segmentierungsfehlern für eine eingebettete Arm-Linux-Plattform füge ich häufig Code hinzu, um einen Stapel backtrace aus dem Signalhandler SIGSEGV zu drucken. Vielleicht kann die Implementierung, die ich beschreibe here für Sie von Nutzen sein.

Ich baue mit den folgenden gcc/g ++ Optionen (unter anderem):

arm-linux-g++ -Wall -pipe -rdynamic -fno-omit-frame-pointer test.cpp -o test