先のエントリで書いたように最近は Windows も触っていて 主に Sysinternals ツールを使って Windows 探検をしている
その流れで ProcDump の使い方を調べていた.
Sysinternals の ProcDump
Windows 版の詳細は上記のリンクを辿って自分でご覧になって欲しい。その中で、CPU 使用率やメモリ使用量(コミットチャージ) をコアダンプ生成のトリガーにできるのが目に留まった
-c CPU しきい値を指定します。このしきい値に達すると、プロセスのダンプが作成されます。 -m メモリ コミットのしきい値を MB 単位で指定します。このしきい値に達すると、プロセスのダンプが作成されます。
gdb もこんな風に扱えたら便利かな〜??? と思っていたところ、ふと Linux 版の存在があるのを思い出したのだった!
Linux 版 🐧
下記のリポジトリで ProcDump の Linux 版が公開されている
ディストリビューション向けのパッケージが配布されており、インストールの手順はREADME.md に書かれている
CLI インタフェースを調べる
手順通りに Ubuntu Xenial にインストールして、man を読み何ができるのかをざっと調べる
man(8) procdump manpage man(8) NAME procdump - generate coredumps based off performance triggers. SYNOPSIS procdump [OPTIONS...] TARGET -C CPU threshold at which to create a coredump of the process from 0 to 100 * nCPU -c CPU threshold below which to create a coredump of the process from 0 to 100 * nCPU -M Memory commit threshold in MB at which to create a coredump -m Trigger when memory commit drops below specified MB value -n Number of dumps to write before exiting -s Consecutive seconds before dump is written (default is 10) TARGET must be exactly one of these: -p pid of the process DESCRIPTION procdump is a Linux reimagining of the class ProcDump tool from the Sysinternals suite of tools for Windows. Procdump provides a convenient way for Linux developers to create core dumps of their application based on performance triggers. 1.0.1 12/18/2017 man(8)
Linux 版でも CPU使用率 やメモリ使用量をトリガーにしてコアダンプできる。コアダンプを採取する回数を指定できたり、採取の間隔を指定できる
アーキテクチャに依存しないエッセンスとなるオプションだけを実装した感じで、Windows 版よりだいぶ簡素かな?
検証(1): メモリの使用量を閾値にしてコアダンプを採取流 🔍
以下のようなテストプロセスを起動して、ProcDump でコアダンプを採取する
さて、上記のプロセスを ProcDump したのを GIF 動画でにした
コアダンプが合計3回採取されているのがわかるだろうか?
ソース 📖
上記のデモで使ったソースは下記の通り
#include <stdio.h> #include <stdlib.h> #include <unistd.h> void malloc_and_free() { size_t size = 100 * 1024 * 1024; char *p = malloc(size); if (p == NULL) { perror("failed to malloc"); exit(1); } // memset でもええねん for (size_t i = 0; i < size; i++) { p[i] = '@'; } sleep(3); free(p); } int main() { sleep(5); malloc_and_free(); malloc_and_free(); malloc_and_free(); }
注意: ProcDump の動作を確認するためのコードなので、コアダンプを採取しても面白いことはなにもない
使ってみよう(2): CPU 使用率を閾値にする 🔍
CPU 使用率を監視してダンプを採取する GIF 動画が ProcDump のリポジトリにのっているので、引用として掲載する
Source: GitHub - microsoft/ProcDump-for-Linux: A Linux version of the ProcDump Sysinternals tool
採取したコアダンプを調査することで CPU 使用率が高い時のバックトレースを調べていくことができるだろう
ユースケース
網を張って気長に待つようなデバッグに向いてるだろう
長時間実行した際に特定の負荷のパターンでうごくプロセスがいるとして、そのようなケースで作業を半自動化できて便利だろう. ( 例: たまーに CPU時間が10数秒スパイクするプロセスがいて調査したいが、再現するタイミングがよくわからない )
『Windows Sysinternals徹底解説 改訂新版』でもそのようなトラブルシューティングの例を出している
まとめ
- ProcDump を使うと CPU使用率やメモリ使用量をトリガーにしてコアダンプをとれる
- プロセスのリソースを見張ってトリガーにする単体のコマンドがあれば、コアダンプの採取以外にも使えて便利な気がする
- コアダンプのサイズは大きくなりがちなので、バックトレースだけ取れたら十分かなという気もする
次回のエントリでは Procump の実装を見ていく