Tôi có thể sử dụng GDB để gỡ lỗi một quy trình đang chạy không?


110

Trong linux, tôi có thể sử dụng GDB để gỡ lỗi một quy trình hiện đang chạy không?

Câu trả lời:


88

Đúng. Sử dụng attachlệnh. Kiểm tra liên kết này để biết thêm thông tin. Nhập help attachtrên bảng điều khiển GDB sẽ cho kết quả sau:

(gdb) help attach

Đính kèm vào quy trình hoặc tệp bên ngoài GDB. Lệnh này gắn với một mục tiêu khác, cùng loại với targetlệnh " " cuối cùng của bạn (" info files" sẽ hiển thị ngăn xếp mục tiêu của bạn). Lệnh có thể lấy đối số là id quy trình, tên quy trình (với id quy trình tùy chọn làm hậu tố) hoặc tệp thiết bị. Đối với id quy trình, bạn phải có quyền gửi tín hiệu cho quy trình và nó phải có cùng một uid hiệu quả như trình gỡ lỗi. Khi sử dụng " attach" cho một quy trình hiện có, trình gỡ lỗi sẽ tìm chương trình đang chạy trong quy trình, tìm kiếm trước trong thư mục làm việc hiện tại hoặc (nếu không tìm thấy ở đó) bằng cách sử dụng đường dẫn tìm kiếm tệp nguồn (xem directorylệnh ""). Bạn cũng có thể sử dụng filelệnh "" để chỉ định chương trình và tải bảng ký hiệu của nó.


LƯU Ý: Bạn có thể gặp khó khăn khi gắn vào một tiến trình do tính bảo mật được cải thiện trong nhân Linux - ví dụ: gắn vào con của một trình bao từ một trình bao khác.

Bạn có thể cần đặt /proc/sys/kernel/yama/ptrace_scopetùy thuộc vào yêu cầu của mình. Nhiều hệ thống hiện mặc định bằng 1hoặc cao hơn.

The sysctl settings (writable only with CAP_SYS_PTRACE) are:

0 - classic ptrace permissions: a process can PTRACE_ATTACH to any other
    process running under the same uid, as long as it is dumpable (i.e.
    did not transition uids, start privileged, or have called
    prctl(PR_SET_DUMPABLE...) already). Similarly, PTRACE_TRACEME is
    unchanged.

1 - restricted ptrace: a process must have a predefined relationship
    with the inferior it wants to call PTRACE_ATTACH on. By default,
    this relationship is that of only its descendants when the above
    classic criteria is also met. To change the relationship, an
    inferior can call prctl(PR_SET_PTRACER, debugger, ...) to declare
    an allowed debugger PID to call PTRACE_ATTACH on the inferior.
    Using PTRACE_TRACEME is unchanged.

2 - admin-only attach: only processes with CAP_SYS_PTRACE may use ptrace
    with PTRACE_ATTACH, or through children calling PTRACE_TRACEME.

3 - no attach: no processes may use ptrace with PTRACE_ATTACH nor via
    PTRACE_TRACEME. Once set, this sysctl value cannot be changed.

8
Các liên kết bị phá vỡ :( Từ quan điểm của tôi, tôi giống như câu trả lời như này từ J. POLFER Cheers;).
olibre

Tôi đã sửa liên kết.
Attie

điều này cũng hoạt động cho một pid của một quá trình trên một mục tiêu từ xa?
Bionix1441 Ngày

Sau đó, bạn phải chạy một máy chủ gỡ lỗi trên mục tiêu từ xa; sau đó nó sẽ giống nhau.
Carl Norum

Cờ có thể được thay đổi bằng cách sử dụng echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope.
Daisuke Aramaki


24

Đúng. Bạn có thể làm:

gdb program_name program_pid

Một phím tắt sẽ là (giả sử chỉ một phiên bản đang chạy):

gdb program_name `pidof program_name`

Tôi không biết điều đó có tác dụng gì nhưng chắc chắn là nó không hiệu quả với tôi. Nó nói rằng <program_pid> không tồn tại.
Owl

2
Tôi thấy rằng điều này hoạt động tốt nhất vì nó tải bảng biểu tượng ngoài việc đính kèm vào quy trình. Cần lưu ý rằng nó program_namehoạt động nếu bạn đang ở trong cùng một thư mục với tệp nhị phân. Tôi nghĩ rằng một đường dẫn đến tệp nhị phân sẽ hoạt động nếu bạn ở trong một thư mục khác.
KarateSnowMachine

Bạn không quên -pphía trước của program_id? Ngoài ra, có thể cần chạy gdb với sudo để đính kèm vào một tiến trình đang chạy.
mxmlnkn

15

Lệnh sử dụng là gdb attach pidnơi pid là id tiến trình của tiến trình bạn muốn đính kèm vào.


3

Có bạn có thể. Giả sử một quá trình foođang chạy ...

ps-chính mình | grep foo

tìm số PID

gdb -a {số PID}

5
Bạn đang chạy trên bản phân phối nào? Sử dụng phiên bản Fedora gần đây, 'gdb -a' in ra lỗi "option -a là không rõ ràng".
Justin Ethier

1
đối số chính thức là -p / - pid
Mahmoud Al-Qudsi

3

Nếu muốn đính kèm một tiến trình, tiến trình này phải có cùng một chủ sở hữu. Gốc có thể gắn vào bất kỳ quy trình nào.


2

ps -elf dường như không hiển thị PID. Tôi khuyên bạn nên sử dụng thay thế:

ps -ld | grep foo
gdb -p PID

2

Cách dễ nhất là cung cấp id quy trình .

gdb -p `pidof your_running_program_name`

Vui lòng nhận danh sách đầy đủ các tùy chọn trong man gdblệnh.

Trong trường hợp có nhiều tiến trình cho cùng một chương trình đang chạy, thì lệnh sau sẽ liệt kê các tiến trình.

ps -C program -o pid h
<number>

Sau đó, id quy trình đầu ra (số) có thể được sử dụng làm đối số cho gdb.

gdb -p <process id>
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.