2010-03-09 20 views
5

Gömülü bir Arm Linux platformunda çalışmamdaki bir uygulamayla ilgili bir kaç gün için çalışıyorum. Ne yazık ki platform, kesin sorunu bulmak için her zamanki yararlı araçlardan herhangi birini kullanmamı engelliyor. Linux çalıştıran PC'de aynı kod çalıştırıldığında, böyle bir hata almıyorum.Seg Hata, gömülü Linux platformunda std :: string kullanırken

Aşağıdaki örnekte, dizeyi, liste veya vektör satırlarını rahatsız ederek sorunu güvenilir bir şekilde yeniden oluşturabilirim. Onları bırakmak, uygulamanın tamamlanmaya kadar devam etmesini sağlar. Bir şeyin yığılmayı bozduğunu umuyorum ama ne göremiyorum? Program bir segmentasyon hatası vermeden önce birkaç saniye çalışacaktır.

kod

bir kol Linux çapraz derleyici derlenir:

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

bir fikir büyük takdir.

#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

Eğer std kontrol ettikten :: dize platformda Pthreads olmadan çalışır? –

+1

Ve 100 yerine 2 iş parçacığı denediniz mi? – indiv

+1

evet, çok fazla iş parçacığı, seg hatasının olası bir nedenidir. –

cevap

5

Belki de new ve delete operatörleri de dahil olmak üzere standart kitaplığın tek bir iş parçacığı sürümünü kullanıyorsunuzdur?

Bu nesneler sizin muteksinizin muhafızları içinde inşa ediliyor, ancak bu sınırların dışında tahrip ediliyor, bu yüzden yıkıcılar birbirlerine adım atıyor olabilir. Bir hızlı test, killer bildirgesinin etrafına {} işaretleme köşebentleri koymak olacaktır. Daha fazla bilgi için bkz: the gcc documentation.

+0

Tavsiyeler için teşekkürler Mark. Kapsam belirleme parantezleri ile denedim ve sorun gider.Bu, Mutex muhafızlarının içindeki nesneleri beyan etmenin veya temelde yanlış bir şey yapmamın öneri şekli mi? "arm-linux-g ++ -v" çağrıldığında, yalnızca sürümü verir ve listelenmez - iş parçacığı dizilerini listelemez. Bu, tek dişli sürümünü kullandığım anlamına mı geliyor? Çapraz derleyiciyi değiştirme seçeneğim olmadığından (sağlayıcı yalnızca bunu desteklemektedir), en iyi yolum nedir? – Brad

+0

"arm-linux-g ++ -v" hangi sürümü veriyor? '-v' seçeneğinin geçirilmesi sadece gcc 2.95.2 sürümüyle çapraz numarayı yazdırabiliyor, fakat' -v' seçeneği ''enable-threads = posix'' gcc 3.4.5-Kol çapraz-derleyicisiyle . – jschmier

+0

Merhaba jschmier, Maalesef projeden bir süre uzak kaldım ve şimdi bu konuya bakıyorum. Kendiniz gibi, geçen geçiş sadece sürüm numarasını yazdırır. Ne yazık ki gcc 2.95.2 Arm cross-compiler'ı kullanmakla sınırlıdır çünkü bu tüm yerleşik destek platformları ile destek sağlayıcısıdır. Çapraz derleyicinizle aynı sorunu yaşadınız mı? Etrafında nasıl çalıştın? Teşekkürler – Brad

0

Sen PTHREAD_MUTEX_INITIALIZER ne söylemiyorum, ama sen :: _ logLock TestSeg üzerinde pthread_mutex_init diyorsun? Bu yapıcılardan gelen yığın ve/veya yığın işlemlerinin muteksinize müdahale eden bir unintialized mutex kullanıyorsanız mümkündür.

+0

'PTHREAD_MUTEX_INITIALIZER',' pthread_mutex_init (3) 'çağırmadan POSIX mutex'i statik olarak başlatmanın standart yoludur. –

0

-Os ve -O0'u denediniz mi? kol-linux-g ++ --version nedir?

0

Gömülü bir Arm Linux platformu için segmentasyon hataları geliştirirken ve hata ayıklama yaparken, genellikle SIGSEGV sinyal işleyicisinden bir yığın backtrace yazdırmak için kod ekliyorum. Belki de here'u tanımladığım uygulama sizin için biraz kullanılabilir.

I (diğerleri arasında) Aşağıdaki gcc/g ++ seçenekleri ile inşa:

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