友人達のために

  • gdb
  • gprof
  • redirect
  • diff

gdb

GNU debugger

$ clang++ -g a.cpp

のように、-goptionを付けてdebug用の情報を埋め込みコンパイルしたバイナリを

   $ gdb a.out

と引数に起動する

種々の情報の後に以下のようなプロンプトが現れ、ここにコマンドを入力していく

(gdb)

run / start

(gdb) run

とすると、バイナリの実行が始まる

(gdb) run < sample.in

とすれば、入力を指定できる

startで起動した場合、main関数でbreakする

list

(gdb) list

現在停止位置周辺のソースコードを表示する

l, li, lis等でも反応する 他のコマンドでも同様である

break

(gdb) break 42
(gdb) break solve

などと行や関数を指定しbreak pointを設定する
実行中、指定した部分に到達したとき実行が一時停止する

print

(gdb) print ary
$1 = {1, 2, 3, 4, 0 <repeats 252 times>}

指定した変数の中身を表示する

watch

指定した変数の中身が変更された時、停止する

(gdb) watch x
Hardware watchpoint 1: x
(gdb) run
Starting program: /path/to/a.out
Hardware watchpoint 1: x

Old value = 0
New value = 1
0x000000000040055c in func (n=3) at a.c:4
4       int func(int n) { return x = n % 2; }

next / step

(gdb) next
(gdb) step

現在位置の次の行を実行し停止する
stepは関数呼び出しの内側へ入り込んでいく

cont

(gdb) cont

実行を再開する 次のbreak pointまで停止しない

up / down

(gdb) up
(gdb) down

stackを上がったり下がったり

backtrace

どのような関数呼び出しを経て現在位置に至ったかを表示する
segvした後に呼ぶと、何処でこけたか判明する

(gdb) backtrace
#0  fact (n=0) at a.c:3
#1  0x000000000040054b in fact (n=1) at a.c:3
#2  0x000000000040054b in fact (n=2) at a.c:3
#3  0x000000000040054b in fact (n=3) at a.c:3
#4  0x000000000040054b in fact (n=4) at a.c:3
#5  0x0000000000400566 in main () at a.c:6

gprof

$ clang++ -pg a.cpp

のように、-pgoptionを付けてprofile用の情報を埋め込みコンパイルする
manを見ると、末尾のg-gとは違うようだ

そうしてできたバイナリを実行するとプロファイル結果が出力されるので、その後gprofを呼び出すとその結果を表示してくれる

$ ./a.out #=> gmon.out
$ gprof a.out

redirect

入力したい文字列をクリップボードでなくファイルに書き出し、

$ cat test.in | ./a.out

とすると、ファイルの中身を自動で入力に渡してくれる

$ ./a.out < test.in > test.out

等とすれば、さらに出力をファイルに書き出すこともできる

diff

$ cat foo
abc
def
xyz
$ cat bar
and
def
xyzzy

のように、ファイルに格納された比較対象を、

$ diff foo bar
1c1
< abc
---

# 競技プログラミング用の基本的な道具の使い方
> and
3c3
< xyz
---

# 競技プログラミング用の基本的な道具の使い方
> xyzzy

diffに渡すと、行ごとの比較をしてくれる

more

$ cat sample.in | ./a.out | diff - sample.out
$ diff <(./a.out < sample.in) sample.out

等とすると便利

$ diff out out

しないように注意