web-dev-qa-db-ja.com

ブラウザをハングさせるJavaScriptをどのようにデバッグできますか?

私は、かなり大規模でリッチなWebページJavaScriptアプリケーションに取り組んでいます。何らかの理由で、最近の変更が原因でブラウザがランダムにハングアップしています。

問題のある場所を絞り込むにはどうすればよいですか?ブラウザが応答しなくなるため、エラーは表示されず、Break on next FireBugを使用します。

54
JeanPaul

コードからコメントアウトする代わりに、debug console logを使用する必要があります。

最新のブラウザのほとんどが提供するconsole.log()機能を使用するか、サポートしていないブラウザを使用する場合はエミュレートする必要があります。

console.log('sometext')を呼び出すたびに、ブラウザのデバッグコンソールのログエントリが指定したテキストで作成され、通常はその後に実際の時間が続きます。

アプリケーションフローのすべての重要な部分の前にログエントリを設定し、その後、呼び出されていないログを特定するまで、ログエントリを設定する必要があります。つまり、そのログの前のコードがブラウザーをハングさせています。

また、特定の変数の状態やプログラムフローのより詳細な側面を含むオブジェクトなど、機能を追加した独自の個人用ログ関数を作成することもできます。

console.log('step 1');

while(1) {}

console.log('step 2');

無限ループはプログラムを停止しますが、プログラムが停止するまでプログラムフローが記録されたコンソールログを表示できます。

したがって、この例では、コンソールログに「ステップ2」は表示されませんが、「ステップ1」が表示されます。これは、プログラムがステップ1とステップ2の間で停止したことを意味します。

その後、2つのステップの間にコードに追加のコンソールログを追加して、問題が見つかるまで深く検索することができます。

41
Jose Faeti

あなたは付け加えられます debugger; JSコードの任意の場所で、ブレークポイントを手動で設定します。実行を一時停止し、コードを再開/検査できるようにします(Firebug/FF)。

Firebug Wikiページ: http://getfirebug.com/wiki/index.php/Debugger;_keyword

16
Ricardo Tomasi

これはまだ適切に回答されていないことに驚いています。最も投票された答えは、基本的に「あなたがそれを理解するまでどこにでもコンソールログを置く」です。常に「コンソールログ」をコピーアンドペーストします。

とにかく、必要なのはdebugger;誰かがすでにこれについて言及していましたが、実際にどのように使用できるかを説明しませんでした

chrome(および他のほとんどのブラウザ)、debugger;は、実行を停止し、開発コンソールに移動し、左側に現在実行中のコードを表示し、右側にスタックトレースを表示します。コンソールの右上には、ボタンのような矢印があります。 1つ目は「スクリプトの実行を再開する」です。必要なのは、次の「次の関数呼び出しのステップオーバー」です。

基本的に、あなたがする必要があるのは、ページがまだフリーズしていないことがわかっているポイントで、コードのどこかにデバッガーを置き、それを実行して、矢印のような「次の関数呼び出しのステップオーバー」を繰り返しクリックすることです円を飛び越えます。スクリプトが実行されるまで、無限ループでハング/スタックするまで、1行ずつ呼び出します。この時点で、コードがスタックしている場所と、現在スコープ内にあるすべての変数/値を正確に確認できます。これは、スクリプトがスタックしている理由を理解するのに役立ちます。

私が取り組んでいるかなり複雑なJSでハングループを見つけようとして頭を悩ませていたところ、この方法を使用して約30秒でそれを見つけることができました。

7

問題を特定するには、エラーを見つけられるようにコードを小さな部分に絞り込むまで、コードのさまざまなセクションを削除/無効化/コメント化することから始めます。別の可能性は、最近コミットされたさまざまな変更について、ソース管理のチェックイン履歴を調べることです。問題がどこから来たのかを理解できれば幸いです。

6
Darin Dimitrov

