SGI KDBを使ったカーネルデバッグスレ
1 :名無しさん@お腹いっぱい。 :2001/05/13(日) 19:02.net カーネルデバッグの話はここで存分にどうぞ
101 :login:Penguin :2001/05/31(木) 11:06.net >>98 ユーザが生成できるプロセスMAX数が設定できないの? MagicKeyでも殺せないの?
102 :オリジナルスレの1 :2001/05/31(木) 12:01.net >>98 ソースを見てみてデバッグしてみた。101が正しいな。 fork.cのdo_fork関数に以下のようなコードがある。 retval = -EAGAIN; if (atomic_read(&p->user->processes) >= p->rlim[RLIMIT_NPROC].rlim_cur) goto bad_fork_free; atomic_inc(&p->user->__count); atomic_inc(&p->user->processes); でp->userはsched.hを見るとuser_structだから、user_structの定義を見ると これもsched.hにある。 struct user_struct { atomic_t __count; /* reference count */ atomic_t processes; /* How many processes does this user have? */ atomic_t files; /* How many open files does this user have? */ /* Hash table maintenance information */ struct user_struct *next, **pprev; uid_t uid; }; これらよりコメントを見れば分かるけどprocessesはこのユーザコンテキスト 上でいくつのプロセスが走っているかを示している。それを p->rlim[RLIMIT_NPROC].rlim_cur と比較してそれ以上になったら fork処理を失敗させている。rlim_curはfork_initでイニシャライズ されていてmax_threads/2になっている。
103 :オリジナルスレの1 :2001/05/31(木) 12:12.net 実際にデバッガでどう動いているか見てみよう。 まず main(){while(fork());} をコンパイルし実行する。 pauseキーでブレイクインし、do_forkにブレイクポイントを張る。 [1]kdb> bp do_fork Instruction(i) BP #0 at 0xc0115270 (do_fork) is enabled globally adjust 1 gで、再実行。先ほど実行したプログラムでforkが実行されまくってる からねすかさず止まるはず。 Instruction(i) breakpoint #0 at 0xc0115270 (adjusted) 0xc0115270 do_forkint3 Entering kdb (current=0xc5f82000, pid 15240) on processor 1 due to Breakpoint @0xc0115270 止まったら if (atomic_read(&p->user->processes) >= p->rlim[RLIMIT_NPROC].rlim_cur) の行までトレースする。ソースをみるとこの条件判断はalloc_task_structの 次の次の条件判断であることが分かる。この辺りのコードでアロケートしてるのは 0xc01152ee do_fork+0x7ecall 0xc012fbe0 __get_free_pages 0xc01152f3 do_fork+0x83mov %eax,%ebx 0xc01152f5 do_fork+0x85test %ebx,%ebx 0xc01152f7 do_fork+0x87je 0xc01158d8 do_fork+0x668 のコードだ。test %ebx,%ebx jeはif (!p) gotoであることは容易に分かる このコードの次の条件判断は 0xc0115314 do_fork+0xa4mov 0x4(%edx),%eax 0xc0115317 do_fork+0xa7cmp 0x300(%ebx),%eax 0xc011531d do_fork+0xadjae 0xc011596b do_fork+0x6fb だから、ここまでトレース。トレースはssコマンドだ。
104 :オリジナルスレの1 :2001/05/31(木) 13:02.net 俺は実際にはトレースするの面倒だから 0xc0115317にブレイクポイントを 設定し実行した。 [0]kdb> bp 0xc0115317 Instruction(i) BP #1 at 0xc0115317 (do_fork+0xa7) is enabled globally adjust 1 [1]kdb> g Instruction(i) breakpoint #1 at 0xc0115317 (adjusted) 0xc0115317 do_fork+0xa7int3 Entering kdb (current=0xc5f82000, pid 15240) on processor 1 due to Breakpoint @0xc0115317 次に実行されるインストラクションはこれ。 0xc0115317 do_fork+0xa7cmp 0x300(%ebx),%eax レジスタの内容を見てみよう。eaxが&p->user->processesのはず。 [1]kdb> rd eax = 0x00001000 ebx = 0xc2bd0000 ecx = 0x00000000 edx = 0xc6d0dfc0 esi = 0xc5f82680 edi = 0xc2bd0680 esp = 0xc5f83f50 eip = 0xc0115317 ebp = 0xc5f83fa4 xss = 0x00000018 xcs = 0x00000010 eflags = 0x00000286 xds = 0xc5f80018 xes = 0x00000018 origeax = 0xffffffff ®s = 0xc5f83f1c eaxは0x1000つまり4096だな。0x300(%ebx)も見てみよう。メモリダンプはmdだ。 [0]kdb> md %ebx+0x300 0xc5aaa300 00001000 00001000 00000400 00000400 ................ p->rlim[RLIMIT_NPROC].rlim_curも0x1000,4096であることがわかる。 つまりこのマシンでは1ユーザーコンテキスト上では4096個以上のプロセスは 立ち上げられないことになる。実際にpsコマンドでみても4096以上は 立ち上がっていない。
105 :オリジナルスレの1 :2001/05/31(木) 13:22.net まあ、こんなもんだ。まあまあの題材だったね。 2.2.19にも retval = -EAGAIN; if (p->user) { if (atomic_read(&p->user->count) >= p->rlim[RLIMIT_NPROC].rlim_cur) goto bad_fork_free; atomic_inc(&p->user->count); } ちゅうコードがあるからちゃんと動くはずだけどなあ。
106 :login:Penguin :2001/05/31(木) 22:00.net ∩ | | | | ∧_∧ | | / ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ( ´Д`)// < 先生!クソレスがついてます! / / \ やはりちゃんころですか!?鬱だ、sageます! / /| / \_____________ __| | .| | \  ̄ ̄ ̄ ̄ ̄ ̄ ̄\ ||\ \ ||\|| ̄ ̄ ̄ ̄ ̄ ̄ ̄|| ̄ || || ̄ ̄ ̄ ̄ ̄ ̄ ̄|| .|| ||
107 :login:Penguin :2001/05/31(木) 22:00.net .'⌒⌒丶 _ ′从 从)_ もう寝る | __ヽゝ・_・ν | |\ ⌒⌒⌒⌒⌒\ | \ \ \ |⌒⌒⌒⌒⌒| \ |_____|
108 :login:Penguin :2001/05/31(木) 22:43.net >>105 ところで、その 1ユーザが生成できるプロセスの上限 はどこで設定できるの?
109 :オリジナルスレの1 :2001/06/01(金) 01:58.net rootユーザーの場合はulimitコマンドで設定することが可能。 一般ユーザーは設定できない。一般ユーザの最大プロセス数を変更したい場合は 2.2系では最大値はtask.hで #define MAX_TASKS_PER_USER (NR_TASKS/2) と定義されてるからここを適当にかえて再構築。 2.4系では>>102 で書いたようにfork_initの中で物理メモリの搭載量をもとに max_threadsが計算され、その半分に設定されている。 変更したい場合は物理メモリの搭載量をかえましょう。 どうしてもメモリをそのままでプロセス数だけ変更したい場合はfork.cのfork_initの init_task.rlim[RLIMIT_NPROC].rlim_cur = max_threads/2; init_task.rlim[RLIMIT_NPROC].rlim_max = max_threads/2; のmax_threads/2を適当な値に変えて再構築しましょう。
110 :login:Penguin :2001/06/01(金) 02:09.net >>109 減らす方向にはユーザレベルで可能なはずだが、 現在手元にソースが無いので確認できず
131 KB
新着レスの表示
掲示板に戻る
全部
前100
次100
最新50
read.cgi ver 2014.07.20.01.SC 2014/07/20 D ★
本文 スレッドタイトル 投稿者