2010-03-09 8 views
5

Ho lavorato per un paio di giorni su un problema con la mia applicazione in esecuzione su una piattaforma Arm Linux incorporata. Purtroppo la piattaforma mi impedisce di utilizzare uno dei soliti strumenti utili per trovare il problema esatto. Quando lo stesso codice viene eseguito sul PC con Linux, non ottengo alcun errore di questo tipo.Seg Errore quando si utilizza std :: string su una piattaforma Linux incorporata

Nell'esempio seguente, posso riprodurre in modo affidabile il problema rimuovendo la stringa, l'elenco o le linee vettoriali. Lasciandoli i risultati commentati nell'applicazione in esecuzione fino al completamento. Mi aspetto che qualcosa stia corrompendo il mucchio, ma non riesco a vedere cosa? Il programma verrà eseguito per alcuni secondi prima di dare un errore di segmentazione.

il codice viene compilato utilizzando un cross compilatore braccio-linux:

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

Tutte le idee molto apprezzato.

#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

Hai controllato std :: string funziona senza pthreads sulla piattaforma? –

+1

E provato, ad esempio, 2 thread anziché 100? – indiv

+1

sì, troppi thread è una probabile causa dell'errore del segmento. –

risposta

5

Forse stai usando una versione a thread singolo della libreria standard, inclusi gli operatori new e delete?

Questi oggetti sono stati costruiti all'interno delle guardie del tuo mutex, ma sono distrutti al di fuori di questi limiti, quindi i distruttori potrebbero fare un passo l'uno sull'altro. Un test rapido consisterebbe nel mettere le parentesi di scoping {} attorno alla dichiarazione di killer.

Vedere the gcc documentation per ulteriori informazioni.

+0

Grazie per il consiglio Marco. Ho provato con le parentesi di scoping e il problema scompare.È questo il modo raccomandato di dichiarare oggetti all'interno delle guardie Mutex o ho fatto qualcosa di fondamentalmente sbagliato? Quando si chiama "arm-linux-g ++ -v" restituisce solo la versione e non elenca affatto --enable-threads. Questo significa che sto usando la versione a thread singolo? Poiché non ho la possibilità di modificare il cross-compiler (il provider supporta solo questo), qual è il mio miglior modo di agire? – Brad

+0

Quale versione fornisce "arm-linux-g ++ -v"? Passando l'opzione '-v' si stampa solo il numero di versione con il mio cross-compilatore gcc 2.95.2 Arm, ma l'opzione' -v' elenca '--enable-threads = posix' con il mio cross-compilatore gcc 3.4.5 Arm . – jschmier

+0

Ciao jschmier, Mi dispiace per essere stato lontano dal progetto per un po 'di tempo e di nuovo guardando questo problema ora. Come te, passando -v stampa solo il numero di versione. Sfortunatamente sono limitato all'utilizzo del cross-compilatore gcc 2.95.2 perché questo è tutto il supporto del fornitore con la loro piattaforma integrata. Hai avuto lo stesso problema con il tuo cross compilatore? Come hai lavorato intorno ad esso? Grazie – Brad

0

Tu non dici quello che PTHREAD_MUTEX_INITIALIZER è, ma stai chiamando pthread_mutex_init su TestSeg :: _ logLock? È possibile che tu stia usando un mutex non specificato che impila e/o le operazioni di heap da quei costruttori interferiscono con il tuo mutex.

+0

'PTHREAD_MUTEX_INITIALIZER' è il metodo standard per inizializzare staticamente il mutex POSIX senza chiamare' pthread_mutex_init (3) '. –

0

Hai provato -Os e -O0? qual è il tuo braccio-linux-g ++ --version?

0

Durante lo sviluppo e il debug di errori di segmentazione per una piattaforma Arm Linux incorporata, aggiungo spesso codice per stampare uno stack backtrace dal gestore di segnale SIGSEGV. Forse l'implementazione che descrivo here può essere di qualche utilità per voi.

costruisco con le seguenti opzioni gcc/g ++ (tra gli altri):

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