2012-02-02 36 views
5

Tôi muốn, như tiêu đề nói, in nội dung của ngăn xếp trong chương trình C của tôi.Làm cách nào để in nội dung của ngăn xếp trong chương trình C?

Dưới đây là các bước tôi đã:

  • tôi đã thực hiện một file lắp ráp đơn giản (helper.s) trong đó có một hàm trả về địa chỉ của thanh ghi ebp tôi và một hàm trả về địa chỉ của tôi đặc biệt là đăng ký

    .globl get_esp 
    
    get_esp: 
        movl %esp, %eax 
        ret 
    # get_ebp is defined similarly, and included in the .globl section 
    
  • tôi gọi là get_esp()get_ebp() chức năng từ chương trình của tôi C (fpC = get_esp(); nơi FPC là một int)
  • I (thành công, tôi nghĩ) in chỉnh sửa địa chỉ của sổ đăng ký đặc biệt và ebp của tôi (fprintf (stderr, "%x", fcP);)
  • Tôi đã thử và không in được nội dung của sổ đăng ký đặc biệt của mình. (Tôi đã thử fprintf (sderr, "%d", *fcP);fprintf (sderr, "%x", *((int *)fcP));, cùng với các phương pháp khác). Chương trình của tôi truy cập lỗi phân đoạn khi chạy khi dòng này được xử lý.

Tôi đang làm gì sai?

EDIT: Điều này phải được thực hiện bằng cách gọi các chức năng lắp ráp này để có được các con trỏ ngăn xếp. EDIT2: Đây là bài tập về nhà.

+0

Bạn có ý gì khi nói không thành công? Bạn đã nhận được kết quả gì và bạn mong đợi điều gì? –

+0

Để in con trỏ, bạn phải sử dụng 'printf ("% p ", (void *) (p))'. "Nội dung của% esp" là một con trỏ. –

+0

@CarlNorum: Không, việc sử dụng 'printf' chỉ đơn giản là bắt buộc theo tiêu chuẩn C. (Cf. "đối số variadic".) –

Trả lời

5

Nếu bạn sử dụng hệ thống GNU, bạn có thể sử dụng phần mở rộng của GNU đối với thư viện C để xử lý các backtraces, xem here.

#include <execinfo.h> 

int main(void) 
{ 
    //call-a-lot-of-functions 
} 

void someReallyDeepFunction(void) 
{ 
    int count; 
    void *stack[50]; // can hold 50, adjust appropriately 
    char **symbols; 

    count = backtrace(stack, 50); 
    symbols = backtrace_symbols(stack, count); 

    for (int i = 0; i < count; i++) 
     puts(symbols[i]); 

    free(symbols); 
} 
+0

Điều đó trông giống như một cách tốt để đi về nó, nhưng tôi cần phải thực hiện điều này bằng cách sử dụng các chức năng lắp ráp (mỗi yêu cầu chuyển nhượng). Tôi nên đã xác định rằng trong vấn đề của tôi ban đầu. – Nate

+0

Điều quan trọng là bạn đánh dấu các câu hỏi bài tập về nhà làm bài tập về nhà. – dreamlax

+0

Xin lỗi về điều đó. Đã chỉnh sửa bài đăng gốc. – Nate

4

get_esp lợi nhuận esp vì nó nằm trong phạm vi chức năng. Nhưng điều này không giống như esp trong chức năng gọi điện, bởi vì hoạt động cuộc gọi thay đổi esp.

Tôi khuyên bạn nên thay thế hàm bằng một đoạn lắp ráp nội tuyến. Bằng cách này, esp sẽ không thay đổi khi bạn cố đọc nó.

Ngoài ra, in tới sderr sẽ không hữu ích. Từ kinh nghiệm của tôi, stderr hoạt động tốt hơn nhiều.

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