Làm cách nào để truyền đối số và chuyển hướng stdin từ tệp sang chương trình chạy trong gdb?


210

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:


136

Truyền các đối số cho runlệnh từ trong gdb.

$ gdb ./a.out
(gdb) r < t
Starting program: /dir/a.out < t

3
rlà viết tắt của runvà 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
phyatt

Đối với tôi nó không hoạt động. Sau đó, tôi đã cố gắng $ 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 = jsont = file containing json rules
mystictot

410

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.


24
Tôi nghĩ rằng tôi đã đọc sai lúc đầu; lẻ mà --args đi trước khi thực thi. Nhưng nó là như vậy!
Lửa cao lanh

8
@Kaolin --args phải đến trước khi thực thi vì nó là một công tắc cho gdb. Nếu nó xuất hiện sau, gdb sẽ phân biệt nó như thế nào với một đối số mà bạn muốn chuyển vào thực thi mà bạn đang gỡ lỗi?
codehippo

9
@codehippo: Chà, nếu bạn không chỉ định --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ồ.
Các cuộc đua nhẹ nhàng trong quỹ đạo

14
Tôi đoán nó bởi vì thông thường argv[0]là tên của người thực thi
Claudiu

3
điều này sẽ chuyển hướng đầu vào của gdbchính nó vào oftệp và dẫn đến gdb đang cố thực thi các lệnh từ nó
unkulunkulu

4

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

1

Bắt đầu GDB cho dự án của bạn.

  1. 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)

  1. 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

  2. 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.


0

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
    • Giả định này, rằng FD 1000, 1001 và 1002 là miễn phí
  • 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?

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.