このチュートリアルでは、OpenResty XRay を使用して、クラッシュした OpenResty/Nginx アプリケーションの core dump ファイルを自動的かつ包括的に分析する方法をご紹介いたします。OpenResty XRay は、C と Lua のコールスタックトレース、Lua の GC オブジェクト参照グラフ、Lua コルーチン、並行 HTTP リクエスト、libc のメモリ割り当てを網羅した詳細な分析レポートを生成いたします。動的トレースとフレームグラフの強力な機能を活用し、死亡プロセス(core dump ファイル)を分析することで、本番環境のアプリケーションクラッシュの根本原因を迅速に特定するお手伝いをいたします。

core dump ファイルの確認

ls コマンドを実行し、現在のディレクトリ内のすべてのファイルを一覧表示いたします。

Screenshot

ここで新しい core dump ファイルが見つかりました。新しい core ファイルが必ずしもこのディレクトリに保存されるわけではありませんが、私どものアプリケーションではこのディレクトリに保存するよう事前に設定しております。

Screenshot

readlink コマンドを実行して、そのファイルの絶対パスを確認いたします。

Screenshot

次に、OpenResty XRay を使用して、このコアファイルをリアルタイムで分析し、プロセスクラッシュの原因とコンテキスト情報を特定します。 この core ファイルのパスをコピーします。

Screenshot

core dump ファイルを分析

ブラウザで OpenResty XRay の Web コンソールを開きます。

Screenshot

現在分析中のマシンが正しいことを確認してください。

Screenshot

正しくない場合は、リストから再選択することができます。

Screenshot

「Guided Analysis」ページに移動します。

Screenshot

ここでは、システムが分析可能な様々な種類の問題を確認できます。

Screenshot

「Core dumps or process crashes」を選択します。

Screenshot

「Next」をクリックします。

Screenshot

把我们刚刚复制的 core 文件路径名粘贴到这里。

Screenshot

OpenResty XRay は、この core ファイルから実行可能ファイルのパスを自動的に抽出し、このテキストボックスに表示します。

Screenshot

アプリケーションのタイプが正しいことを確認します。通常、デフォルト値が正しいです。

Screenshot

分析を開始します。システムは分析を実行します。

Screenshot

初回の分析が完了し、レポートを生成しています。

Screenshot

自動生成された分析レポートが表示されます。

Screenshot

レポートの右上に core ファイルのパスと生成時刻が表示しています。

Screenshot

まず、実行コンテキストを確認しましょう。

Screenshot

マシンコードレベルの情報を見てみましょう。

Screenshot

プロセスが SEGV シグナルによって中断されたことが分かります。

Screenshot

以下は、このシグナルの詳細な説明です。SEGV は「セグメンテーション違反」を意味し、プログラムがアクセス権限のないメモリ領域にアクセスしようとしたか、存在しないメモリ領域にアクセスしようとした際に発生いたします。

Screenshot

ここには、現在実行中の命令の周辺の逆アセンブリコードが表示されています。

Screenshot

この行が現在実行中の命令で、行の前にある赤い矢印で識別できます。まさにこの命令を実行中にセグメンテーション違反が発生しました。

Screenshot

このディレクティブはメモリアドレスを読み取っています。

Screenshot

これは core dump 発生時の CPU レジスタの値です。

Screenshot

これは GNU C ライブラリの関数です。

Screenshot

メモリの一部分を別の場所にコピーする機能があります。

Screenshot

この関数は LuaJIT の一部です。FFI の cdata 型に対する __index メタメソッドを処理します。

Screenshot

ngx_http_lua_run_thread は Nginx ウェブサーバーの関数で、Lua ルーチンを実行します。

Screenshot

ngx_http_core_content_phase は HTTP リクエスト処理サイクルのコンテンツフェーズを処理する役割を担っています。

Screenshot

これは Lua のバックトレースが実行されています。

Screenshot

この C 関数はメモリコピーを行っています。C のコールスタックトレースでもこの関数を確認しました。

Screenshot

これら 2 つのメタメソッドは、cdata 内部のフィールドメンバーにアクセスする際に呼び出されます。

Screenshot

decode_order_data はビジネスロジック内の Lua 関数です。

Screenshot

「More」をクリックすると、さらに詳細を確認できます。

Screenshot

上記のコールスタックトレースは、この Lua CPU フレームグラフから自動的に導出されたものです。

Screenshot

以下は完全なコールスタックトレースで、各 Lua 関数フレーム内のすべての引数とローカル変数の値が含まれています。

Screenshot

ここをクリックすると、decode_order_data 関数のすべてのローカル変数と引数変数を確認できます。

Screenshot

ビジネスレベルの関数 decode_order_data に戻りましょう。マウスを関数の緑色のボックスに置いてください。

Screenshot

この関数のソースファイル名が表示されます。ツールチップにはファイルの完全なパスも表示されております。

