2ちゃんねる スマホ用 ■掲示板に戻る■ 全部 1- 最新50    

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
名前: E-mail (省略可) :

read.cgi ver 2014.07.20.01.SC 2014/07/20 D ★