psを読む
をテンプレートにして作成
[
トップ
] [
新規
|
一覧
|
単語検索
|
最終更新
|
ヘルプ
]
開始行:
#contents
*はじめに [#od641b43]
今回はpsを読みます。何故psかというと、
-伝統的なUNIXのコマンド
-/procから情報を得るプログラムが実際どうやっているのかを...
という理由からです。それでは、psを使う際に多分最も多く使...
ps aux
とした場合に何が行われるかを眺めます。
なお今回対象としたバージョンはprocps 3.2.7に含まれるpsで...
*処理の流れ [#wcc0c362]
psディレクトリにあるHACKINGを見るとどのファイルに何が書い...
main関数を眺めると以下の処理が行われています。
+初期化
+オプションの解析
+出力の下準備
+プロセス情報の表示
それぞれ見ていくことにしましょう。
*初期化 [#ce38f0b4]
初期化はreset_global関数(global.c)に書かれています。
reset_global関数でまず呼ばれているreset_selection_list関...
if(selection_list == (selection_node *)0xdeadbeef){
selection_list = NULL;
return;
}
無効なアドレスを指すのにdeadbeefですか:-)。deadbeafがなん...
次にset_personality関数を見てみます。bsearch関数使われて...
*オプションの解析 [#mea0f605]
では次にオプションの解析です。オプションの解析はarg_parse...
まずparse_all_options関数です。下請けのarg_type関数でハイ...
:simple_select|SS_B_a | SS_B_x
:format_flag|FF_Bu
次のthread_option_check関数ではthread_flagsは0初期化され...
:thread_flags|TF_show_proc
次にprocess_sf_options関数(sortformat.c)です。format_fl...
なお、search_format_array関数やsearch_macro_array関数およ...
"OL_u"の場合、以下の表示項目になります。
/* Justification control for flags field. */
#define USER CF_USER // left if text, right if nu...
#define LEFT CF_LEFT
#define RIGHT CF_RIGHT
#define UNLIMITED CF_UNLIMITED
#define PIDMAX CF_PIDMAX
#define TO CF_PRINT_THREAD_ONLY
#define PO CF_PRINT_PROCESS_ONLY
#define ET CF_PRINT_EVERY_TIME
/* short names to save space */
#define ARG PROC_FILLARG /* read cmdline (cleared if...
#define USR PROC_FILLUSR /* uid_t -> user names */
/* code header print() sort() widt...
{"user", "USER", pr_euser, sr_euser, 8,...
{"pid", "PID", pr_pid, sr_tgid, 5,...
{"pcpu", "%CPU", pr_pcpu, sr_pcpu, 4,...
{"pmem", "%MEM", pr_pmem, sr_nop, 4,...
{"vsz", "VSZ", pr_vsz, sr_vm_size, 6,...
{"rsz", "RSZ", pr_rss, sr_vm_rss, 5,...
{"tname", "TTY", pr_tty8, sr_tty, 8,...
{"stat", "STAT", pr_stat, sr_state, 4,...
{"start_time", "START", pr_stime, sr_start_time, 5,...
{"bsdtime", "TIME", pr_bsdtime, sr_nop, 6,...
{"args", "COMMAND", pr_args, sr_cmd, 27,...
arg_parse関数に戻って次に呼ばれているのはselect_bits_setu...
最後にchoose_dimensions関数、wの数に応じて表示幅を設定し...
*出力の下準備 [#n563b2b6]
**init_output() [#y6e58a66]
出力の下準備としてまずinit_output関数(output.c)を呼んで...
次にmeminfo関数(proc/sysinfo.c)を呼び出して/proc/meminf...
最後にcheck_header_width関数を呼び出してactive_cols変数を...
**lists_and_needs() [#g0825a1e]
次にlists_and_needs関数が呼び出されています。今まで設定さ...
:proc_format_list|format_list
:proc_format_needs|PROC_FILLCOM | PROC_FILLUSR
*プロセス情報の表示 [#b7f76b2a]
ようやくプロセス情報の表示です。forest_typeが0でsort_list...
+プロセステーブルのオープン
+次のプロセス情報の読み込み
+表示対象かの判断
+プロセス情報の表示
それではひとつずつ見ていくことにしましょう。
**openproc() [#f013ae77]
プロセステーブルのオープンを行うopenproc関数はproc/readpr...
needs_for_format | needs_for_sort | needs_for_select | n...
なので展開すると以下になります。
PROC_FILLUSR | PROC_FILLCOM | PROC_FILLSTAT | PROC_FILLS...
というわけでPROC_PIDは立っていないことを考えると、
:PT->reader|simple_readproc
:PT->procfs|opendir("/proc")
:PT->finder|simple_nextpid
が設定されます。
**readproc() [#e3e6ea33]
次にプロセス情報の読み込みを行っているreadproc関数です。...
proc_t* readproc(PROCTAB *restrict const PT, proc_t *res...
restrictキーワードはC99で追加されたものでポインタが同じも...
次に、以下の部分
if (unlikely(! PT->finder(PT,p) )) goto out;
unlikelyはproc/procps.hで以下のように定義されています。
#if __GNUC__ > 2 || __GNUC_MINOR__ >= 96
#define likely(x) __builtin_expect(!!(x),1)
#define unlikely(x) __builtin_expect(!!(x),0)
#else
#define likely(x) (x)
#define unlikely(x) (x)
__buildin_expectはgcc拡張で大体この値になるから分岐を最適...
***simple_nextpid() [#uaa5766e]
それではPT->finderの実体のsimple_nextpid関数です。openpro...
***simple_readproc() [#t7842077]
次にPT->readerの実体のsimple_readproc関数です。
まずプロセスディレクトリを引数にstat関数を実行して所有者...
次に、PROC_FILLSTATフラグが立っているのでプロセスディレク...
その後、PROC_FILLUSRフラグが立っているのでuidからユーザ名...
最後に、PROC_FILLCOMフラグが立っているのでプロセスディレ...
引数1(NUL)引数2(NUL)引数3(NUL)[align]<引数1へのポインタ>...
<-- ファイルの内容 --> ↑
返されるポインタ
**want_this_proc() [#q55dab4b]
表示対象かの判断を行うwant_this_proc関数はselect.cに書か...
**show_one_proc() [#q9ef1061]
最後にプロセス情報の表示です。show_one_proc関数はoutput.c...
初めて呼び出された場合、lines_to_next_headerは1なのでproc...
show_one_procではformat_nodeをたどり、スペースとかを考慮...
-pr_pcpu()
-pr_tty8()
***pr_pcpu() [#n5013c21]
pr_pcpu関数ではプロセスが使用したCPU時間を計算して表示し...
はまあ普通の処理なのですが設定された記憶のないHertz変数が...
Linuxのバージョンは2.4.0以上として、init_libproc関数は環...
***pr_tty8() [#k99fab5c]
次にttyの表示を行うpr_tty8関数です。実際の処理はproc/devn...
dev_to_tty関数はdriver_name関数を呼ぶことでtty番号からtty...
*おわりに [#ne8f4f83]
今回はpsの挙動を見てきました。感想としては、
-いろんなことを処理するのにテーブルベースの処理がよく使わ...
-gotoラベルの変数代入や__attribute__などいろいろなgcc拡張...
-効率アップのために知らないと理解に苦しむという部分もちら...
といったところです。それではみなさんもよいコードリーディ...
終了行:
#contents
*はじめに [#od641b43]
今回はpsを読みます。何故psかというと、
-伝統的なUNIXのコマンド
-/procから情報を得るプログラムが実際どうやっているのかを...
という理由からです。それでは、psを使う際に多分最も多く使...
ps aux
とした場合に何が行われるかを眺めます。
なお今回対象としたバージョンはprocps 3.2.7に含まれるpsで...
*処理の流れ [#wcc0c362]
psディレクトリにあるHACKINGを見るとどのファイルに何が書い...
main関数を眺めると以下の処理が行われています。
+初期化
+オプションの解析
+出力の下準備
+プロセス情報の表示
それぞれ見ていくことにしましょう。
*初期化 [#ce38f0b4]
初期化はreset_global関数(global.c)に書かれています。
reset_global関数でまず呼ばれているreset_selection_list関...
if(selection_list == (selection_node *)0xdeadbeef){
selection_list = NULL;
return;
}
無効なアドレスを指すのにdeadbeefですか:-)。deadbeafがなん...
次にset_personality関数を見てみます。bsearch関数使われて...
*オプションの解析 [#mea0f605]
では次にオプションの解析です。オプションの解析はarg_parse...
まずparse_all_options関数です。下請けのarg_type関数でハイ...
:simple_select|SS_B_a | SS_B_x
:format_flag|FF_Bu
次のthread_option_check関数ではthread_flagsは0初期化され...
:thread_flags|TF_show_proc
次にprocess_sf_options関数(sortformat.c)です。format_fl...
なお、search_format_array関数やsearch_macro_array関数およ...
"OL_u"の場合、以下の表示項目になります。
/* Justification control for flags field. */
#define USER CF_USER // left if text, right if nu...
#define LEFT CF_LEFT
#define RIGHT CF_RIGHT
#define UNLIMITED CF_UNLIMITED
#define PIDMAX CF_PIDMAX
#define TO CF_PRINT_THREAD_ONLY
#define PO CF_PRINT_PROCESS_ONLY
#define ET CF_PRINT_EVERY_TIME
/* short names to save space */
#define ARG PROC_FILLARG /* read cmdline (cleared if...
#define USR PROC_FILLUSR /* uid_t -> user names */
/* code header print() sort() widt...
{"user", "USER", pr_euser, sr_euser, 8,...
{"pid", "PID", pr_pid, sr_tgid, 5,...
{"pcpu", "%CPU", pr_pcpu, sr_pcpu, 4,...
{"pmem", "%MEM", pr_pmem, sr_nop, 4,...
{"vsz", "VSZ", pr_vsz, sr_vm_size, 6,...
{"rsz", "RSZ", pr_rss, sr_vm_rss, 5,...
{"tname", "TTY", pr_tty8, sr_tty, 8,...
{"stat", "STAT", pr_stat, sr_state, 4,...
{"start_time", "START", pr_stime, sr_start_time, 5,...
{"bsdtime", "TIME", pr_bsdtime, sr_nop, 6,...
{"args", "COMMAND", pr_args, sr_cmd, 27,...
arg_parse関数に戻って次に呼ばれているのはselect_bits_setu...
最後にchoose_dimensions関数、wの数に応じて表示幅を設定し...
*出力の下準備 [#n563b2b6]
**init_output() [#y6e58a66]
出力の下準備としてまずinit_output関数(output.c)を呼んで...
次にmeminfo関数(proc/sysinfo.c)を呼び出して/proc/meminf...
最後にcheck_header_width関数を呼び出してactive_cols変数を...
**lists_and_needs() [#g0825a1e]
次にlists_and_needs関数が呼び出されています。今まで設定さ...
:proc_format_list|format_list
:proc_format_needs|PROC_FILLCOM | PROC_FILLUSR
*プロセス情報の表示 [#b7f76b2a]
ようやくプロセス情報の表示です。forest_typeが0でsort_list...
+プロセステーブルのオープン
+次のプロセス情報の読み込み
+表示対象かの判断
+プロセス情報の表示
それではひとつずつ見ていくことにしましょう。
**openproc() [#f013ae77]
プロセステーブルのオープンを行うopenproc関数はproc/readpr...
needs_for_format | needs_for_sort | needs_for_select | n...
なので展開すると以下になります。
PROC_FILLUSR | PROC_FILLCOM | PROC_FILLSTAT | PROC_FILLS...
というわけでPROC_PIDは立っていないことを考えると、
:PT->reader|simple_readproc
:PT->procfs|opendir("/proc")
:PT->finder|simple_nextpid
が設定されます。
**readproc() [#e3e6ea33]
次にプロセス情報の読み込みを行っているreadproc関数です。...
proc_t* readproc(PROCTAB *restrict const PT, proc_t *res...
restrictキーワードはC99で追加されたものでポインタが同じも...
次に、以下の部分
if (unlikely(! PT->finder(PT,p) )) goto out;
unlikelyはproc/procps.hで以下のように定義されています。
#if __GNUC__ > 2 || __GNUC_MINOR__ >= 96
#define likely(x) __builtin_expect(!!(x),1)
#define unlikely(x) __builtin_expect(!!(x),0)
#else
#define likely(x) (x)
#define unlikely(x) (x)
__buildin_expectはgcc拡張で大体この値になるから分岐を最適...
***simple_nextpid() [#uaa5766e]
それではPT->finderの実体のsimple_nextpid関数です。openpro...
***simple_readproc() [#t7842077]
次にPT->readerの実体のsimple_readproc関数です。
まずプロセスディレクトリを引数にstat関数を実行して所有者...
次に、PROC_FILLSTATフラグが立っているのでプロセスディレク...
その後、PROC_FILLUSRフラグが立っているのでuidからユーザ名...
最後に、PROC_FILLCOMフラグが立っているのでプロセスディレ...
引数1(NUL)引数2(NUL)引数3(NUL)[align]<引数1へのポインタ>...
<-- ファイルの内容 --> ↑
返されるポインタ
**want_this_proc() [#q55dab4b]
表示対象かの判断を行うwant_this_proc関数はselect.cに書か...
**show_one_proc() [#q9ef1061]
最後にプロセス情報の表示です。show_one_proc関数はoutput.c...
初めて呼び出された場合、lines_to_next_headerは1なのでproc...
show_one_procではformat_nodeをたどり、スペースとかを考慮...
-pr_pcpu()
-pr_tty8()
***pr_pcpu() [#n5013c21]
pr_pcpu関数ではプロセスが使用したCPU時間を計算して表示し...
はまあ普通の処理なのですが設定された記憶のないHertz変数が...
Linuxのバージョンは2.4.0以上として、init_libproc関数は環...
***pr_tty8() [#k99fab5c]
次にttyの表示を行うpr_tty8関数です。実際の処理はproc/devn...
dev_to_tty関数はdriver_name関数を呼ぶことでtty番号からtty...
*おわりに [#ne8f4f83]
今回はpsの挙動を見てきました。感想としては、
-いろんなことを処理するのにテーブルベースの処理がよく使わ...
-gotoラベルの変数代入や__attribute__などいろいろなgcc拡張...
-効率アップのために知らないと理解に苦しむという部分もちら...
といったところです。それではみなさんもよいコードリーディ...
ページ名: