2010-03-09 26 views
5

Tôi đã làm việc trong một vài ngày về một vấn đề với ứng dụng của tôi đang chạy trên nền tảng Arm Linux được nhúng. Thật không may nền tảng này ngăn cản tôi sử dụng bất kỳ công cụ hữu ích thông thường nào để tìm ra vấn đề chính xác. Khi cùng một mã được chạy trên PC chạy Linux, tôi không nhận được lỗi như vậy.Lỗi khi sử dụng std :: string trên nền tảng Linux nhúng

Trong ví dụ bên dưới, tôi có thể tái tạo lại vấn đề một cách đáng tin cậy bằng cách bỏ ghi chú chuỗi, danh sách hoặc đường vectơ. Để họ nhận xét kết quả trong ứng dụng đang chạy để hoàn thành. Tôi hy vọng rằng một cái gì đó đang làm hỏng đống, nhưng tôi không thể nhìn thấy cái gì? Chương trình sẽ chạy trong vài giây trước khi đưa ra lỗi phân đoạn.

Mã này được biên soạn bằng cách sử dụng trình biên dịch chéo cánh tay-linux:

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

Bất kỳ ý tưởng đánh giá cao.

#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

có bạn kiểm tra std :: string hoạt động mà không pthreads trên bục giảng? –

+1

Và cố gắng, nói rằng, 2 chủ đề thay vì 100? – indiv

+1

có, quá nhiều luồng là nguyên nhân có khả năng gây ra lỗi seg. –

Trả lời

5

Có thể bạn đang sử dụng phiên bản đơn luồng của thư viện chuẩn, bao gồm các toán tử newdelete?

Các đối tượng đó đang được xây dựng bên trong bảo vệ của mutex của bạn, nhưng bị phá hủy bên ngoài những giới hạn đó, vì vậy các destructors có thể bước vào nhau. Một thử nghiệm nhanh chóng là đặt các dấu ngoặc phạm {} vào khoảng khai báo killer.

Xem the gcc documentation để biết thêm.

+0

Cảm ơn lời khuyên Mark. Tôi đã thử với các dấu ngoặc phạm, và vấn đề biến mất.Đây có phải là cách được khuyến nghị để khai báo các đối tượng bên trong nhân viên bảo vệ Mutex hay tôi đã làm điều gì đó sai về cơ bản? Khi gọi "arm-linux-g ++ -v", nó chỉ mang lại phiên bản và không liệt kê tất cả các chuỗi có thể mở. Điều này có nghĩa là tôi đang sử dụng phiên bản luồng đơn? Vì tôi không có tùy chọn thay đổi trình biên dịch chéo (nhà cung cấp chỉ hỗ trợ trình biên dịch này), hành động tốt nhất của tôi là gì? – Brad

+0

Sản lượng "arm-linux-g ++ -v" phiên bản nào? Việc chuyển tùy chọn '-v' chỉ in số phiên bản với gcc 2.95.2 của tôi là trình biên dịch chéo, nhưng tùy chọn' -v' liệt kê '--enable-threads = posix' với trình biên dịch chéo gcc 3.4.5 của tôi . – jschmier

+0

Xin chào jschmier, Xin lỗi, tôi đã rời khỏi dự án một thời gian và nhìn lại vấn đề này ngay bây giờ. Giống như chính bạn, đi qua -v chỉ in số phiên bản. Thật không may, tôi bị hạn chế sử dụng gcc 2.95.2 Arm cross-compiler vì đây là tất cả các nhà cung cấp hỗ trợ với nền tảng nhúng của họ. Bạn đã có cùng một vấn đề với trình biên dịch chéo của bạn? Làm thế nào bạn làm việc xung quanh nó? Cảm ơn – Brad

0

Bạn không nói PTHREAD_MUTEX_INITIALIZER là gì, nhưng bạn đang gọi pthread_mutex_init trên TestSeg :: _ logLock? Nó có thể nếu bạn đang sử dụng một mutex unintialized rằng ngăn xếp và/hoặc hoạt động đống từ những nhà xây dựng đang can thiệp với mutex của bạn.

+0

'PTHREAD_MUTEX_INITIALIZER' là cách tiêu chuẩn để khởi tạo tĩnh mutix POSIX mà không cần gọi' pthread_mutex_init (3) '. –

0

Bạn đã thử -Os và -O0 chưa? whats arm-linux-g ++ --version của bạn?

0

Khi phát triển và gỡ lỗi lỗi phân đoạn cho nền tảng Arm Linux được nhúng, tôi thường thêm mã để in ngăn xếp backtrace từ trình xử lý tín hiệu SIGSEGV. Có lẽ việc triển khai tôi mô tả here có thể là một số cách sử dụng cho bạn.

tôi xây dựng với các tùy chọn gcc/g ++ sau đây (trong số những người khác):

arm-linux-g++ -Wall -pipe -rdynamic -fno-omit-frame-pointer test.cpp -o test 
Các vấn đề liên quan