2017-06-28 26 views
5

Vì lý do khắc phục sự cố, tôi muốn có thể truy xuất và in ngăn xếp người gọi của chức năng hiện đang chạy. Tôi đã thử những điều sau đây:Làm cách nào để truy xuất ngăn xếp ngăn xếp của ngăn xếp của hàm hiện đang chạy?

/******************************************************************************* 
* * 
* * xxxTracePrint - stack trace print function 
* * 
* * RETURNS: OK or ERROR 
* */ 

static void xxxTracePrint 
    (
     INSTR *caller, 
      int func, 
       int nargs, 
        int *args 
         ) 
{ 
    char buf [250]; 
    int ix; 
    int len = 0; 

    len += sprintf (&buf [len], "%#10x: %#10x (", (int)caller, func); 
    for (ix = 0; ix < nargs; ix++) { 
     if (ix != 0) 
      len += sprintf (&buf [len], ", "); 
     len += sprintf (&buf [len], "%#x", args [ix]); 
    } 

    len += sprintf (&buf [len], ")\n"); 

    printf (buf); 
} 

/******************************************************************************* 
* * 
* * xxxTrace - stack trace 
* * 
* * RETURNS: OK or ERROR 
* */ 

int xxxTrace(int tcb) 
{ 
    REG_SET regs; 

    if (tcb == 0) 
     return (ERROR); 

    taskRegsGet (tcb, &regs); 
    trcStack (&regs, (FUNCPTR) xxxTracePrint, tcb); 

    return (OK); 
} 

void DbgTest(void) 
{ 
    xxxTrace(taskIdSelf()); 
} 

nhưng tôi nhận được:

JPAX-DP> DbgTest 
trcStack aborted: error in top frame 
value = 0 = 0x0 

Đây có phải là thậm chí có thể? Tôi có thể làm cái này như thế nào? Tôi đã thấy, đối với taskRegsGet(), họ nói:

Thường trình này chỉ hoạt động tốt nếu công việc được xác định là ổn định, trạng thái không thực hiện là . Tự kiểm tra, ví dụ, không được khuyến khích, vì kết quả là không thể đoán trước.

Nhưng tôi nên áp dụng phương pháp nào khác?

Trình biên dịch là diab và cpu vòm powerpc

+0

Bạn có thể sử dụng backtrace() , nếu nó có sẵn trong vxworks, trang người đàn ông của nó có một ví dụ làm việc quá – Pras

+0

@ Harry bạn có quyền truy cập vào mã surce & WindRiver Workbench? – cerr

+0

@cerr Có Tôi có quyền truy cập vào mã nguồn và bàn làm việc của Windriver – Harry

Trả lời

1

Bạn đã đề cập đến taskRegsGet() đề cập đến việc không nên gọi từ nhiệm vụ hiện đang chạy. Tuy nhiên tôi đã thấy ai đó sử dụng taskDelay (1) với chú thích 'force context save'. Tôi không thể nhận tín dụng cho nó, cũng như tôi không biết nó đáng tin cậy như thế nào, hoặc tác dụng phụ nào có thể có, nhưng nó có thể giúp lấy thông tin chính xác về nhiệm vụ hiện tại:

taskDelay (1);  /* Force context save */ 
taskRegsGet (0, &regs); /* 0 task-id for myself */ 
trcStack (&regs, NULL, 0); /* NULL function pointer for default print fcn, 0 task-id for myself */ 
1

Nếu trình biên dịch của bạn là GCC và các công ước gọi giấy phép kiến ​​trúc của bạn nó (x86 là người đầu tiên mà nói đến cái tâm), tôi khuyên bạn nên sử dụng __builtin_return_address (unsigned int cấp độ). Bạn có thể tìm thêm thông tin tại đây: https://gcc.gnu.org/onlinedocs/gcc/Return-Address.html.

+0

Thật không may, tôi đang sử dụng powerPC và trình biên dịch diab – cerr

+0

Trong khi tay nặng hơn và đòi hỏi nhiều hơn một quá trình lặp đi lặp lại bạn có thể viết một số lắp ráp nội tuyến để di chuyển liên kết đăng ký nội dung vào một biến C mà bạn có thể in. Nhược điểm chính của phương pháp này bên cạnh việc sử dụng cú pháp lắp ghép tài liệu kém tài liệu mà các hỗ trợ của diab là bạn chỉ có thể tìm thấy người gọi hàm hiện tại. Để nhận cuộc gọi tiếp theo, bạn phải sửa đổi chức năng gọi để nhận liên kết đăng ký nội dung. Tôi đã sử dụng điều này trong thẻ ARM và PPC, nhưng đó là một kỹ thuật cuối cùng. – vxWizard

+0

Bạn có thể thực hiện "tt" trên công việc không? tt trên vỏ vxWorks. Ngoài ra, hãy thử đặt các tùy chọn bên dưới cho tác vụ và xem liệu nó có giúp "taskOptionsSet , 2, 0" hay không. –

Các vấn đề liên quan