この記事は最新のLinuxについてです。 たとえば、2.6.3xカーネルを搭載したRHEL6は機能しますが、2.6.18カーネルを搭載したRHEL5(ちなみに、本番環境で最も普及している)-ああ、いいえ。 そしてまだ-核デバッガーやSytemTapスクリプトの説明はありません。 / procファイルシステムのいくつかの有用なノードに関して、「cat / proc / PID / xyz」のような古き良きシンプルなコマンドのみ。
「抑制」プロセスの診断
頻繁に発生する問題をラップトップで再現した良い例を次に示します。ユーザーは、
find
結果を返さずに「はるかに遅い」と不平を言ってい
find
。 問題が何であるかを知って、問題を解決しました。 しかし、私はそのような問題を解決する体系的なアプローチを設定するように頼まれました。
幸いなことに、システムはOEL6を実行しています。 かなり新しいカーネル(つまり-2.6.39 UEK2)
それでは、診断を始めましょう。
最初に、検索プロセスがまだ動作しているかどうかを確認します。
[root @ oel6〜]#ps -ef | grep find
ルート27288 27245 4 11:57ポイント/ 0 00:00:01 検索 -タイプf
ルート27334 27315 0 11:57ポイント/ 1 00:00:00 grep検索
はい、あります-PID 27288(さらに診断例ではこのpidを使用します)
基本から始めて、このプロセスのボトルネックを見てみましょう。 何にもブロックされていない場合(たとえば、必要なものをすべてキャッシュから読み取る)、CPUを100%使用する必要があります。 IOまたはネットワークの問題が原因でブロックされている場合、プロセッサの負荷は低くなるか、まったくなくなるはずです。
[root @ oel6〜]#top -cbp 27288
top-11:58:15最大7日間、3:38、2ユーザー、負荷平均:1.21、0.65、0.47
タスク:合計1、実行0、スリープ1、停止0、ゾンビ0
CPU:0.1%us、0.1%sy、0.0%ni、99.8%id、0.0%wa、0.0%hi、0.0%si、0.0%st
メモリ:合計2026460k、1935780k使用、90680k無料、64416kバッファ
スワップ:合計4128764k、使用済み251004k、3877760k無料、662280kキャッシュ
PIDユーザーPR NI VIRT RES SHR S%CPU%MEM時間+コマンド
27288ルート20 0 109m 1160 844 D 0.0 0.1 0:01.11検索 -タイプf
「top」コマンドの出力は、このプロセスがCPUにまったく負荷をかけないことを示しています(または負荷が非常に小さいため、ゼロと見なすことができます)。 ただし、完全にフリーズし、プロセッサクォンタムを取得する機会がまったくないプロセスと、スタンバイ状態から常に起動してすぐに再びスリープ状態になるプロセス(たとえば、常にタイムアウトで終了するポーリング操作、そして、プロセスは再びそれを呼び出してスリープ状態になります)。 残念ながら、これらの2つの状態を認識するには「トップ」コマンドでは不十分です。 しかし、少なくともこのプロセスはプロセッサ時間を浪費しないことがすでにわかっています。
他のツールを試してみましょう。 通常、プロセスがこのようにハングするように見える場合(CPUの0%は、通常、プロセスが何らかのシステムコールをブロックしていることを意味します-これにより、カーネルがプロセスをスリープさせます)、そのプロセスで
strace
を実行して、どのシステムコールを追跡します彼は現在立ち往生しています。 プロセスが実際に完全にハングせず、定期的にシステムコールから戻って起動する場合、これはstraceの出力にも表示されます(システムコールは定期的に終了し、再度呼び出されます)。
[root @ oel6〜]#strace -cp 27288
プロセス27288が添付されました-中断して中断します
^ C
^ Z
[1] + strace -cp 27288を停止しました
[root @ oel6〜]#kill -9 %%
[1] + strace -cp 27288を停止しました
[root @ oel6〜]#
[1] +殺された痕跡-cp 27288
おっと... straceチーム自体もハングしているようです! 彼女は長い間何も表示せず、CTRL + Cを押しても応答しなかったため、最初にCTRL + Zを押して彼女をバックグラウンドに送り、その後完全に殺す必要がありました。 簡単な診断ではありません!
pstackを試してみましょう(Linuxでは、pstackはGDBデバッガーの単なるラッパースクリプトです)。 Pstackはカーネルの内部キッチンについては何も教えませんが、少なくともそれがどのようなシステムコールであるかを示します(通常はユーザースタック上のlibcライブラリ関数呼び出しのように見えます)。
[root @ oel6〜]#pstack 27288
^ C
^ Z
[1] + pstack 27288を停止しました
[root @ oel6〜]#%%を殺す
[1] + pstack 27288を停止しました
[root @ oel6〜]#
[1] +終了したpstack 27288
Pstackも説明なしでハングしました!
そのため、プロセスが100%無料(alas)なのか、99.99%(目覚めてすぐに眠りにつく)なのかはまだわかりません。また、これがどこで起こったのかもわかりません。
他にどこが見えますか? よくアクセスできる別の場所があります。ステータスとWCHANフィールドは、古き良きpsコマンドを使用して内容を調べることができます(たぶん、すぐに実行してゾンビに対処していないことを確認してください)。
[root @ oel6〜]#ps -flp 27288
FS UID PID PPID C PRI NI ADDR SZ WCHAN STIME TTY TIME CMD
0 Dルート27288 27245 0 80 0-28070 rpc_wa 11:57ポイント/ 0 00:00:01検索 -タイプf
プロセスが引き続き同じ状態にあることを確認するには、psを連続して数回実行する必要があります(間違ったときに行われた唯一の試行に基づいて誤った結論に達したくないですか?)。 ただし、ここでは勇気を持って1回だけの起動を示しています。
プロセスは状態D(「サウンドスリープ」)にあり、通常はディスクI / Oに関連付けられています(psのマニュアルページにも記載されています)。 さらに、WCHANフィールド(プロセスを休止状態または待機状態にした関数の名前)は少しトリミングされています。 ps呼び出しにオプションを追加してこのフィールドの出力を少し広くすることができますが、その内容はいずれの場合も/ procシステムから取得されるため、ソースを直接見てみましょう(繰り返しますが、凍結を確認するためにこれを数回行うとよいでしょう)プロセスが完了しているかどうか、または非常に頻繁にたくさん寝ているかどうか):
[root @ oel6〜]#cat / proc / 27288 / wchan
rpc_wait_bit_killable
うーん...プロセスは何らかのRPCコールを期待しているようです。 これは通常、プロセスが他のプロセスと通信していることを意味します(ローカルマシン上、またはリモートサーバー上でも)。 しかし、まだ理由はわかりません。
何か動きがありますか、またはプロセスが完全に行き詰っていますか?
記事の「肉」に進む前に、プロセスが完全にスタックしているかどうかを判断しましょう。 最新のカーネルでは、/ proc / PID / statusを調べることでこれについて知ることができます。 わかりやすくするために、興味深い値を強調しています。
[root @ oel6〜]#cat / proc / 27288 / status
名前:検索
状態:D(ディスクスリープ)
Tgid:27288
Pid:27288
PPid:27245
TracerPid:0
Uid:0 0 0 0
Gid:0 0 0 0
Fdsize:256
グループ:0 1 2 3 4 6 10
VmPeak:112628 kB
VmSize:112280 kB
VmLck:0 kB
VmHWM:1508 kB
VmRSS:1160 kB
VmData:260 kB
VmStk:136 kB
VmExe:224 kB
VmLib:2468 kB
VmPTE:88 kB
VmSwap:0 kB
スレッド:1
SigQ:4/15831
SigPnd:0000000000040000
ShdPnd:0000000000000000
SigBlk:0000000000000000
SigIgn:0000000000000000
SigCgt:0000000180000000
CapInh:0000000000000000
CapPrm:ffffffffffffffff
CapEff:ffffffffffffffff
Capbnd:ffffffffffffffff
Cpus_allowed:ffffffff、ffffffff
Cpus_allowed_list:0-63
Mems_allowed:00000000,00000000,00000000,00,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000、 00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000001
Mems_allowed_list:0
voluntary_ctxt_switches:9950
nonvoluntary_ctxt_switches:17104
プロセスは状態D-ディスクスリープ(「サウンド」スリープ)です。 また、
voluntary_ctxt_switches
と
nonvoluntary_ctxt_switches
値にも注意してください-プロセッサーがCPUの
nonvoluntary_ctxt_switches
受け取った(または返した)回数がわかります。 次に、数秒後にコマンドを再度実行し、値が増加したかどうかを確認します。 私の場合、数は増えませんでした。したがって、プロセスがきつくハングすることをお勧めします(まあ、少なくともチーム間で数秒間起きないでください)。 そのため、プロセスが完全にフリーズしていることを確信できるようになりました(レーダーの下を飛んでいるだけでなく、プロセッサの時間の0.04%を常に消費しています)。
ちなみに、コンテキストスイッチの数を確認できる場所がさらに2つあります(さらに、2つ目は古代のカーネルで使用可能です)。
[root @ oel6〜]#cat / proc / 27288 / sched
検索(27288、#threads:1)
-se.exec_start:617547410.689282
se.vruntime:2471987.542895
se.sum_exec_runtime:1119.480311
se.statistics.wait_start:0.000000
se.statistics.sleep_start:0.000000
se.statistics.block_start:617547410.689282
se.statistics.sleep_max:0.089192
se.statistics.block_max:60082.951331
se.statistics.exec_max:1.110465
se.statistics.slice_max:0.334211
se.statistics.wait_max:0.812834
se.statistics.wait_sum:724.745506
se.statistics.wait_count:27211
se.statistics.iowait_sum:0.000000
se.statistics.iowait_count:0
se.nr_migrations:312
se.statistics.nr_migrations_cold:0
se.statistics.nr_failed_migrations_affine:0
se.statistics.nr_failed_migrations_running:96
se.statistics.nr_failed_migrations_hot:1794
se.statistics.nr_forced_migrations:150
se.statistics.nr_wakeups:18507
se.statistics.nr_wakeups_sync:1
se.statistics.nr_wakeups_migrate:155
se.statistics.nr_wakeups_local:18504
se.statistics.nr_wakeups_remote:3
se.statistics.nr_wakeups_affine:155
se.statistics.nr_wakeups_affine_attempts:158
se.statistics.nr_wakeups_passive:0
se.statistics.nr_wakeups_idle:0
avg_atom:0.041379
avg_per_cpu:3.588077
nr_switches:27054
nr_voluntary_switches:9950
nr_involuntary_switches:17104
se.load.weight:1024
ポリシー:0
プリオ:120
クロックデルタ:72
ここでは、
nr_switches
(
nr_voluntary_switches
+
nr_involuntary_switches
等しい)の数を調べる必要があります。
上記の部分のnr_switchesの総数は27054であり、出力/ proc / PID / schedstatの3番目のフィールドにもあります。
[root @ oel6〜]#cat / proc / 27288 / schedstat
1119480311 724745506 27054
そして、それは増加しません...
/ procファイルシステムを使用したコアカーネルキッチンの探索
私たちのプロセスは非常に固く凍結されているようです:)。 Straceとpstackは役に立ちません。 彼らはptrace()システムコールを使用してプロセスに接続し、メモリに挿入しますが、プロセスが絶望的にハングするため、おそらく何らかのシステムコールでハングするので、ptrace()コールもそれ自体でハングすると仮定します(ところで、私はどういうわけか、ターゲットプロセスに接続する瞬間にstrace自体でstraceを実行しようとしましたが、これによりプロセスがクラッシュしました。
どのシステムコールでstraceまたはpstackなしで電話を切ったのかを知るにはどうすればよいですか? 幸いなことに、私たちは最新のコアに取り組んでいます! ようこそ/ proc / PID / syscall!
[root @ oel6〜]#cat / proc / 27288 / syscall
262 0xffffffffffffffff9c 0x20cf6c8 0x7fff97c52710 0x100 0x100 0x676e776f645f616d 0x7fff97c52658 0x390e2da8ea
つまずく! そして、私はこれで何をすべきですか?
まあ、通常、これらの数字は何かのために必要です。 “ 0xAVeryBigNumber”のようなものが表示される場合、これは通常メモリ内のアドレスであり(pmapなどのユーティリティで使用できます)、数値が小さい場合は、おそらくある種の配列のインデックスです。 たとえば、開いているファイル記述子の配列(/ proc / PID / fdで確認できます)、またはこの場合、システムコールを処理しているため、これはプロセスが存在するシステムコールの数です! そのため、プロセスがシステムコール#262でスタックしていることがわかりました。
システムコール番号は、オペレーティングシステム、OSバージョン、プラットフォームによって異なる場合があるため、OSから正しいヘッダーファイルが必要になることに注意してください。 / usr / includeフォルダーで「syscall *」を探すことから始めるのがよいでしょう。 私のバージョンおよびLinuxプラットフォーム(64ビット)では、システムコールはファイル
/usr/include/asm/unistd_64.h
定義されています。
[root @ oel6〜]#grep 262 /usr/include/asm/unistd_64.h
#define __NR_ newfstatat 262
もうすぐです! 262システムコールは
newfstatat
と呼ばれるもの
newfstatat
。 人を動かし、それが何であるかを知ることは残っています。 システムコールの名前について簡単なヒントを示します。マニュアルページで必要な名前が見つからない場合は、あらゆる種類のサフィックスとプレフィックスなしで検索してみてください(たとえば、「man pread64」ではなく「man pread」)-この場合、「new」prefix-
man fstatat
なしでmanを実行します
man fstatat
。 まあ、または単にそれをグーグル。
場合によっては、この「new-fstat-at」システムコールにより、通常のstatシステムコールと非常によく似たファイルプロパティを読み取ることができます。 そして、私たちはファイルのメタデータを読み取る操作に専念しました。 それで、私たちはさらに一歩前進しました。 ただし、凍結が発生した理由はまだわかりません。
さて、
私の小さな友人 / proc / PID / stackに挨拶する時が来ました。これにより、procファイルの内容を印刷するだけで、プロセスの核スタックのチェーンを見ることができます!!!
[root @ oel6〜]#cat / proc / 27288 / スタック
[] rpc_wait_bit_killable + 0x24 / 0x40 [sunrpc]
[] __rpc_execute + 0xf5 / 0x1d0 [sunrpc]
[] rpc_execute + 0x43 / 0x50 [sunrpc]
[] rpc_run_task + 0x75 / 0x90 [sunrpc]
[] rpc_call_sync + 0x42 / 0x70 [sunrpc]
[] nfs3_rpc_wrapper.clone.0 + 0x35 / 0x80 [nfs]
[] nfs3_proc_getattr + 0x47 / 0x90 [nfs]
[] __nfs_revalidate_inode + 0xcc / 0x1f0 [nfs]
[] nfs_revalidate_inode + 0x36 / 0x60 [nfs]
[] nfs _getattr + 0x5f / 0x110 [nfs]
[] vfs_getattr + 0x4e / 0x80
[] vfs_fstatat + 0x70 / 0x90
[] sys_ newfstatat + 0x24 / 0x50
[] system_call_fastpath + 0x16 / 0x1b
[] 0xffffffffffffffff
一番上の機能は、カーネルコード内の場所です。 これはまさにWCHANフィールドが既に言ったことです(ただし、実際には、必要に応じてプロセスをスリープまたはウェイクアップするカーネル
schedule()
関数など、いくつかの機能があることに注意してください。ただし、これらの機能はここには示しません)おそらく、それらはすでに期待の状態の結果であり、その原因ではないからです)。
このタスクのための完全なカーネルスタックを手元に用意して、ボトムアップで調査し、
rpc_wait_bit_killable
関数
rpc_wait_bit_killable
がスケジューラーの呼び出しにどのように
rpc_wait_bit_killable
、
rpc_wait_bit_killable
状態になったかを把握することが
rpc_wait_bit_killable
ます。
system_call_fastpath
コールは、処理しているnewfstatat(
sys_newfstatat
)システムコールを実装するコードにつながった標準カーネルシステムコールハンドラです。 さらに「子」関数に移動すると、NFSに関連するいくつかのことがわかります。 これはすでに、NFS処理コード領域のどこかにいるという100%反論できない証拠です! 上記で見た限り、これらのNFS関数の最後は、RPC関数(rpc_call_sync)を呼び出して別のプロセスにアクセスします。 この場合、おそらく
[kworker/N:N]
、
[nfsiod]
、
[lockd]
または
[rpciod]
IOカーネルスレッドです。 そして、これらのスレッドのいくつかは何らかの理由で応答しません(通常、ネットワーク接続の切断、パケット損失、または何らかのネットワークの問題を疑う必要があります)。
これらの補助スレッドのいずれかがネットワーク関連のコードでハングしているかどうかを判断するには、たとえば、kworkersがRPCをNFSに接続するだけでなく、はるかに多くの機能を実行する場合でも、スタックを考慮する必要があります 別の実験(NFSを介して大きなファイルをコピーするだけ)で、コードでネットワークと通信するために待機しているkworkersの1人を見つけました。
[root @ oel6 proc]# `pgrep worker`のiの場合; ps -fp $ i; cat / proc / $ i /スタック; やった
UID PID PPID C STIME TTY TIME CMD
ルート53 2 0 2月14日? 00:04:34 [ kworker / 1:1]
[] __cond_resched + 0x2a / 0x40
[] lock_sock_nested + 0x35 / 0x70
[] tcp_sendmsg + 0x29 / 0xbe0
[] inet_sendmsg + 0x48 / 0xb0
[] sock_sendmsg + 0xef / 0x120
[] kernel_sendmsg + 0x41 / 0x60
[] xs_send_kvec + 0x8e / 0xa0 [sunrpc]
[] xs_sendpages + 0x173 / 0x220 [sunrpc]
[] xs_tcp_send_request + 0x5d / 0x160 [sunrpc]
[] xprt_transmit + 0x83 / 0x2e0 [sunrpc]
[] call_transmit + 0xa8 / 0x130 [sunrpc]
[] __rpc_execute + 0x66 / 0x1d0 [sunrpc]
[] rpc_async_schedule + 0x15 / 0x20 [sunrpc]
[] process_one_work + 0x13e / 0x460
[] worker_thread + 0x17c / 0x3b0
[] kthread + 0x96 / 0xa0
[] kernel_thread_helper + 0x4 / 0x10
おそらく、カーネルトレースを有効にして、どのカーネルスレッドが相互に通信しているかを正確に見つけることは難しくありませんが、この記事ではこれを行いたくありません。 実用的な(そして簡単な)診断演習にしてください!
理解して「修理」する
いずれの場合でも、最新のLinuxでカーネルスタックの印刷を非常に簡単に取得できるため(どのバージョンのカーネルが登場したか正確には言えません)、findコマンドがハングした場所、つまりカーネルのNFSコードで一貫して結論を出すことができましたLinux また、NFSに関連するハングアップを処理している場合は、おそらくネットワークの問題を疑う必要があります。 示された問題の再現方法に興味がある場合は、すべてが非常に簡単です。仮想マシンからNFSボリュームをマウントし、findコマンドを実行してから、マシンを停止しました。 これにより、TCPエンドノードに通知せずに接続がサイレントに終了する、または何らかの理由でパケットが単に通過しないネットワーク(構成、ファイアウォール)の問題がある場合と同じ症状が生じました。
スタックの一番上には「killable」関数の1つ(安全に中断できる
rpc_wait_bit_killable
)があるため、
kill -9
コマンドでそれを
rpc_wait_bit_killable
できます。
[root @ oel6〜]#ps -fp 27288
UID PID PPID C STIME TTY TIME CMD
ルート27288 27245 0 11:57ポイント/ 0 00:00:01 検索 -タイプf
[root @ oel6〜]#kill -9 27288
[root @ oel6〜]#ls -l / proc / 27288 / stack
ls:/ proc / 27288 / stackにアクセスできません:そのようなファイルまたはディレクトリはありません
[root @ oel6〜]#ps -fp 27288
UID PID PPID C STIME TTY TIME CMD
[root @ oel6〜]#
プロセスは完了です。
「ひざの上の」カーネルスレッドのプロファイリング
ファイル/ proc / PID / stackは通常のテキストファイルのように見えることに注意してください。 したがって、カーネルスレッドプロファイルを簡単に取得できます! 以下は、「ひざまずいて」現在のシステムコールとカーネルスタックの昇格(システムコールの場合)を確認し、これらすべてを半階層プロファイルに結合する方法です。
[root @ oel6〜]#export LC_ALL = C ; for iの{1..100}; do cat / proc / 29797 / syscall | awk '{print $ 1}'; cat / proc / 29797 /スタック| / home / oracle / os_explain -k; usleep 100000; 完了| sort -r | uniq -c
69ランニング
1 ffffff81534c83
2 ffffff81534820
6,247
25,180
100 0xffffffffffffffff
1 thread_group_cputime
27 sysenter_dispatch
3 ia32_sysret
1 task_sched_runtime
27 sys32_pread
1 compat_sys_io_submit
2 compat_sys_io_getevents
27 sys_pread64
2 sys_io_getevents
1 do_io_submit
27 vfs_read
2 read_events
1 io_submit_one
27 do_sync_read
1 aio_run_iocb
27 generic_file_aio_read
1 aio_rw_vect_retry
27 generic_file_read_iter
1 generic_file_aio_read
27 mapping_direct_IO
1 generic_file_read_iter
27 blkdev_direct_IO
27 __blockdev_direct_IO
27 do_blockdev_direct_IO
27 dio_post_submission
27 dio_await_completion
6 blk_flush_plug_list
これにより、プロセスがカーネル内のどこで時間を費やしているのかを非常に大まかに評価できます。 システムコール番号は、上部で個別に強調表示されます。 「実行中」とは、診断中にプロセスがユーザー空間で機能したことを意味します(システムコールでは機能しません)。 そのため、プロセスがユーザーコードであった時間の69%です。 システムコール#180(私のシステムではnfsservctl)で25%、システムコール#247(waitid)で6%。
上記では、作成者はスクリプト/ home / oracle / os_explainの呼び出しを使用しています。 参照で取得できます-約。 perev。出力には、さらに2つの「関数」が表示されますが、何らかの理由で名前で表示されませんでした。 ただし、それらのアドレスは既知であるため、手動で確認できます。
[root @ oel6〜]#cat / proc / kallsyms | grep -i ffffff81534c83
ffffffff81534c83 t ia32_sysret
これは32ビットサブシステムのシステムコールからの戻り値のようですが、この関数自体はシステムコールではないため(単なる内部補助関数です)、明らかに/ proc /スタックハンドラはその名前を表示しませんでした。 / procの状態はリーダーと一致しないため、これらのアドレスが表示される可能性もあります。一方、1つのスレッドがこれらのメモリ構造とスレッドを読み取る要素を変更すると、古いデータが表示される場合があります。
2番目のアドレスを同時に確認します。
[root @ oel6〜]#cat / proc / kallsyms | grep -i ffffff81534820
[root @ oel6〜]#
何も見つかりませんでしたか? ただし、デバッグはここまでではありません! このアドレスの周辺で何か面白いものを探しましょう。 たとえば、アドレスの末尾にある最後の数桁を削除します。
[root @ oel6〜]#cat / proc / kallsyms | grep -i ffffff815348
ffffffff8153480d t sysenter_do_call
ffffffff81534819 t sysenter_dispatch
ffffffff81534847 t sysexit_from_sys_call
ffffffff8153487a t sysenter_auditsys
ffffffff815348b9 t sysexit_audit
sysenter_dispatch関数は、/ proc / PID / stackにマッピングされた元のアドレスの1バイト前に文字通り開始するようです。 そのため、ほとんどの場合1バイトをほぼ完了しました(おそらく、動的デバッグ用にそこにあるNOPコマンド)。 ただし、スタックのこれらの部分は
sysenter_dispatch
関数にあるようです
sysenter_dispatch
関数は、それ自体はシステムコールではなく、ヘルパー関数です。 (
少し掘り下げた場合-違いはまだ1バイトではなく7バイトです。数字は16進数です!-およそTransl。 )
スタックプロファイリングの詳細
LinuxのPerf、SolarisのDTraceのOprofileおよび
profile
ユーティリティなど、さまざまなスタックプロモーションユーティリティは、命令ポインターレジスタ(32ビットIntelのEIP、またはx64のRIP)と、スタックポインター(32ビットのESPおよびRSPのESP x64)プロセッサ上の現在のスレッドに対して、スタックポインタに沿って戻ります。 したがって、これらのユーティリティは、テスト時にCPUで実行されるスレッドのみを表示できます!
これは、もちろん、プロセッサの負荷が高い問題を探しているときは素晴らしいことですが、デッドロックまたは長時間待機/休止状態のプロセスの診断にはまったく役に立ちません。Linux、Solaris、HP-UX、procstack(AIX上)、ORADEBUG SHORT_STACK上のpstack、および/ proc / PID / stack疑似ファイルの読み取りなどのユーティリティは、CPUプロファイリングユーティリティへの適切な追加(置換ではありません)-プロセスメモリに独立してアクセスできる限りスケジューラーの状態からスタックを読み取ります。プロセスがスリープしてCPUに触れない場合、プロセススタックの最上部は保存されたコンテキストから読み取ることができます。保存されたコンテキストは、コンテキストの切り替え中にOSスケジューラーによってカーネルメモリに保存されます。もちろん、プロセッサイベントプロファイリングユーティリティは、多くの場合、pstack、OProfile、Perf、さらにはDTrace(Solaris11)のCPCプロバイダー以上のものを実行できます。たとえば、内部プロセッサカウンタを設定および読み取り、メモリアクセスの待機中にミスしたCPUサイクル数などを評価します。L1 / L2キャッシュのミス数など しかし、Kevin Clossonがこれについて書いていることをよく読んでください:(Perf、Oprofile)幸運を祈ります:-)関連トピック