我经常运行一个程序:
./a.out arg1 arg2 <file
我想用gdb调试它。
我知道set args
功能,但只能从gdb提示符。
在项目上启动GDB。
这将启动gdb,打印以下内容:GNU gdb(Ubuntu 7.11.1-0ubuntu1~16.04)7.11.1版权所有(C)2016 Free Software Foundation,Inc。............... ..................................键入“apropos word”以搜索与“word”相关的命令。从projectExecutablename中读取符号...完成。 (GDB)
希望这可以帮助。
免责声明:这个解决方案不是我的,它改编自https://web.stanford.edu/class/cs107/guide_gdb.html这个简短的gdb指南很可能是在斯坦福大学开发的。
在任何命令前键入debug
以便能够在shell级别使用gdb
进行调试,这不是很好吗?
下面是这个功能。它甚至可以使用以下内容:
"$program" "$@" < <(in) 1> >(out) 2> >(two) 3> >(three)
这是一个调用,你无法控制任何东西,一切都是变量,可以包含空格,换行符和shell元字符。在这个例子中,in
,out
,two
和three
是消耗或产生不得损害的数据的任意其他命令。
以下bash
函数在这样的环境中几乎干净地调用gdb
[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 "$@";
}
如何应用此示例:只需在前面键入debug
:
之前:
p=($'\n' $'I\'am\'evil' " yay ")
"b u g" "${p[@]}" < <(in) 1> >(out) 2> >(two) 3> >(three)
后:
p=($'\n' $'I\'am\'evil' " yay ")
debug "b u g" "${p[@]}" < <(in) 1> >(out) 2> >(two) 3> >(three)
而已。现在用gdb
进行调试是绝对明智的。除了一些细节或更多:
gdb
不会自动退出,因此保持IO重定向打开,直到您退出gdb
。但我称这是一个功能。argv0
那样轻松地将exec -a arg0 command args
传递给程序。以下应该这样做:在exec-wrapper
将"exec
改为"exec -a \"\${DEBUG_ARG0:-\$1}\"
之后。0<&1000 1>&1001 2>&1002
更改为读取0<&1000 1>&1001 2>&1002 1000<&- 1001>&- 1002>&-
/dev/tty
(或STDIN),也可能存在问题。要解决这个问题,请将/dev/tty
替换为"${DEBUGTTY:-/dev/tty}"
。在其他一些TTY类型tty; sleep inf
然后使用打印的TTY(即E. /dev/pts/60
)进行调试,如DEBUGTTY=/dev/pts/60 debug command arg..
。那就是Shell的力量,习惯它!功能说明:
1000<&0 1001>&1 1002>&2
移走前3个FD
这假设FDs 1000,1001和1002是免费的0</dev/tty 1>/dev/tty 2>&0
恢复前3个FD指向您当前的TTY。所以你可以控制gdb
。/usr/bin/gdb -q -nx -nw
运行gdb
在shell上调用gdb
-ex 'set exec-wrapper /bin/bash -c "exec 0<&1000 1>&1001 2>&1002 \"\$@\""
创建了一个启动包装器,它可以恢复保存到1000及以上的前3个FD-ex r
使用exec-wrapper
启动程序--args "$@"
传递了给定的论点那不容易吗?