謝辞
| (7) |
はじめに
| (19) |
第 1 部 デバッギングにおけるゲシュタルト
|
| 3 |
1.1 バグとデバッギング
| 3 |
1.1.1 バグの定義
| 4 |
1.1.2 プロセスバグとソリューション
| 8 |
1.1.3 計画的なデバッグ
| 18 |
1.2 デバッグ作業と前提知識
| 19 |
1.2.1 スキルセット
| 19 |
1.2.2 スキルセットの習得
| 22 |
1.3 デバッギングプロセス
| 23 |
1.3.1 ステップ1:バグを再現する
| 25 |
1.3.2 ステップ2:バグ内容を書き留める
| 26 |
1.3.3 ステップ3:バグの原因は自分にあるとする
| 27 |
1.3.4 ステップ4:細分化し、征服する
| 27 |
1.3.5 ステップ5:創造的に考える
| 28 |
1.3.6 ステップ6:ツールを活用する
| 29 |
1.3.7 ステップ7:詳細デバッグを開始する
| 29 |
1.3.8 ステップ8:バグの除去具合を検証する
| 30 |
1.3.9 ステップ9:デバッグ内容を記録する
| 32 |
1.3.10 デバッギング秘儀
| 32 |
まとめ
| 33 |
第 2 章 デバッグ入門
| 35 |
2.1 変更内容の追跡
| 36 |
2.1.1 バージョンコントロールシステム
| 37 |
2.1.2 バグ追跡システム
| 41 |
2.1.3 最適なシステムの選択
| 42 |
2.2 デバッグシステムの構築スケジュール
| 43 |
2.2.1 ビルドとデバッグシンボル
| 44 |
2.2.2 警告とエラー(マネージドコード編)
| 49 |
2.2.3 ほぼ常に警告をエラーとして扱う(ネイティブコード編)
| 51 |
2.2.4 DLLのロード位置(ネイティブコード)
| 54 |
2.2.5 マネージドモジュールとベースアドレス
| 60 |
2.2.6 リリースビルドと軽量な診断システム
| 69 |
2.3 ビルド作業とスモークテスト
| 70 |
2.3.1 ビルド処理の繰り返し
| 70 |
2.3.2 スモークテスト
| 72 |
2.4 インストールプログラムのビルド
| 73 |
2.5 QAとデバッグビルド
| 74 |
2.6 デバッグシンボルのインストールとシンボルストアのセットアップ
| 75 |
2.6.1 ソースコードとシンボルサーバー
| 85 |
まとめ
| 86 |
第 3 章 コーディングとデバッグ
| 87 |
3.1 アサートの重要性
| 89 |
3.1.1 アサート条件の定義
| 90 |
3.1.2 NET Windowsフォームアプリケーションとコントロールアプリケーションのアサート
| 100 |
3.1.3 ASP.NETアプリケーションとXML Webサービスのアサート
| 110 |
3.1.4 ネイティブC++アプリケーションとアサート
| 121 |
.1.5 いろいろなVisual C++アサート
| 126 |
3.1.6 SUPERASSERT
| 129 |
3.2 TRACEの重要性
| 152 |
3.2.1 Windowsフォームとコンソール.NETアプリケーションのトレース
| 153 |
3.2.2 ASP.NETアプリケーションとXML Webサービスのトレース
| 155 |
3.2.3 ネイティブC++アプリケーションのトレース
| 158 |
3.3 COMMENTの重要性
| 158 |
3.4 信頼と検証(単体テスト)
| 160 |
まとめ
| 163 |
第 2 部 パワーデバッギング
|
| 167 |
4.1 いろいろなWindowsデバッガ
| 168 |
4.1.1 ユーザーモードデバッガ
| 169 |
4.1.2 カーネルモードデバッガ
| 171 |
4.2 Windowsオペレーティングシステムと被デバッグプロセスサポート
| 174 |
4.2.1 ジャストインタイム(JIT)デバッギング
| 174 |
4.2.2 デバッギングの自動化
| 179 |
4.3 単純なWin32デバッガMinDBG
| 182 |
4.4 実用レベルのデバッガWDBG
| 201 |
4.4.1 メモリへの読み出し/書き込み処理
| 203 |
4.4.2 ブレークポイントとシングルステップ動作
| 206 |
4.4.3 シンボルテーブル、シンボルエンジン、そしてスタック検索
| 212 |
4.4.4 ステップイン、ステップオーバー、ステップアウト
| 221 |
4.5 デバッガを自作する方法
| 222 |
4.6 WDBG改良指針
| 223 |
まとめ
| 224 |
第 5 章 Visual Studio .NETの高度な使い方
| 227 |
5.1 高度なブレークポイントとその使い方
| 228 |
5.1.1 ブレークポイント活用上のヒント
| 229 |
5.1.2 関数とクイックブレーク
| 231 |
5.1.3 ロケーションブレークポイント修飾子
| 235 |
5.1.4 同一行への複数ブレークポイント設定
| 238 |
5.2 [ウォッチ]ウィンドウ
| 239 |
5.2.1 [ウォッチ]ウィンドウでのメソッド呼び出し
| 240 |
5.2.2 [次のステートメントの設定]コマンド
| 243 |
まとめ
| 244 |
第 6 章 高度な.NETデバッグ
| 247 |
6.1 .NETプログラムと高度なブレークポイント
| 247 |
6.1.1 条件式
| 248 |
6.2 [ウォッチ]ウィンドウ
| 253 |
6.2.1 独自定義型の自動展開
| 253 |
6.3 覚えてほしい裏技
| 257 |
6.3.1 DebuggerStepThroughAttributeとDebuggerHiddenAttribute
| 257 |
6.3.2 混合モードを使ったデバッギング
| 258 |
6.3.3 リモートデバッギング
| 260 |
6.4 ILDASMとMicrosoft中間言語
| 262 |
6.4.1 ILDASMの基礎
| 264 |
6.4.2 CLR入門
| 269 |
6.4.3 MSIL、ローカル変数、そしてパラメータ
| 270 |
6.4.4 鍵となる命令
| 272 |
6.4.5 その他のリバースエンジニアリングツール
| 279 |
まとめ
| 280 |
第 7 章 Visual Studio .NETを使った高度なネイティブコードデバッギング
| 281 |
7.1 高度なブレークポイント設定機能
| 281 |
7.1.1 高度なブレークポイント設定構文
| 282 |
7.1.2 システムやエクスポート関数へのブレークポイントの設定方法
| 283 |
7.1.3 条件式
| 286 |
7.1.4 データブレークポイント
| 289 |
7.2 [ウォッチ]ウィンドウ
| 292 |
7.2.1 データフォーマットと式評価
| 292 |
7.2.2 [ウォッチ]ウィンドウとタイミング制御
| 295 |
7.2.3 非公開の疑似レジスタ
| 295 |
7.2.4 自作データ型の自動展開機能
| 295 |
7.3 リモートデバッギング
| 304 |
7.4 ネイティブデバッグ機能を有効活用するためのヒント
| 307 |
7.4.1 注入コードのデバッグヒント
| 307 |
7.4.2 [メモリ]ウィンドウと自動メモリ評価機能
| 308 |
7.4.3 例外の監視
| 308 |
7.4.4 シンボル操作上のヒント
| 311 |
7.4.5 Windows 2000プロセスからのデタッチ
| 312 |
7.4.6 ダンプファイルの操作
| 312 |
7.5 x86アセンブリ言語
| 315 |
7.5.1 CPUの基礎
| 316 |
7.5.2 Visual C++ .NETインラインアセンブラの基礎
| 323 |
7.5.3 理解しておくべきアセンブリ言語命令
| 324 |
7.5.4 パターンを持つシーケンス:関数の入口と出口
| 328 |
7.5.5 プロシージャ呼び出しと復帰
| 330 |
7.5.6 呼び出し規約
| 331 |
7.5.7 変数へのアクセス:グローバル変数、パラメータ、およびローカル変数
| 337 |
7.5.8 その他の知っておくべき命令
| 342 |
7.5.9 文字列操作命令
| 349 |
7.5.10 よく使用されるアセンブリ言語構造
| 352 |
7.5.11 構造体とクラス参照
| 354 |
7.5.12 完全なサンプルプログラム
| 356 |
7.5.13 [混合モード]ウィンドウ
| 358 |
7.5.14 スタックの手動検索
| 363 |
7.5.15 高度なヒント
| 367 |
まとめ
| 369 |
第 8 章 WinDBGと高度なネイティブコードデバッグ技術
| 371 |
8.1 WinDBGのインストール
| 372 |
8.2 WinDBG入門
| 375 |
8.3 WinDBGを使ったデバッグ作業
| 380 |
8.3.1 コマンド情報の取得
| 381 |
8.3.2 正確なシンボルのロード
| 381 |
8.3.3 プロセスとスレッド
| 386 |
8.4 [Command]ウィンドウを使った一般的なデバッギング
| 393 |
8.4.1 変数の表示と評価
| 393 |
8.4.2 実行、ステップ実行、トレーシング
| 394 |
8.4.3 ブレークポイント
| 400 |
8.4.4 式とイベント
| 404 |
8.4.5 WinDBGの制御
| 406 |
8.5 強力な拡張機能
| 408 |
8.5.1 拡張機能のロードと制御
| 409 |
8.5.2 重要な拡張コマンド
| 410 |
8.6 ダンプファイルの活用方法
| 415 |
8.6.1 ダンプファイルの作成
| 415 |
8.6.2 ダンプファイルのオープン
| 417 |
8.6.3 ダンプファイルのデバッグ
| 418 |
8.7 SOS(Son of Strike)
| 419 |
8.7.1 SOSの活用
| 420 |
まとめ
| 427 |
|
第 9 章 Visual Studio .NETの拡張
| 431 |
9.1 マクロを使った拡張
| 433 |
9.1.1 マクロパラメータ
| 435 |
9.1.2 プロジェクトの問題
| 436 |
9.1.3 コードの構成要素
| 437 |
9.2 自動ドキュメントツールCommenTater
| 440 |
9.3 アドイン入門
| 449 |
9.3.1 アドインウィザード生成コードの修正
| 450 |
9.3.2 ツールバーボタン問題の解決
| 454 |
9.3.3 ツールウィンドウの作成
| 455 |
9.3.4 マネージドコードと[オプション]ダイアログボックスのプロパティページの作成
| 458 |
9.4 SuperSaverアドイン
| 463 |
9.5 SettingsMasterアドイン
| 470 |
9.5.1 SettingsMaster実装ハイライト
| 477 |
9.5.2 SettingsMasterの改善点
| 478 |
まとめ
| 479 |
第 10 章 マネージド例外の監視
| 481 |
10.1 プロファイリングAPI入門
| 482 |
10.1.1 自作プロファイラの起動
| 489 |
10.2 ProfilerLibの紹介
| 491 |
10.3 ExceptionMonの紹介
| 493 |
10.3.1 インプロセスデバッギングとExceptionMon
| 495 |
10.4 .NETと例外の関係
| 501 |
まとめ
| 504 |
第 11 章 フロートレーシング
| 505 |
11.1 プロファイリングAPIと関数フック
| 506 |
11.1.1 EnterとLeave通知の要求
| 506 |
11.1.2 フック関数の実装
| 507 |
11.1.3 インライン処理
| 508 |
11.1.4 関数IDマッパー
| 509 |
11.2 FlowTraceの使用法
| 510 |
11.3 FlowTrace実装上の特徴
| 512 |
11.4 FlowTrace拡張上のヒント
| 514 |
まとめ
| 515 |
|
第 12 章 クラッシュアドレスとソース情報
| 519 |
12.1 MAPファイルの作成と解読
| 520 |
12.1.1 MAPファイルの内容
| 522 |
12.1.2 関数、ソースファイル、行番号の見つけ方
| 525 |
12.1.3 PDBからMAPへの変換
| 527 |
12.2 CrashFinderの使用法
| 529 |
12.2.1 CrashFinder実装コードの特徴
| 533 |
12.3 CrashFinderを改善するためのヒント
| 539 |
まとめ
| 539 |
第 13 章 クラッシュハンドラ
| 541 |
13.1 構造化例外処理とC++例外処理
| 542 |
13.1.1 構造化例外処理(SEH)
| 542 |
13.1.2 C++例外処理
| 546 |
13.1.3 C++例外処理の使用は避けよ!
| 547 |
13.2 SetUnhandledExceptionFilter API関数
| 554 |
13.3 CrashHandler APIの呼び出し
| 556 |
13.4 EXCEPTION_POINTERS構造体の変換作業
| 581 |
13.5 ミニダンプ
| 584 |
13.5.1 MiniDumpWriteDump API
| 584 |
13.5.2 MiniDumpWriteDumpのラッピング
| 586 |
まとめ
| 594 |
第 14 章 Windowsサービスと関連DLLのデバッグ作業
| 597 |
14.1 サービスの基礎
| 598 |
14.1.1 サービス固有のAPI
| 599 |
14.1.2 サービスとセキュリティ
| 600 |
14.2 サービスのデバッグ
| 601 |
14.2.1 コアコードのデバッグ
| 601 |
14.2.2 基本サービスのデバッグ
| 602 |
まとめ
| 611 |
第 15 章 マルチスレッドデッドロック
| 613 |
15.1 マルチスレッドプログラミングのための秘儀
| 614 |
15.1.1 マルチスレッド化を回避する
| 614 |
15.1.2 スレッドの過度の使用を避ける
| 615 |
15.1.3 個別の小さなコードをマルチスレッド化する
| 615 |
15.1.4 最も低レベルで同期を取る
| 616 |
15.1.5 クリティカルセクションを活用する
| 620 |
15.1.6 CreateThreadの使用を避ける
| 621 |
15.1.7 デフォルトのメモリマネージャに注意する
| 622 |
15.1.8 フィールドダンプを活用する
| 624 |
15.1.9 コードを繰り返しレビューする
| 625 |
15.1.10 マルチプロセッサマシン環境でテストする
| 625 |
15.2 DeadlockDetection仕様要求
| 629 |
15.3 DeadlockDetectionと設計上の高度な問題
| 630 |
15.4 DeadlockDetectionの使用法
| 632 |
15.5 DeadlockDetectionの実装
| 635 |
15.5.1 インポート関数のフッキング
| 635 |
15.5.2 実装上の特徴
| 644 |
15.6 DeadlockDetectionの機能アップ用のヒント
| 659 |
まとめ
| 660 |
第 16 章 テストの自動化
| 663 |
16.1 単体テストとユーザーインターフェイス
| 664 |
16.2 Testerの要求仕様
| 665 |
16.3 Testerの使用法
| 666 |
16.3.1 Testerスクリプト
| 666 |
16.3.2 記録スクリプト
| 672 |
16.4 Testerの実装
| 675 |
16.4.1 TESTER.DLL通知と再現の実装
| 675 |
16.4.2 TESTREC.EXEの実装
| 691 |
16.5 Tester拡張用のヒント
| 703 |
まとめ
| 704 |
第 17 章 デバッグ版Cランタイムライブラリ
| 705 |
17.1 デバッグCランタイムライブラリの機能
| 706 |
17.2 デバッグCランタイムライブラリの応用
| 708 |
17.2.1 DCRTが抱えるバグ
| 709 |
17.2.2 便利なDCRT関数
| 713 |
17.3 正しいCランタイムライブラリの選択
| 715 |
17.4 MemDumperValidatorの使用法
| 717 |
17.4.1 C++とMemDumperValidator
| 724 |
17.4.2 CとMemDumperValidator
| 725 |
17.4.3 より高精度なメモリ検証
| 726 |
17.5 MemDumperValidatorの実装
| 730 |
17.5.1 C++と初期化/終了処理
| 732 |
17.5.2 リークレポートの表示
| 733 |
17.6 MemStressの使用法
| 734 |
17.6.1 おもしろいストレス問題
| 736 |
17.7 OSヒープ
| 737 |
17.8 メモリ問題を分析するコツ
| 740 |
17.8.1 未初期化メモリへの書き込み検出テクニック
| 740 |
17.8.2 メモリオーバーランの検出
| 742 |
17.9 キラースイッチ
| 748 |
17.9.1 ランタイムチェックスイッチ
| 748 |
17.9.2 バッファセキュリティチェックスイッチ
| 755 |
まとめ
| 756 |
第 18 章 サーバーアプリケーショントレースツールの開発
| 759 |
18.1 基本的な問題とその解決策
| 760 |
18.2 FastTraceの使用法
| 761 |
18.2.1 トレースログのマージ
| 763 |
18.3 FastTraceの実装
| 764 |
まとめ
| 765 |
第 19 章 ワーキングセットの軽量化
| 767 |
19.1 ワーキングセットチューニング
| 768 |
19.2 SWSの使用法
| 772 |
19.2.1 SWSコンパイルの準備
| 772 |
19.2.2 SWSとアプリケーションの実行
| 775 |
19.2.3 オーダーファイルの作成とその使用法
| 776 |
19.3 SWSの実装
| 778 |
19.3.1 _penter関数
| 778 |
19.3.2 .SWSファイルフォーマットとシンボル列挙
| 783 |
19.3.3 ランタイムとチューニング
| 788 |
19.4 SWS拡張のためのヒント
| 791 |
まとめ
| 791 |
付録
| 793 |
監訳を終えて
| 805 |
索引
| 807 |