web-dev-qa-db-ja.com

「最大コールスタックサイズを超えました」のデバッグ

次の出力で停止させることができるサーバーがあります。

events.js:38
EventEmitter.prototype.emit = function(type) {
                                  ^
RangeError: Maximum call stack size exceeded

ただし、スタックダンプまたはトレースがないと、問題のある関数がどこにあるかは言うまでもなく、これが無限再帰なのか、チェーンが少し大きすぎるのかを判断する方法がありません。

実行中Node with --traceオプションを使用すると、テストの実行が遅くなるだけでなく(予想どおり)、問題が再現されませんでした。

誰かがこれの底に到達するための解決策やヒントを持っていますか?

24
OrangeDog

現在のところ、答えは次のようです。しっかりと座って、Node.jsが新しいV8バージョンに更新されるのを待つか、 このChromiumプロジェクトのバグレポートのパッチ を使用して独自にビルドします。

v8-devメーリングリストからのこのアーカイブされたスレッド は、

  • Dave Smithがこの問題を提起し、パッチを提案します
  • ChromiumプロジェクトのYangGuoがそれについて話し合い、問題に対してChromiumのバグを報告し、別の修正を適用します
  • Daveは、Node(当時は0.8)がV8 3.11を使用していることを指摘し、パッチのバックポートについて質問します。Yangは、パッチはおそらくV8 3.15に到達し、バックポートされないだろうと答えています。

Node.jsv0.8はV83.11を使用していることに注意してください。 Node.js0.10は現在V83.14を使用しています。したがって、この問題のためにChromiumによって受け入れられたパッチは、Nodeに関する限り、まだ「将来」です。

(この回答は@Coderoshiのおかげです。なぜなら、私がこれをすべて学んだのは、彼の回答のスレッドをたどることによるからです。)

9
metamatt

それが「少し大きすぎるチェーン」である可能性は低いようです。

おそらく、それ自体をトリガーしたイベントを呼び出す関数です。

したがって、コードの速度低下が無限再帰を停止させている場合。私の推測では、あなたはキューを持っていて、遅いモードではそれはそれほど速くいっぱいになりません。

これが役に立たない場合は、もっと情報が必要だと思います。たぶん誰かがこれのキャッチオールを持っています。

4
megakorre

このパッチは、解決策を見つけるのに役立つ場合があります。スタックトレースを大幅に拡張します。

https://github.com/dizzyd/node/commit/40434019540ffc17e984ff0653500a3c5db87deb

2
Coderoshi