このページは翻訳中です。
翻訳作業に参加する場合は、履歴にある翻訳者と連絡·調整してください。
このドキュメントでは、32 ビットの Microsoft Windows システム上で Mozilla を効果的にデバッグする方法についてよく寄せられる質問への回答を試みます。この文書は、Microsoft Visual C++ 開発環境とデバッガの使い方を知っていることを前提とします。
これらの手順は、もともと VC++ 6.0 向けに書かれました。Visual Studio .NET 2003 としてしられる VC++ 7.0 やそれ以降との差異を追記し始めました。VC++ 7.0 向けの追記はまだ不十分です。VC++ 7.0 のための注意事項が他にあればぜひここに追加してください。
【訳注: 基本的にVisual Studio C++ 6.0/7.0 の日本語版を元に翻訳しています】
要件
Windows Build Prerequisites を参照してください。
デバッグを開始する方法
MSDEV を起動し、メニューより [ファイル (F)] > [ワークスペースを開く (W)] (VC++ 7.0 では [ソリューションを開く(E)] となります) を選択し、 Mozilla 実行ファイルを開いてください。これでプロジェクトが作成されます。F5 を押すことでデバッグを始められます。
VC6/7 をお使いの場合は、コマンドラインより msdev <プログラム名>
と入力します。この際、実行ファイルと同じディレクトリである必要があるでしょう。
VC8/9 をお使いの場合は、コマンドラインより devenv /debugexe <プログラム名> <引数>
と入力します。Visual Studio が開いたら、[デバッグ] メニューから [デバッグを開始] を選択します。
アサーションに当たるまでプログラムを実行します。デバッグしたいかどうかを尋ねるダイアログボックスが表示されます。[キャンセル] を押してください。MSDEV IDE が起動し、アサーションが起こったファイルが読み込まれます。この際、デフォルトで実行可能ファイルのディレクトリに Visual C++ Mozilla プロジェクトも作成されます。
リリースビルドのデバッグ
Firefox 3.0a5 以降、Mozilla は ナイトリービルドとリリースビルド向けにシンボルサーバ をメンテナンスしています。
Mozilla のための Visual C++ プロジェクトを作成する
以下の方法はもう利用できないでしょう:
おそらく、 mozilla ルートディレクトリに Mozilla プロジェクトを作成したいでしょう。その場合、[ファイル (F)] > [ワークスペースを開く (W)] を選び client.mak ファイルを開いてください。 Visual C++ はこれを読めないと文句を言いますので、これを無視してください (以下の訳注を参照)。すると、プロジェクトファイルを作成するために名前を付けるよう尋ねられますので、「mozilla」と答えてください。
もし、あなたが [ファイル (F)] > [ワークスペースを開く (W)] (VC++ 7.0 では [ソリューションを開く (E)]) で実行ファイルを選択して開いた場合、 Visual C++ はデフォルトで実行ファイルのディレクトリにプロジェクトを作成します。
プロジェクトが作成されたら、すべてのワークスペース情報を保存するために、[すべて保存] を行ってください。 Visual C++ のオプションを変更するする時には、いつでもそうしてください。
実際プロジェクトを使い始める前に、いくつかのオプションなどを設定するとよいでしょう。読み進んでください。
訳注: VC++ 6.0 で私がやったときには以下のメッセージを表示するダイアログが出ました。
C:\xxxx\mozilla\client.mak
このメイクファイルは Developer Studio で作成されていません。
続行するとこのメイクファイルを含む新しい Developer Studio プロジェクトを作成します。新しいプロジェクトが作成された後で保存の確認が表示されます。 続行しますか?
これに [はい] と答えると、続いて
外部メイクファイルをサポートしているプラットフォームを選択してください
プラットフォーム(P)
Win32
と出るので、Win32 を選択した状態で OK を押すと、プロジェクトを保存するためにプロジェクト名を入力するファイルダイアログが表示されました。
デバッグのための実行ファイルの選択/変更
VC++ 6.0 でデバッグのための実行ファイルを選択/変更するには、[プロジェクト (P)] > [設定 (S)] で [デバッグ] タブを選択して、【訳注: 】 プルダウンで [一般] を選択します。[デバッグセッションの実行ファイル (E)] は、デバッグしている実行可能ファイルを示しています。もしそれが空か、または不正確ならば、矢印ボタンを使い、[参照] を選択し、実行ファイルを探してください。
コマンドラインパラメータと環境変数
VC++ 6.0 でコマンドラインオプションを設定/変更するには、[プロジェクト (P)] > [設定 (S)] で [デバッグ] タブを選択して、【訳注: 】 プルダウンで [一般] を選択します。[プログラムの引数 (U)] によりオプションが表示されます。
ブラウザに起動後すぐに開かせたいファイルの URL はよく用いられる引数で、プロファイルマネージャを起動することや、プロファイルを選択することも出来ます。ファイルにコンソールアウトプットもリダイレクトできます (例えば「> filename.txt」を引用符なしで追加するなど)。
VC 7/8 では、このオプションは [プロジェクト] > [プロパティ] > [デバッグ] > [コマンド引数] です。VC 8 ではここで環境変数も設定できるようになっています。
メモリにロードされていない DLL にブレークポイントをセットする方法
VC++ 6.0 では、[プロジェクト (P)] > [設定 (S)] で [デバッグ] タブを選択して、【訳注: 】 プルダウンで [追加する DLL] を選択します。 DLL ごとに、新規に登録するために [新規作成] ボタン 【訳注: 文字の含まれないアイコンになっています】 をクリックし、DLL を選択するために [...] ボタンを押してください。一度に 1 つだけ DLL を追加することができます。
VC++ 7.0 は、追加する DLL を自動的に探します。
Unicode 文字列を表示する方法
VC++ 6.0 では、[ツール (T)] > [オプション (O)] 選び、[デバッグ] タブで [Unicode 文字を表示 (U)] というオプションをチェックしてください。
VC++ 7.0 では、特に設定しなくても Unicode 文字列を表示できます。
デバッガの変数ビューをカスタマイズする
Visual C++ が変数ビューのクラスをどう表示するかはカスタマイズ可能です。デフォルトでは Visual C++ は「{...}」と表示するので、必要に応じて小さな + アイコンをクリックして表示を展開し、メンバを参照しなければなりません。 この表示設定は変更可能で、ただの「{...}」の代わりに、どのようなデータメンバもどのような順序、フォーマットでも好みに Visual C++ に表示させることができます。
Visual C++ インストールディレクトリに「AUTOEXP.DAT」と呼ばれるファイルを置く必要があります。デフォルトディレクトリは、以下の通りです。
VC++ 6.0:
C:\Program Files\Microsoft Visual Studio\Common\MSDev98\Bin\AUTOEXP.DAT
VC++ 7.0:
C:\Program Files\Microsoft Visual Studio .NET 2003\Common7\Packages\Debugger\AUTOEXP.DAT
このファイルは先頭に表示フォーマットについての情報を持っています。ちょっとしたことをするだけで、自分流にできます。ここで、デバッグライフをより豊かにする容易にするいくつかの設定を示します。
;; Mozilla (1.7beta 以降) nsAutoString=<mData,su> nsString=<mData,su> nsCString=<mData,s> nsCAutoString=<mData,s> nsRect=x=<x,d> y=<y,d> width=<width,d>; height=<height,d> nsStaticAtomWrapper=<mStaticAtom->mString,s> nsIAtom=<mString,su> ; the following are not necessary in vc8 nsCOMPtr<*>=<mRawPtr,x> nsRefPtr=<mRawPtr,x> nsAutoPtr=<mRawPtr,x>
設定を変更し、ファイルを保存した後、変更を有効にするためには Visual C++ を再起動する必要があります。
XPCOM String (「外部」文字列 API) の場合は、以下のような値を使うことができます。
;; Mozilla (1.9) ; Internal Strings nsAString_internal=<mData,su>, length=<mLength,u> nsACString_internal=<mData,s>, length=<mLength,u> ; XPCOM Strings nsAString=<nsStringContainer.v,su>, length=<nsStringContainer.d1,u> nsACString=<nsCStringContainer.v,s>, length=<nsCStringContainer.d1,u> nsStringContainer=<v,su>, length=<d1,u> nsCStringContainer=<v,s>, length=<d1,u>
このファイルのさらに機能豊富なバージョンは、現在作業中ですが、AutoExpForVC8 にあります。
特定の関数へのステッピングを防ぐ
VC のドキュメント化されていない機能を使って、nsCOMPtr メソッドなど、特定の関数へのステッピングを防ぐことができます。詳しくは をご覧ください。
以下のようにワイルドカードも使えます (VC 8 でテスト済み)。
nsCOMPtr.*\:\:.*=NoStepInto (nsG|g)etter_*AddRefs.*=NoStepInto NS_ConvertUTF.* ; Might be too broad: (ns|Promise)[^\:]*[sS]tring.* ...add common functions to this list
should probably make a .reg file for easy importing
stdout
やその他の FILE
ハンドラを取得する
stdout
やその他の FILE
ハンドラを取得する Visual Studio の コマンドウィンドウ で以下のコマンドを実行させると stdout
の値が返ります。これは (nsGenericElement::List
など) FILE*
パラメータを取る様々なデバッグ方法に利用できます。
Debug.EvaluateStatement {,,msvcr80d}(&__iob_func()[1])
(または、QuickWatch ウィンドウで {,,msvcr80d}(&__iob_func()[1])
を評価することもできます)
同じように、fopen
を使ってディスク上のファイルを開くこともできます。
>Debug.EvaluateStatement {,,msvcr80d}fopen("c:\\123", "w") 0x10311dc0 { ..snip.. } >Debug.EvaluateStatement ((nsGenericElement*)0x03f0e710)->List((FILE*)0x10311dc0, 1) <void> >Debug.EvaluateStatement {,,msvcr80d}fclose((FILE*)0x10311dc0) 0x00000000
なお、ファイルハンドルをクリアするか閉じるまで、デバッグ出力を見ることはできません。
アサーションを無効にする
基本的に、アサーションを無効にするための 2 つの方法があります。1 つは環境変数の設定が必要です。もう一方は、現在メモリにあるプログラムインスタンスの実行中だけ有効になります。
環境変数
アサーションでの停止を使用不可にできる環境変数があります。これを以下のようにセットするとよいでしょう。
set XPCOM_DEBUG_BREAK=warn
この環境変数は warn 以外にも値を取ります。詳細は XPCOM_DEBUG_BREAK
を参照してください。注意: Unix と違い、Windows ではデフォルトは warn に設定されていません。ポップアップのダイアログになっています。
実行コード変更
普通、これの必要はないはずです (ただアプリケーションを終了し、上記のように環境変数を設定し、起動し直せばよいです)。そして危険ですらあります (ハードディスクをクラッシュさせ、システムを破壊することも)。従って、実行コード変更に自信がない限り、行わないでください。あなたは警告を受けています!
メモリ上の割り込んだコード (デバッガ中でブレイクを発生させることで得られる) を、ただ NOP (無演算) とするよう、コードを変更することができます。
アサーションに行き当たるまで、デバッガでプログラムを実行することでこれを行うことができます。あるアセンブラコードを見てください。あるアセンブラコードは実行中に「int 3」を読むとします。この行のメモリアドレスをチェックします。メモリビューをここで表示し 【訳注: ポップアップメニューになっているデバッグメニューのアイコンの中に、メモリビュー表示アイコンがあります】、「int 3」のアドレスをメモリビューにコピーペーストして、その周辺の表示します。そしてそのアドレスの値に「90」を入れ、メモリビューを閉じ、F5 キーで継続します。
混乱しましたか?下のスクリーンショットを見てください
VC++ 7.0?
デバッガをアタッチしないでアサーションを自動的に取り扱う
アサーションが発生していて、デバッガにアタッチしていない時には小さなアプリケーション ([https://www.mozilla.org/build/windbgdlg.html windbgdlg.exe) を起動します。事前に設定しておけば、このアプリケーションにより、プロンプトの代わりに自動的に「Do you want to debug(デバッグしますか)」というダイアログが表示され、動作を選択することができます。詳しくは [https://www.mozilla.org/build/windbgdlg.html windbgdlg.exe をご覧ください。
最適化ビルドのデバッグ
最適化ビルドの効果的なデバッグのためには、最適化されたコードの中に、ブレイクポイントなどのデバッグ用シンボルを効果的に残した形のデバッグ情報を有効にしなくてはなりません。コードは最適化されているため、コードを通して実行することはデバッガがどこかをジャンプしてしまうときなどちょっとばかり驚きを感じさせるような動きを見せることが時に見られるでしょう。
最適化ビルドのデバッグのためには、以下の設定を入れなくてはなりません。
--enable-debugger-info-modules=yes
You can also choose to include or exclude specific modules. This is particularly useful to avoid linking layout with debugging information.
同時に Mozilla の 2 つのインスタンスを実行する
環境変数 MOZ_NO_REMOTE をセットすることで、同時に Mozilla の2つのインスタンスを実行することができます (デバッグモードでも、最適化モードでも)。
set MOZ_NO_REMOTE=1
また、Firefox 2や他のGecko 1.8.1に依存するアプリケーションであるならば、コマンドラインの-no-remote を使うこともできます。(バグ 325509 への対処)
-Pprofile_nameのコマンドライン引数を使ってプロファイルを分けることもできます。
JavaScript のデバッグ
Mozilla 向けの JavaScript デバッガである Venkman を使って下さい。
You can use helper functions from nsXPConnect.cpp to inspect and modify the state of JavaScript code from the MSVS debugger.
For example, to print curent JavaScript stack to stdout, evaluate this in QuickWatch window:
{,,xpc3250}DumpJSStack()
Got a tip?
If you think you know a cool Mozilla debugging trick, feel free to discuss it with #developers and then post it here.
Originally by Heikki Toivonen.