2010-04-05 23 views

Trả lời

8

Đó là vì bạn không biên dịch với gỡ lỗi được bật. Hãy thử xem gcc -g file.c

+0

Bạn có nghĩa là gdb không thể được sử dụng để gỡ lỗi programe arbitary? – user198729

+2

@ user198729: Bạn có thể sử dụng GDB để gỡ lỗi chương trình tùy ý, nhưng bạn phải làm việc chăm chỉ hơn nhiều nếu chương trình không có bảng biểu tượng. Về cơ bản, bảng biểu tượng cho trình gỡ rối biết về các hàm và các biến và số dòng và các tệp nguồn - và nếu nó bị thiếu, tất cả những gì bạn đã để lại là trình biên dịch. –

+0

@ Jonathan Leffler, có vẻ như bạn có nghĩa là vẫn có thể gỡ lỗi chương trình ngay cả khi nó không có bảng biểu tượng, bạn có thể đưa ra một ví dụ không? – user198729

2

Bảng biểu tượng chứa thông tin gỡ lỗi cho trình gỡ lỗi biết vị trí bộ nhớ tương ứng với ký hiệu nào (như tên hàm và tên biến) trong tệp mã nguồn gốc. Bảng biểu tượng thường được lưu trữ bên trong tệp thực thi, có.

gdb cho bạn biết rằng nó không thể tìm thấy bảng đó. Nếu bạn đã biên dịch bằng gcc, trừ khi bạn đã sử dụng cờ -g, nó sẽ không bao gồm bảng biểu tượng trong tệp. Phương pháp dễ nhất có thể là biên dịch lại tệp của bạn bằng -g. gdb sau đó sẽ tự động tìm thấy thông tin bảng biểu tượng.

Hoặc thêm cờ -g vào đối số dòng lệnh của gcc hoặc vào Makefile mà bạn đã sử dụng để biên dịch chương trình. (Rất nhiều lần, sẽ có một biến được gọi là CFLAGS hoặc tương tự bên trong Makefile).

Nếu bạn đang cố gắng gỡ lỗi chương trình của bên thứ ba tùy ý, rất nhiều lần thông tin sẽ bị "tước" khỏi nó. Điều này được thực hiện để làm cho kỹ thuật đảo ngược khó hơn và làm cho kích thước của tệp thực thi nhỏ hơn. Trừ khi bạn có quyền truy cập vào mã nguồn và có thể tự biên dịch chương trình, bạn sẽ có một thời gian rất khó khăn khi sử dụng gdb trên đó.

+0

Tại sao một số công cụ khác như softice có thể gỡ lỗi chương trình tùy ý, không phải chúng sử dụng các kỹ thuật tương tự như gdb? – user198729

+0

Cũng tương tự như vậy. Bạn có thể làm những việc tương tự với gdb như đặt breakpoint trên các cuộc gọi hệ thống hoặc kiểm tra mã assembly hoặc xem xét các giá trị đăng ký hoặc nội dung của các địa chỉ bộ nhớ cụ thể, ngay cả khi không có bảng biểu tượng. Bạn cũng có thể muốn kiểm tra strace hoặc ltrace nếu bạn đang sử dụng Linux. – RarrRarrRarr

+0

Nhưng bất kể lệnh nào tôi gõ, gdb luôn trả lời bằng 'Không có bảng biểu tượng nào được tải. Sử dụng lệnh "file", có vẻ như không thể gỡ lỗi một chương trình mà không có bảng biểu tượng ... Hoặc có thể có cái gì đó tôi đang bỏ lỡ? – user198729

18

Có hai bộ ký hiệu mà gdb sử dụng.

Tập hợp -g là các biểu tượng gỡ lỗi, giúp mọi thứ dễ dàng hơn nhiều khi chúng cho phép bạn xem mã của bạn và xem các biến trong khi gỡ lỗi.

Một bộ biểu tượng khác được bao gồm theo mặc định khi bạn biên dịch. Đây là những biểu tượng liên kết và sống trong bảng biểu ELF (biểu mẫu có thể liên kết có thể thực hiện được). Điều này chứa thông tin ít hơn rất nhiều so với các biểu tượng gỡ lỗi, nhưng chứa những thứ quan trọng nhất, chẳng hạn như địa chỉ của những thứ trong tệp thực thi của bạn (hoặc thư viện hoặc tệp đối tượng). Nếu không có thông tin này, gdb thậm chí sẽ không biết chính ở đâu, vì vậy (gdb) break main sẽ không thành công.

Nếu bạn không có biểu tượng gỡ lỗi (-g) thì bạn vẫn có thể (gdb) break main nhưng gdb sẽ không có bất kỳ khái niệm nào về các dòng mã trong tệp nguồn của bạn. Khi bạn cố gắng bước qua mã, bạn sẽ chỉ tiến một lệnh máy tại một thời điểm, thay vì một dòng tại một thời điểm.

Lệnh dải thường được sử dụng để strip tắt các ký hiệu từ tệp thực thi (hoặc tệp đối tượng khác). Điều này thường được sử dụng nếu bạn không muốn ai đó có thể nhìn thấy biểu tượng hoặc nếu bạn muốn tiết kiệm dung lượng trong tệp. Biểu tượng bảng có thể nhận được lớn. Dải loại bỏ cả hai biểu tượng gỡ lỗi và các biểu tượng liên kết, nhưng nó có một số thiết bị chuyển mạch dòng lệnh có thể giới hạn những gì nó loại bỏ.

Nếu bạn chạy lệnh file trên chương trình của mình, một trong những điều nó sẽ cho bạn biết là thời tiết hoặc không thực thi được đã bị xóa.

$ gcc my_prog.c -o my_prog 
$ file my_prog 
my_prog: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.15, not stripped 
$ strip my_prog 
my_prog: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.15, stripped 
$ 
+0

bạn có chắc chắn các biểu tượng liên kết ('.dynsym', phải không?) Được xóa bởi' dải'? Theo [this] (http://stackoverflow.com/a/8624223/264047) thì không. –

+2

'strip' có các tùy chọn kiểm soát các biểu tượng nào và không bị xóa. Hành vi mặc định thường không phá vỡ mọi thứ. – nategoose

+0

@nategoose bạn có thể vui lòng cho chúng tôi biết thời tiết hoặc biểu tượng gỡ lỗi inlcude các biểu tượng trong bảng biểu tượng ELF hay không. Nói cách khác, GDB chỉ sử dụng các biểu tượng gỡ lỗi khi ứng dụng đã được biên dịch bằng -g? –

1

Tìm điểm nhập của ứng dụng.

objdump -f main 

    main:  file format elf32-i386 
    architecture: i386, flags 0x00000112: 
    EXEC_P, HAS_SYMS, D_PAGED 
    start address 0x08048054 

Đặt một breakpoint có sử dụng trình gỡ lỗi gnu

gdb 

    exec-file main 
    break *0x8048054 
    set disassemble-next-line on 
    run 

Sau đó, bước qua mã

gdb 

    stepi 

Lưu ý đặc biệt

Nếu bạn đang sử dụng phiên bản mới nhất của Ubuntu bạn sẽ không bị ảnh hưởng bởi điều này, nhưng bạn có thể chạy vào lỗi này nếu bạn đang chạy Ubuntu 10.04 o r cũ hơn.

https://bugs.launchpad.net/ubuntu/+source/gdb/+bug/151518G 

Giải pháp sẽ là bắt đầu gỡ lỗi tại địa chỉ điểm nhập cộng một.

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