次の方法で共有


目 次

謝辞 (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