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 args
chứ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 args
chứ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 run
lệnh từ trong gdb.
$ gdb ./a.out
(gdb) r < t
Starting program: /dir/a.out < t
$ gdb ./a.out
rồi (gdb) r < t arg1 arg2
mà 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õ run
vào bảng điều khiển lệnh gdb để bắt đầu gỡ lỗi.
--args
thì 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
gdb
chính nó vào of
tệp và dẫn đến gdb đang cố thực thi các lệnh từ nó
Nếu bạn muốn có run
lệ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 --args
tham số, gdb
quyế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õ debug
trước bất kỳ lệnh nào để có thể gỡ lỗi với gdb
mứ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à three
là 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.
bash
Hàm sau gọi gdb
gầ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:
gdb
khô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 argv0
chươ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 "exec
thà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/tty
bằng "${DEBUGTTY:-/dev/tty}"
. Trong một số loại TTY khác tty; sleep inf
và 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>&0
Khô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 -nw
chạy gdb
invoke gdb
trê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?
r
là viết tắt củarun
và 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 <file
hoặc có thể làrun arg1 arg2 <file