Tetsuo Handa
from-****@I-lov*****
2008年 11月 30日 (日) 23:04:23 JST
熊猫です。 > とりあえず objdump とってみましたがソースコードは入ってないみたいです。 > CONFIG_DEBUG_INFO というのは .config に見つからなかったのですが、 > CONFIG_DEBUG_KERNEL が not set のせいでしょうか? そうですね。 # CONFIG_DEBUG_KERNEL is not set. だと CONFIG_DEBUG_INFO は設定できません。 http://tomoyo.sourceforge.jp/cgi-bin/lxr/source/fs/realpath.c#L619 と 比較しながら推測してみました。(まったく自信ありません。) −−−−− 00000000000001b0 <ccs_free>: /* if (!p) goto 1e8; */ 1b0: 48 85 ff test %rdi,%rdi 1b3: 53 push %rbx 1b4: 74 32 je 1e8 <ccs_free+0x38> /* v = &cache_list->next; */ 1b6: 48 8b 1d 00 00 00 00 mov 0x0(%rip),%rbx # 1bd <ccs_free+0xd> /* goto 1c9; */ 1bd: eb 0a jmp 1c9 <ccs_free+0x19> 1bf: 90 nop /* if (entry->ptr == p) goto 1f0; */ 1c0: 48 39 7b 10 cmp %rdi,0x10(%rbx) 1c4: 74 2a je 1f0 <ccs_free+0x40> /* v = v->next; */ 1c6: 48 89 f3 mov %rsi,%rbx 1c9: 48 8b 33 mov (%rbx),%rsi /* if (v) goto 1c0; */ 1cc: 48 81 fb 00 00 00 00 cmp $0x0,%rbx /* prefetch(v->next), */ 1d3: 0f 18 0e prefetcht0 (%rsi) 1d6: 75 e8 jne 1c0 <ccs_free+0x10> 1d8: 5b pop %rbx /* entry = NULL; */ 1d9: 48 c7 c7 00 00 00 00 mov $0x0,%rdi 1e0: 31 c0 xor %eax,%eax 1e2: e9 00 00 00 00 jmpq 1e7 <ccs_free+0x37> 1e7: 90 nop /* return; */ 1e8: 5b pop %rbx 1e9: c3 retq 1ea: 66 0f 1f 44 00 00 nopw 0x0(%rax,%rax,1) /* list_del(&entry->list); */ 1f0: 48 8b 43 08 mov 0x8(%rbx),%rax 1f4: 48 89 46 08 mov %rax,0x8(%rsi) 1f8: 48 89 30 mov %rsi,(%rax) 1fb: 48 c7 43 08 00 02 20 movq $0x200200,0x8(%rbx) 202: 00 203: 48 c7 03 00 01 10 00 movq $0x100100,(%rbx) /* dynamic_memory_size -= entry->size; */ 20a: 8b 43 18 mov 0x18(%rbx),%eax 20d: 29 05 00 00 00 00 sub %eax,0x0(%rip) # 213 <ccs_free+0x63> 213: e8 00 00 00 00 callq 218 <ccs_free+0x68> 218: 48 89 de mov %rbx,%rsi 21b: 48 8b 3d 00 00 00 00 mov 0x0(%rip),%rdi # 222 <ccs_free+0x72> 222: 5b pop %rbx 223: e9 00 00 00 00 jmpq 228 <ccs_free+0x78> 228: 0f 1f 84 00 00 00 00 nopl 0x0(%rax,%rax,1) 22f: 00 −−−−− ccs_free+0x19/0x80 でこけるということは、 1c9 の位置ですね。 list_for_each(v, &cache_list) マクロの中の pos = (head)->next あるいは pos = pos->next を処理する箇所だと思われます。 何かの拍子に %rbx が 0xffffffffffffffff になってしまい、そのまま (%rbx) (読み出しアクセス)を実行したことで BUG: unable to handle kernel paging request at ffffffffffffffff となったのでしょうが、何故 %rbx に 0xffffffffffffffff が入ったのかは 特定できませんでした。誰かが %rip の指す領域に 0xffffffffffffffff と 書きこんでいたのであれば 1b6 で%rbx に 0xffffffffffffffff が入るので 納得ですが、これ以上の解析はできそうにないです。 spin_lock() / spin_unlock() / kfree() / kmem_cache_free() / printk() を 呼んでいる気配がしないのが何とも不気味ですね。 %rip には cache_list とか dynamic_memory_size とかのアドレスを 代入する必要があるのに、それらしき箇所も見当たりません。 # CONFIG_DEBUG_KERNEL is not set. なのに CONFIG_DEBUG_LIST=y なのか、 LIST_POISON1 ( $0x100100 )や LIST_POISON2 ( $0x200200 )を代入している ように見えます。 1cc の箇所が pos != (head) ではなく pos != NULL のように見えるのも 変な気がします。 う〜ん、どうやって動いているんでしょうねぇ?