■ とりあえずビルドして実行ファイルをつくる
簡単なコードを用意
#include< stdio.h>
int main() {
printf( "test\n" );
return 0;
}
main.cpp をコンパイルしてリンクする
出力実行ファイル名を指定する。
cl /out:test.exe main.cpp
POINT
すべてのコンパイルオプションをファイル出力しておくと便利。
cl /help > d:/cl_doc.txt
■ Compile
ファイル単位でコンパイルして、リンクをする
// /c でコンパイルのみの指定
cl /c main.cpp
// /out:FILE で出力実行ファイル名の指定をする
link /out:test.exe main.obj
■ Debug.のためのビルド設定
次の設定が必要になる。
// デバック用のオプションを指定してコンパイル
cl /MDd /Zi /Od main.cpp
// そしてリンク
link /DEBUG main.obj
WARNING
pdb ファイル名( Path )を勝手に変更しないこと
exe に pdb のパスが書かれているデバッガがシンボル情報を見つけられなくなる
"main.exe のデバッグ情報が見つからないか一致しません"
// 名前をかえてみる
mv main.pdb foo.pdb
POINT
正しくシンボルテーブルが読まれているかは [ 出力 ]ウィンドウで確認できる。
'test.exe': 'D:\test\release\test.exe' を読み込みました。シンボルが読み込まれました。
// ここは /MD にしているから
// /MTd にしても Windows System DLL の Symbol は Load されない
'test.exe': 'C:\WINDOWS\system32\ntdll.dll' を読み込みました。シンボルが読み込まれていません。
'test.exe': 'C:\WINDOWS\system32\kernel32.dll' を読み込みました。シンボルが読み込まれていません。
'test.exe': 'C:\WINDOWS\system32\msvcrt.dll' を読み込みました。シンボルが読み込まれていません。
プラグインを開発する時は, 実行ファイル本体のシンボルテーブルは存在しない。
その場合はデバッグ開始時に次のような表記がでる。
app.exe のデバッグ情報がみつからないか, または一致しません。
さらにデバッガは exe が参照する DLL を順番にロードする。
ここでデバッグ対象の DLL のシンボルが読み込まれているか確認する。
app.exe': 'd:/dll/test.dll' を読み込みました。シンボルが読み込まれました。
■ /Zi /ZI /Z7
DESC
生成する Debug.情報 の種類を指定する
POINT
Debug.情報とは
変数や関数の名前, 型, 行番号のリストのこと
サードパーティのライブラリを配布する場合は
.pdb ファイルを持たない利点あり
ただし
プリコンパイル済みヘッダーの .obj ファイルは
リンク フェーズおよびデバッグで必要です
.pch オブジェクト ファイルに型情報だけがある (コードはない) 場合は
/Yl (デバッグ ライブラリの PCH 参照の挿入) も指定してコンパイルする必要あり
POINT
次の指定だけでも Debug.情報を生成できる
POINT
VisualStudio 上の設定は次のようにする
Compile Option
全般 > Debug.情報の形式
> 無効 // BP に Hit しない
> ProgramDatabase(/Zi) // BP に Hit
> エディット コンティニュ用プログラム データベース
Linker
Debug > Debug.情報を生成
> いいえ // pdb ファイルが生成されない && BP に Hit しない
> はい ( /DEBUG ) // pdb ファイルが生成 && BP に Hit
■ SymbolTableを作成する
// Debug をするには SymbolTableを作成する
// そのための option として /Zi を指定
cl /c /Zi main.cpp
// vc90.pdb ( Program Data Base File が作成される )
// obj ファイルに組み込むには /Z7 を指定する
// main.obj のサイズが大きくなることがわかる
cl /c /Z7 main.cpp
WARNING
Debugger が外部の SymbolTable を見つけるためには同一箇所に置く必要がある
■ DLL.を作成する
int add( int a, int b ) {
return a + b;
}
// コンパイル
cl /c dll.cpp
// リンカーに DLL を作成するように指示する
link /DLL /EXPORT:add dll.obj
■ DLL.の.Debug
POINT
DLL の Debug を開始できる Project は 次の 2 つ
DLL をコールする実行可能ファイルプロジェクト
DLL を作成するプロジェクト
POINT
DLL を作成したプロジェクトからデバッグを開始するには
DLL のデバッグに使用する実行可能ファイルを指定する
構成 > Debug > Command
d:/myapp/myapp.exe
■ Debug.に役立つ関数
■ DebugBreak(__debugbreak)
SYNTAX
void DebugBreak();
DESC
現在のプロセスでブレークポイント例外を発生させる
デバッガに信号を送り何らかの処理を強制的に実行できる
プロセスがデバッグ中でないときは
標準例外ハンドラの検索ロジックが使われます
ほとんどの場合
未処理のブレークポイント命令のために呼び出し側プロセスは終了する
■ __debugbreak
SYNTAX
__debugbreak();
DESC
コンパイラの組み込み関数
DebugBreak __debugbreak を呼び出した場合の動作は
その位置にブレークポイントを設定することと同じ。
■ debug.有無の開始
DESC
c-f5 : debug なし 開始
f5 : debug あり
-> 違い
break point の判定
POINT
c-f5 で実行した場合, terminal に実行結果が停止して表示される
WARNING
assert がスキップされるわけではない( assert は _DEBUG にたしいて有効 )
■ debug.開始directoryの設定
DESC
SE > RMB > 構成プロパティ > debug > 作業 dir
POINT
SE > RMB > スタートアップ プロジェクトに設定
--------------- // ( 以下従来の方法 )
-> SE > Debug > 新しいインスタンスを開始 ( これで修正可能な場合もある )
path の問題かどうかは, shell から直接実行することで確認できる.
■ 条件付きbreakpoint
DESC
条件:
条件式が真の場合に停止 ->
2. 値が変更:
i :
*p : p の指す値
3. hitcount :
for loop の際に使用
i >= 2
i*i >= 10
strcmp( data[i], "aaa" ) == 0 ERR
pow( i, 2 ) >= 10 ERR
■ 混合モード
DESC
ソースコードとコンパイラによって生成されたアセンブリコードを
交互に混ぜて表示するモード。
POINT
クラッシュしたアドレスがわかっている場合にデバッグで役にたつ。
Debug > Window > 逆アセンブル ( Alt - 8 )
現在のコードに移動する。
ステップ実行( F10 )をした場合は, アセンブラコードの単位で一行ずつ実行される。
// ソースコードと
7: main()
// アセンブリコードが交互に表示される
0040B7B0 push ebp
POINT
アプリケーションがクラッシュした場合に表示されるダイアログを見れば, どこで落ちたかわかる。
障害モジュールの名前: test.exe
■ スタティックライブラリをつくる(StaticLibrary)
DESC
スタティックライブラリとは、コンパイル済みのオブジェクト( *.obj )をアーカイブしたもの。
LINK はしないので, Linker の設定は不要
よく利用するモジュールは StaticLibrary として用意しておくと
実行ファイルをつくるときに、コンパイルせずにリンクだけで完了するので便利。
math のモジュールをつくる場合
math
vector.cpp
matrix.cpp
$(VC)/VC/bin/lib/Lib.exe を利用してアーカイブする。
// コンパイルして
cl /c vector.cpp matrix.cpp
// アーカイブする
lib vector.obj matrix.obj
作成した StaticLibrary を利用する場合はコンパイル済みなので link するだけで完了する。
link main.obj math.lib kernel32.lib
WARNING
Library 内の関数のみが lib に含まれる
PlatformSDK などを利用するなら, exe 側で LINK すること
POINT
C/C++ > コード生成 > ランタイムライブラリ の修正を忘れないこと ( 大量のエラーがでる )
POINT
Application 側で Debug するには pdb というファイルが必要
これを lib と同じ場所においてやる必要がある
POINT
Application 側は次のような設定をする
C/C++ > コード生成 > ランタイムライブラリ
DLL なし 版にきりかえる
WARNING
DLL, exe を作成するときは利用してはダメ
POINT
LibraryManager のこと