2010-03-09 5 views
5

임베디드 암 Linux 플랫폼에서 실행되는 응용 프로그램 문제로 며칠 동안 작업했습니다. 불행하게도이 플랫폼은 정확한 문제를 찾는 데 유용한 도구를 사용하지 못하도록합니다. Linux를 실행하는 PC에서 동일한 코드를 실행하면 오류가 발생하지 않습니다.임베디드 Linux 플랫폼에서 std :: string을 사용할 때의 Seg 오류

아래 예제에서 문자열, 목록 또는 벡터 선의 주석을 제거하여 문제를 확실히 재현 할 수 있습니다. 주석 처리 된 상태로두면 응용 프로그램이 완료 될 때까지 실행됩니다. 무언가가 힙을 손상 시키길 기대하지만, 나는 무엇을 볼 수 없습니까? 세그먼테이션 오류가 발생하기 전에 프로그램이 몇 초 동안 실행됩니다.

코드

는 아암 리눅스 크로스 컴파일러를 이용하여 컴파일된다

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

당신이 표준을 확인했다 :: 캐릭터 라인은, 플랫폼에의 pthreads없이 작동? –

+1

그리고 100 개 대신 2 개의 스레드를 시도 했습니까? – indiv

+1

예, 너무 많은 스레드가 seg 오류의 원인 일 수 있습니다. –

답변

5

아마도 newdelete 연산자를 포함하여 단일 스레드 버전의 표준 라이브러리를 사용하고 있습니까?

이러한 개체는 뮤텍스의 보호자 내에서 생성되지만 해당 경계 외부에서 소멸되므로 소멸자가 서로 밟을 수 있습니다. 빠른 테스트 중 하나는 의 범위를 killer으로 지정하는 것입니다.

자세한 내용은 the gcc documentation을 참조하십시오.

+0

Mark에게 조언 해 주셔서 감사합니다. 범위 지정 대괄호로 시도했지만 문제는 사라집니다.이것은 뮤텍스 가드 내부에서 객체를 선언하는 데 권장되는 방법입니까, 아니면 근본적으로 잘못된 것을 수행 했습니까? "arm-linux-g ++ -v"를 호출하면 버전 만 생성되고 --enable-threads는 전혀 나열되지 않습니다. 이것은 단일 스레드 버전을 사용한다는 것을 의미합니까? 교차 컴파일러를 변경할 수있는 옵션이 없으므로 (공급자 만이이 기능을 지원합니다) 최선의 행동 방침은 무엇입니까? – Brad

+0

"arm-linux-g ++ -v"의 버전은 무엇입니까? '-v' 옵션을 건네 주면 gcc 2.95.2 암 크로스 컴파일러와 함께 버전 번호 만 출력되지만'-v' 옵션은 my gcc로'--enable-threads = posix'를 나열합니다 3.4.5 암 크로스 컴파일러 . – jschmier

+0

안녕하세요 jschmier, 죄송합니다. 지금 당분간이 프로젝트에서 멀어져서이 문제를 다시보고 있습니다. 자신과 마찬가지로 -v를 전달하면 버전 번호 만 인쇄됩니다. 불행히도 gcc 2.95.2 Arm 크로스 컴파일러는 모든 공급자가 임베디드 플랫폼에서 지원하므로 제한적입니다. 크로스 컴파일러에서 동일한 문제가 발생 했습니까? 어떻게 그 주변에서 일 했니? 감사합니다. – Brad

0

당신은 PTHREAD_MUTEX_INITIALIZER가 무엇인지 말을하지 않습니다,하지만 당신은 :: _ logLock TestSeg에 pthread_mutex_init를 호출? 생성자의 스택 및/또는 힙 조작이 뮤텍스를 방해하는 비 고유화 뮤텍스를 사용하는 경우 가능합니다.

+0

'PTHREAD_MUTEX_INITIALIZER'는'pthread_mutex_init (3)'을 호출하지 않고 POSIX 뮤텍스를 정적으로 초기화하는 표준 방법입니다. –

0

시도해 보셨습니까 -Os 및 -O0? 너 팔 -linux-g ++ 버전?

0

임베디드 암 Linux 플랫폼에 대한 세그먼트 화 오류를 개발하고 디버깅 할 때 종종 SIGSEGV 신호 처리기에서 스택 backtrace을 인쇄하는 코드를 추가합니다. 아마도 내가 구현 한 내용은 here 일 수 있습니다.

내가 (다른 사람의 사이에서) 다음의 gcc/g ++ 옵션을 구축 :

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