GoogleをインストールしますChrome、ページに移動し、f12を押すと、開発者コンソールがポップアップ表示されます。次に、Scriptsボタンを選択してから、コンソールの左上のドロップダウンからスクリプトを選択(例:myScript.js)を選択します。次に、最初の行(またはハングしないと思われる行)をクリックすると、break-pointが作成されます。 JavaScriptがブレークポイントに到達したら、コンソールの右上のボタンのいずれかをクリックします(一時停止記号などのボタンが表示され、次に他の4つのボタンが表示されます)。 2ºボタンを押す(または一時停止した後にステップオーバーするボタン)または3ºボタン(ステップイン)。ボタンの上にマウスを置くと、ボタンの意味が説明されます。その後、ハングするまでこのようなコードを入力し、デバッグを改善できます。

Google Chromeデバッガーはfirebugよりもはるかに優れており、高速です。firebugから変更を加えました。これは本当に素晴らしいです!;)

3
Totty.js

今日のブラウザFirefox/Seamonkey(Ctrl-Shift-I /デバッガー/ PAUSE-Icon)、Chrome、...通常、いつでも動作するPAUSEボタンを備えた組み込みのJSデバッガーがあります。ループ/ CPUを集中的に使用するページでそれを押すと、ほとんどの場合、「コールスタック」のようなペインが問題を指摘します。

3
kxr

私はそれが原始的であることを知っていますが、問題が発生する前にコードがどの程度進んでいるかを確認するために、jsコードに「アラート」を振りかけるのが好きです。警告ウィンドウが煩わしい場合は、ログを追加できるテキストエリアをセットアップすることができます。

<textarea id='txtLog' ...></textarea>

<script>

...
function log(str) {
    $('#txtLog').append(str + '\n');
}
log("some message, like 'Executing Step #2'...");
...

</script>
1
Trevor

私の経験では、ブラウザーが応答しなくなる問題は通常、無限ループなどです。

開始点として、後で依存するものをインクリメントしないなどの愚かなことについてループを調査します。

以前のポスターで述べたように、それ以外は、問題を特定するためにコードの一部をコメントアウトします。分割と征服の方法論を使用して「JS」のページの半分をほぼコメントアウトすることができますが、別のエラーが発生した場合は、おそらく正しいビットが見つかりました!.

次に、犯人が見つかるまで、それを半分に分割します。

1
dougajmcdonald

手動のログ出力とdebuggerを使用するほかに、ループが発生する場所を追跡するために、すべての関数呼び出しをログに記録することが役立つ場合があります。 console.logをすべての関数に自動的に追加する からのスニペットに従って、そうするのに便利かもしれません...

function augment(withFn) {
    var name, fn;
    for (name in window) {
        fn = window[name];
        if (typeof fn === 'function') {
            window[name] = (function(name, fn) {
                var args = arguments;
                return function() {
                    withFn.apply(this, args);
                    return fn.apply(this, arguments);

                }
            })(name, fn);
        }
    }
}

augment(function(name, fn) {
    console.log("calling " + name);
});
0
Markus

私は同じ問題にぶつかりました、そしてそれは私がそれを解決した方法です。

  1. コンソールでエラーを確認し、修正します

タイムコンソールがハングしている

  1. ループが無限である場合、すべてのループを確認します
  2. 再帰コードを確認する
  3. ドキュメントに要素を動的に追加しているコードを確認します
  4. コンソールでブレークポイントを使用する
  5. いくつかのコンソールロギングを使用します。つまり、疑わしいコードブロックを記録します。
0
Tofeeq

このようにコンソールログを使用できると思います

console.log(new Date() + " started Function Name or block of lines from # to #");

// functions or few lines of code

console.log(new Date() + " finished Function Name or block of lines from # to #")

Webページの実行が終了するまでに、実行中に非常に時間がかかる領域を特定できます。b

0
Ihab Salem

私はこの質問が古いことを知っていますが、VS2013では、一時停止ボタンを押して完全なJSスタックトレースを取得できます。ループが角の内側にあるので、これは私を夢中にさせました。そのため、それらをどこに置くべきかわからなかったので、アラート、ブレークポイントなどを入れることができませんでした。無料のエクスプレス版で動作するかどうかはわかりませんが、一見の価値があります。

また、Chromeには一時停止機能があるため、これはオプションかもしれませんが、自分で試したことはありません。

0
Lathejockey81