フルパスからの解放

  • 投稿日:
  • by
  • カテゴリ:



6.6以降で、substitute-pathという変数が追加されました。



手元で試そうと思ったら6.5でした(侘)



$ gdb --version
GNU gdb 6.5.50.20060706-cvs (cygwin-special)
Copyright (C) 2006 Free Software Foundation, Inc.

で、これが何を解決するかと言うと、デバッグ情報に含まれるソースファイルのパスの問題を解決します。


困ったことに、gcc -gでオブジェクトに付加されるデバッグ情報のソースファイル名はフルパスです。多くの場合、自分で-g付きでコンパイルしたバイナリをデバッグするので問題は生じません。しかし例えば、デバッグ用と称して他人にバイナリを渡したりすると途端に破綻します。


破綻の例:



(gdb) b main
Breakpoint 1 at 0x401075: file hello.c, line 6.
(gdb) r
Starting program: /home/yasuda/src/hello.exe
Loaded symbols for /cygdrive/c/Windows/system32/ntdll.dll
Loaded symbols for /cygdrive/c/Windows/system32/kernel32.dll
Loaded symbols for /usr/bin/cygwin1.dll
Loaded symbols for /cygdrive/c/Windows/system32/advapi32.dll
Loaded symbols for /cygdrive/c/Windows/system32/rpcrt4.dll

Breakpoint 1, main (argc=1, argv=0xfe1eb8) at hello.c:6
6 hello.c: No such file or directory.
in hello.c
(gdb) list
1 in hello.c
(gdb)


これは、以下のようなディレクトリ構成で意図的に発生させています。



  • /somewhere/beyond/the/sea/hello.c コンパイル時のソース置き場

  • /home/yasuda/other/hello.c デバッグ時のソース置き場

  • /home/yasuda/src/hello.exe バイナリ

  • /home/yasuda/src/ gdb実行


従来これを回避するために多くの人が以下のような対処をしていたと思います。



  • ソースをgdb実行ディレクトリにコピーする

  • directoryコマンドでソースの場所を指定する


HelloWorldくらいならそれで充分でしょうが、複雑なディレクトリ構成のときは破綻します。


gdb実行ディレクトリにソースをコピーすることの意味は、directoryコマンドのデフォルト値



Source directories searched: $cdir:$cwd

のうち、$cwdつまりカレントディレクトリをアテにしているのです。


ということは、ディレクトリツリーの構造ににかかわらずすべてのソースをひとつのディレクトリにコピーする必要が生じます。


めったに無いでしょうが、同じファイル名があったら超困ります。


directoryコマンドにも問題があります。このコマンドで指定するディレクトリは再帰的にサブディレクトリを走査してくれたりはしません。


cvsのようなお節介さは無いとうことです。つまりそれは、巨大なソースツリーのサブディレクトリをすべて登録しなければならないことを意味します。


コマンドファイルに書いておけば良いだけのことでしょうか?おそらくこれまではそれがオススメだったのでしょう。


substituteはDOS/WindowsのSUBSTコマンドと同じように機能します。あるいはmountのように。


先ほどと同じディレクトリ構成であれば、



  • /somewhere/beyond/the/sea/hello.c コンパイル時のソース置き場

  • /home/yasuda/other/hello.c デバッグ時のソース置き場

  • /home/yasuda/src/hello.exe バイナリ

  • /home/yasuda/src/ gdb実行



set substitute-path /somewhere/beyond/the/sea/ /home/yasuda/other/

てな感じで書いておけばよいわけです。サブディレクトリも含めて処理されるため、substitute-pathには、トップディレクトリだけを指定すればよいはずです。


(ここまで書いておいて、自分で試してないのカヨ)



この機能の日本語の解説がどこにもないというのは悲しいですネ。


まぁ、役に立つ場面が非常に限られていると言うのも分かるんですが・・・・


役立つ場面の例:



  • 同僚が-g付きでコンパイルしたバイナリとリンクしてデバッグする

  • ソースは共有


※ソースを共有しているなら、自分でコンパイルすればいいじゃないか、というオチ。



リンク


gdbマニュアル


Specifying Source Directories


http://sourceware.org/gdb/current/onlinedocs/gdb/Source-Path.html#Source-Path


(2010.11.29 デッドリンクになってたので張り直し)





GDBハンドブック

GDBハンドブック