Screenshot

ソースコードの行番号は 79 です。

Screenshot

このアイコンをクリックすると、この関数の完全なソースファイルパスがコピーされます。

Screenshot

vim エディタを使用してソースファイルを開き、このファイル内の Lua コードを確認します。お好みのエディタをご使用いただいて構いません。

Screenshot

OpenResty XRay が提案したとおり、79 行目に移動します。

Screenshot

order_cdata が NULL ポインタである可能性があるため、その user_id フィールドにアクセスする際にセグメンテーション違反が発生し、クラッシュいたしました。したがって、アクセスする前に order_cdata が NULL ポインタでないかを確認する必要があります。

Screenshot

ここから、このコード行が実際に decode_order_data 関数内にあることが確認できます。これは先ほどのレポートで言及されていた通りです。

Screenshot

これは、まだ生存している LuaJIT コルーチンの中で最も一般的なコールスタックトレースです。

Screenshot

sleep は C 言語の関数で、現在のスレッドの実行を一定時間停止するために使用されます。

Screenshot

ここには、クラッシュ発生時に処理中のすべての HTTP リクエストが表示されています。

Screenshot

これは、クラッシュ発生時に Nginx プロセスが処理していた HTTP リクエストの情報です。

Screenshot

ここには、リクエストを発信したクライアントの IP アドレスが表示されています。

Screenshot

リクエストメソッドは POST です。

Screenshot

これはリクエストの URI です。

Screenshot

他のすべての並行 HTTP リクエストをさらに確認することができます。

Screenshot

レポートにはメモリ分析も含めます。

Screenshot

これは Lua GC オブジェクトメモリ分布の最もホットなデータ参照パスです。

Screenshot

このパスの意味は以下の通りです:registry レジストリに移動し、

Screenshot

_LOADED テーブルを見つけ、

Screenshot

その中で engines.sre.sre_lib モジュールを見つけ、

Screenshot

そのモジュール内で、run_rules 関数またはデータにアクセスします。

Screenshot

このパスは、この Lua GC オブジェクトメモリ分布フレームグラフから自動的に導出されたものです。

Screenshot

完全自動化された分析とレポート

OpenResty XRayは、オンラインアプリケーションによって生成された新しいコアダンプを監視し、これらのファイルを分析してレポートを生成することもできます。「Insights」ページに切り替えます。

Screenshot

「Insights」ページでは、日次および週次のレポートを確認することができます。

Screenshot

したがって、「Guided Analysis」機能を必ずしも使用する必要はありません。もちろん、「Guided Analysis」はアプリケーションの開発やデモンストレーションに非常に有用です。

Screenshot

OpenResty XRay について

OpenResty XRay動的トレーシング製品であり、実行中のアプリケーションを自動的に分析して、パフォーマンスの問題、動作の問題、セキュリティの脆弱性を解決し、実行可能な提案を提供いたします。基盤となる実装において、OpenResty XRay は弊社の Y 言語によって駆動され、Stap+、eBPF+、GDB、ODB など、様々な環境下で複数の異なるランタイムをサポートしております。

著者について

章亦春(Zhang Yichun)は、オープンソースの OpenResty® プロジェクトの創始者であり、OpenResty Inc. の CEO および創業者です。

章亦春(GitHub ID: agentzh)は中国江蘇省生まれで、現在は米国ベイエリアに在住しております。彼は中国における初期のオープンソース技術と文化の提唱者およびリーダーの一人であり、Cloudflare、Yahoo!、Alibaba など、国際的に有名なハイテク企業に勤務した経験があります。「エッジコンピューティング」、「動的トレーシング」、「機械プログラミング」 の先駆者であり、22 年以上のプログラミング経験と 16 年以上のオープンソース経験を持っております。世界中で 4000 万以上のドメイン名を持つユーザーを抱えるオープンソースプロジェクトのリーダーとして、彼は OpenResty® オープンソースプロジェクトをベースに、米国シリコンバレーの中心部にハイテク企業 OpenResty Inc. を設立いたしました。同社の主力製品である OpenResty XRay動的トレーシング技術を利用した非侵襲的な障害分析および排除ツール)と OpenResty XRay(マイクロサービスおよび分散トラフィックに最適化された多機能ゲートウェイソフトウェア)は、世界中の多くの上場企業および大企業から高い評価を得ております。OpenResty 以外にも、章亦春は Linux カーネル、Nginx、LuaJITGDBSystemTapLLVM、Perl など、複数のオープンソースプロジェクトに累計 100 万行以上のコードを寄与し、60 以上のオープンソースソフトウェアライブラリを執筆しております。

翻訳

英語版の原文と日本語訳版(本文)をご用意しております。読者の皆様による他の言語への翻訳版も歓迎いたします。全文翻訳で省略がなければ、採用を検討させていただきます。心より感謝申し上げます!