私は通常、プログラムを次のように実行します:
./a.out arg1 arg2 <file
Gdbを使用してデバッグしたいと思います。
set args
機能は知っていますが、それはgdbプロンプトからのみ機能します。
引数をgdb内からrun
コマンドに渡します。
$ gdb ./a.out
(gdb) r < t
Starting program: /dir/a.out < t
あなたはこれを行うことができます:
gdb --args path/to/executable -every -arg you can=think < of
魔法のビットは--args
です。
Gdbコマンドコンソールでrun
と入力するだけで、デバッグを開始できます。
run
でgdb
コマンドをそのままにして、リダイレクトと引数を使用してプログラムを実行する場合は、set args
を使用できます。
% gdb ./a.out
(gdb) set args arg1 arg2 <file
(gdb) run
--args
パラメーターで同じ動作を実現できませんでした。gdb
はリダイレクトを激しくエスケープします。
% 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
...
これは実際にgdbの入力をリダイレクトしますが、ここで本当に欲しいものではありません
% gdb --args echo 1 2 <file
zsh: no such file or directory: file
プロジェクトでGDBを起動します。
プロジェクトの実行可能ファイルを既にコンパイルしたプロジェクトディレクトリに移動します。次のようにコマンドgdbと実行可能ファイルの名前を発行します。
gdb projectExecutablename
これによりgdbが起動し、次が出力されます。GNU gdb(Ubuntu 7.11.1-0ubuntu1〜16.04)7.11.1 Copyright(C)2016 Free Software Foundation、Inc. ......... ........................................「apropos Word」と入力して、関連するコマンドを検索します「Word」へ... projectExecutablenameからシンボルを読み取り中...完了。 (gdb)
プログラムの実行を開始する前に、ブレークポイントを設定する必要があります。 breakコマンドを使用すると、これを行うことができます。 mainという名前の関数の先頭にブレークポイントを設定するには:
(gdb)bメイン
(gdb)プロンプトが表示されると、runコマンドは実行ファイルの実行を開始します。デバッグしているプログラムにコマンドライン引数が必要な場合は、それらをrunコマンドに指定します。 「xfiles」ファイル(プロジェクトディレクトリの「mulder」フォルダにある)でプログラムを実行する場合は、次のようにします。
(gdb)r mulder/xfiles
お役に立てれば。
免責事項:このソリューションは私のものではなく、 https://web.stanford.edu/class/cs107/guide_gdb.html から採用されています。gdbのこの短いガイドは、おそらくスタンフォード大学で開発されました。
シェルレベルでdebug
name__を使用してデバッグできるようにするには、コマンドの前にgdb
name__と入力するだけでいいのではないでしょうか。
その下にこの関数。以下でも動作します:
"$program" "$@" < <(in) 1> >(out) 2> >(two) 3> >(three)
これは、何も制御できない呼び出しであり、すべてが可変であり、スペース、改行、およびシェルメタキャラクターを含めることができます。この例では、in
name __、out
name __、two
name__、およびthree
name__は、損傷してはならないデータを消費または生成する任意の他のコマンドです。
次のbash
name__関数は、そのような環境[_ Gist ]でほぼきれいにgdb
name__を呼び出します。
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
name__と入力するだけです:
前:
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
name__でデバッグするのは非常に簡単です。いくつかの詳細を除いて:
gdb
name__は自動的に終了しないため、gdb
name__を終了するまでIOリダイレクトを開いたままにします。しかし、これを機能と呼びます。
argv0
のようにexec -a arg0 command args
をプログラムに簡単に渡すことはできません。以下は、このトリックを行う必要があります。exec-wrapper
の後に、"exec
を"exec -a \"\${DEBUG_ARG0:-\$1}\"
に変更します。
1000を超えるFDが開いており、通常は閉じています。これが問題になる場合は、0<&1000 1>&1001 2>&1002
を変更して0<&1000 1>&1001 2>&1002 1000<&- 1001>&- 1002>&-
を読み取ってください
2つのデバッガーを並行して実行することはできません。他のコマンドが/dev/tty
(またはSTDIN)を消費する場合にも問題が発生する可能性があります。これを修正するには、/dev/tty
を"${DEBUGTTY:-/dev/tty}"
に置き換えます。他のTTYでtty; sleep inf
と入力し、/dev/pts/60
のように、デバッグ用に印刷されたTTY(i。E. DEBUGTTY=/dev/pts/60 debug command arg..
)を使用します。それがシェルの力です、それに慣れてください!
機能の説明:
1000<&0 1001>&1 1002>&2
は最初の3つのFDを移動します0</dev/tty 1>/dev/tty 2>&0
は、現在のTTYを指すように最初の3つのFDを復元します。したがって、gdb
name__を制御できます。/usr/bin/gdb -q -nx -nw
がgdb
name__を実行し、シェルでgdb
name__を呼び出します-ex 'set exec-wrapper /bin/bash -c "exec 0<&1000 1>&1001 2>&1002 \"\$@\""
は、1000以上に保存された最初の3つのFDを復元するスタートアップラッパーを作成します-ex r
は、exec-wrapper
を使用してプログラムを開始します--args "$@"
は与えられた引数を渡します簡単じゃなかった?