Tôi thường chạy một chương trình như:
./a.out arg1 arg2 <file
Tôi muốn gỡ lỗi bằng gdb.
Tôi biết set argschức năng này, nhưng nó chỉ hoạt động từ dấu nhắc gdb.
Tôi thường chạy một chương trình như:
./a.out arg1 arg2 <file
Tôi muốn gỡ lỗi bằng gdb.
Tôi biết set argschức năng này, nhưng nó chỉ hoạt động từ dấu nhắc gdb.
Câu trả lời:
Truyền các đối số cho runlệnh từ trong gdb.
$ gdb ./a.out
(gdb) r < t
Starting program: /dir/a.out < t
$ gdb ./a.outrồi (gdb) r < t arg1 arg2mà hoạt động tốt đối với tôi. Trong trường hợp của tôi a.out = nft arg1 = import arg2 = json vàt = file containing json rules
Bạn có thể làm được việc này:
gdb --args path/to/executable -every -arg you can=think < of
Một chút ma thuật --args.
Chỉ cần gõ runvào bảng điều khiển lệnh gdb để bắt đầu gỡ lỗi.
--argsthì sẽ không có bất kỳ đối số nào được chuyển cho tệp thực thi, vì vậy nó hầu như không mơ hồ.
argv[0]là tên của người thực thi
gdbchính nó vào oftệp và dẫn đến gdb đang cố thực thi các lệnh từ nó
Nếu bạn muốn có runlệnh trần gdbđể thực thi chương trình của mình với các chuyển hướng và đối số, bạn có thể sử dụng set args:
% gdb ./a.out
(gdb) set args arg1 arg2 <file
(gdb) run
Tôi đã không thể đạt được hành vi tương tự với --argstham số, gdbquyết liệt thoát khỏi các chuyển hướng, tức là
% gdb --args echo 1 2 "<file"
(gdb) show args
Argument list to give program being debugged when it is started is "1 2 \<file".
(gdb) run
...
1 2 <file
...
Điều này thực sự chuyển hướng đầu vào của gdb, không phải những gì chúng ta thực sự muốn ở đây
% gdb --args echo 1 2 <file
zsh: no such file or directory: file
Bắt đầu GDB cho dự án của bạn.
Chuyển đến thư mục dự án, nơi bạn đã biên dịch thực thi dự án. Ban hành lệnh gdb và tên của tệp thực thi như dưới đây:
dự án gdbExecutablename
Điều này khởi động gdb, in ra như sau: GNU gdb (Ubuntu 7.11.1-0ubfox1 ~ 16.04) 7.11.1 Bản quyền (C) 2016 Free Software Foundation, Inc. ............... .................................. Nhập "từ apropos" để tìm kiếm các lệnh liên quan đến "từ" .. Đọc biểu tượng từ dự ánExecutablename ... đã xong. (gdb)
Trước khi bắt đầu chương trình của bạn chạy, bạn muốn thiết lập các điểm dừng của mình. Lệnh break cho phép bạn làm như vậy. Để đặt một điểm dừng ở đầu hàm có tên chính:
(gdb) b chính
Khi bạn đã có dấu nhắc (gdb), lệnh run sẽ bắt đầu chạy thực thi. Nếu chương trình bạn đang gỡ lỗi yêu cầu bất kỳ đối số dòng lệnh nào, bạn chỉ định chúng cho lệnh chạy. Nếu bạn muốn chạy chương trình của tôi trên tệp "xfiles" (nằm trong thư mục "mulder" trong thư mục dự án), bạn sẽ làm như sau:
(gdb) r mulder / xfiles
Hi vọng điêu nay co ich.
Tuyên bố miễn trừ trách nhiệm: Giải pháp này không phải của tôi, nó được điều chỉnh từ https://web.stanford.edu/ class / cs107 / guide_gdb.html Hướng dẫn ngắn này về gdb, rất có thể, được phát triển tại Đại học Stanford.
Sẽ không hay ho gì khi chỉ cần gõ debugtrước bất kỳ lệnh nào để có thể gỡ lỗi với gdbmức độ vỏ?
Bên dưới nó chức năng này. Nó thậm chí hoạt động với sau:
"$program" "$@" < <(in) 1> >(out) 2> >(two) 3> >(three)
Đây là một cuộc gọi trong đó bạn không thể kiểm soát bất cứ điều gì, mọi thứ đều có thể thay đổi, có thể chứa khoảng trắng, nguồn cấp dữ liệu và ký tự đại diện hệ vỏ. Trong ví dụ này, in, out, two, và threelà tùy ý các lệnh khác mà tiêu thụ hoặc dữ liệu sản phẩm mà không bị tổn hại.
bashHàm sau gọi gdbgần như sạch trong một môi trường như vậy [ Gist ]:
debug()
{
1000<&0 1001>&1 1002>&2 \
0</dev/tty 1>/dev/tty 2>&0 \
/usr/bin/gdb -q -nx -nw \
-ex 'set exec-wrapper /bin/bash -c "exec 0<&1000 1>&1001 2>&1002 \"\$@\"" exec' \
-ex r \
--args "$@";
}
Ví dụ về cách áp dụng điều này: Chỉ cần gõ debugở phía trước:
Trước:
p=($'\n' $'I\'am\'evil' " yay ")
"b u g" "${p[@]}" < <(in) 1> >(out) 2> >(two) 3> >(three)
Sau:
p=($'\n' $'I\'am\'evil' " yay ")
debug "b u g" "${p[@]}" < <(in) 1> >(out) 2> >(two) 3> >(three)
Đó là nó. Bây giờ nó là một không có trí tuệ tuyệt đối để gỡ lỗi gdb. Ngoại trừ một vài chi tiết trở lên:
gdbkhông tự động thoát và do đó giữ cho chuyển hướng IO mở cho đến khi bạn thoát gdb. Nhưng tôi gọi đây là một tính năng.
Bạn không thể dễ dàng vượt qua argv0chương trình như với exec -a arg0 command args. Sau đây nên làm thủ thuật này: Sau khi exec-wrapperđổi "execthành "exec -a \"\${DEBUG_ARG0:-\$1}\".
Có các FD trên 1000 mở, thường được đóng. Nếu đây là một vấn đề, thay đổi 0<&1000 1>&1001 2>&1002để đọc0<&1000 1>&1001 2>&1002 1000<&- 1001>&- 1002>&-
Bạn không thể chạy song song hai trình gỡ lỗi. Cũng có thể có vấn đề, nếu một số lệnh khác tiêu thụ /dev/tty(hoặc STDIN). Để khắc phục điều đó, thay thế /dev/ttybằng "${DEBUGTTY:-/dev/tty}". Trong một số loại TTY khác tty; sleep infvà sau đó sử dụng TTY được in (i. E. /dev/pts/60) để gỡ lỗi, như trong DEBUGTTY=/dev/pts/60 debug command arg... Đó là Sức mạnh của Shell, hãy làm quen với nó!
Chức năng giải thích:
1000<&0 1001>&1 1002>&2 di chuyển 3 FD đầu tiên
0</dev/tty 1>/dev/tty 2>&0Khôi phục 3 FD đầu tiên để trỏ đến TTY hiện tại của bạn. Vì vậy, bạn có thể kiểm soát gdb./usr/bin/gdb -q -nx -nwchạy gdbinvoke gdbtrên vỏ-ex 'set exec-wrapper /bin/bash -c "exec 0<&1000 1>&1001 2>&1002 \"\$@\"" tạo một trình bao bọc khởi động, phục hồi 3 FD đầu tiên được lưu thành 1000 trở lên-ex r bắt đầu chương trình bằng cách sử dụng exec-wrapper--args "$@" vượt qua các đối số như được đưa raĐiều đó có dễ không?
rlà viết tắt củarunvà bạn có thể theo dõi nó với bất kỳ đối số. Giống như trong câu hỏi này, nó sẽ là:r arg1 arg2 <filehoặc có thể làrun arg1 arg2 <file