리눅스 커널메시지를 이용해서 "C" 코드를 찾는방법 ?
글쓴이: chxooi / 작성시간: 수, 2010/07/07 - 12:28오전
아래와 같이 kernel message 가 있다고할때...
net_rx_action+0x69
의 정확한 위치는 아래의 "C" 코드중에 어딘지 정확히 어떻게 알 수 있을까요?
밑의 objdump 를 보면 0x69 의 위치는 0x25c212 로보이는데요..
이 0x25c212 의 "C" 코드가 정확히 어떤건지를 알 수가 없어서요...
Assembler 를 study 해야 할까요???
아니면 이 메시지를 보고 저밑의 3번 ) 실제 함수(net_rx_action)안에서 정확한 code line 을 알아낼 순 없을까요?
1) kernel message .. [<c035d212>] net_rx_action+0x69/0xfa [<c011ea9e>] __do_softirq+0x53/0xe7 [<c0139a6c>] handle_IRQ_event+0x25/0x4a [<c011eb59>] do_softirq+0x27/0x29 [<c011ed72>] irq_exit+0x32/0x34 [<c0104ed8>] do_IRQ+0x4c/0x94 2) objdump -d vmlinuz 실행한것.. 0025c1a9 <net_rx_action>: 25c1a9: 55 push %ebp 25c1aa: 57 push %edi 25c1ab: 56 push %esi 25c1ac: 53 push %ebx 25c1ad: 83 ec 04 sub $0x4,%esp 25c1b0: a1 00 00 00 00 mov 0x0,%eax 25c1b5: 89 04 24 mov %eax,(%esp) 25c1b8: 8b 3d 00 00 00 00 mov 0x0,%edi 25c1be: fa cli 25c1bf: 81 3d 10 00 00 00 10 cmpl $0x10,0x10 25c1c6: 00 00 00 25c1c9: 74 37 je 25c202 <net_rx_action+0x59> 25c1cb: 85 ff test %edi,%edi 25c1cd: 7e 47 jle 25c216 <net_rx_action+0x6d> 25c1cf: a1 00 00 00 00 mov 0x0,%eax 25c1d4: 39 04 24 cmp %eax,(%esp) 25c1d7: 75 3d jne 25c216 <net_rx_action+0x6d> 25c1d9: fb sti 25c1da: 8b 35 10 00 00 00 mov 0x10,%esi 25c1e0: 8b 5e 0c mov 0xc(%esi),%ebx 25c1e3: 31 ed xor %ebp,%ebp 25c1e5: f6 46 08 01 testb $0x1,0x8(%esi) 25c1e9: 75 20 jne 25c20b <net_rx_action+0x62> 25c1eb: 39 dd cmp %ebx,%ebp 25c1ed: 7f 62 jg 25c251 <net_rx_action+0xa8> 25c1ef: fa cli 25c1f0: 39 dd cmp %ebx,%ebp 25c1f2: 74 32 je 25c226 <net_rx_action+0x7d> 25c1f4: 29 ef sub %ebp,%edi 25c1f6: 81 3d 10 00 00 00 10 cmpl $0x10,0x10 25c1fd: 00 00 00 25c200: 75 c9 jne 25c1cb <net_rx_action+0x22> 25c202: fb sti 25c203: 83 c4 04 add $0x4,%esp 25c206: 5b pop %ebx 25c207: 5e pop %esi 25c208: 5f pop %edi 25c209: 5d pop %ebp 25c20a: c3 ret 25c20b: 89 da mov %ebx,%edx 25c20d: 89 f0 mov %esi,%eax 25c20f: ff 56 10 call *0x10(%esi) 25c212: 89 c5 mov %eax,%ebp 25c214: eb d5 jmp 25c1eb <net_rx_action+0x42> 25c216: 83 05 08 00 00 00 01 addl $0x1,0x8 25c21d: 83 0d 00 00 00 00 08 orl $0x8,0x0 25c224: eb dc jmp 25c202 <net_rx_action+0x59> 25c226: 8b 46 08 mov 0x8(%esi),%eax 25c229: a8 02 test $0x2,%al 25c22b: 75 4c jne 25c279 <net_rx_action+0xd0> 25c22d: 8b 06 mov (%esi),%eax 25c22f: 8b 56 04 mov 0x4(%esi),%edx 25c232: 89 50 04 mov %edx,0x4(%eax) 25c235: 89 02 mov %eax,(%edx) 25c237: a1 14 00 00 00 mov 0x14,%eax 25c23c: 89 35 14 00 00 00 mov %esi,0x14 25c242: c7 06 10 00 00 00 movl $0x10,(%esi) 25c248: 89 46 04 mov %eax,0x4(%esi) 25c24b: 89 30 mov %esi,(%eax) 25c24d: 29 ef sub %ebp,%edi 25c24f: eb a5 jmp 25c1f6 <net_rx_action+0x4d> 25c251: 8b 0d 10 8f 03 00 mov 0x38f10,%ecx 25c257: 85 c9 test %ecx,%ecx 25c259: 75 94 jne 25c1ef <net_rx_action+0x46> 25c25b: ba 71 09 00 00 mov $0x971,%edx 25c260: b8 89 6a 01 00 mov $0x16a89,%eax 25c265: e8 fc ff ff ff call 25c266 <net_rx_action+0xbd> 25c26a: c7 05 10 8f 03 00 01 movl $0x1,0x38f10 25c271: 00 00 00 25c274: e9 76 ff ff ff jmp 25c1ef <net_rx_action+0x46> 25c279: a8 01 test $0x1,%al 25c27b: 74 22 je 25c29f <net_rx_action+0xf6> 25c27d: 8b 16 mov (%esi),%edx 25c27f: 8b 46 04 mov 0x4(%esi),%eax 25c282: 89 42 04 mov %eax,0x4(%edx) 25c285: 89 10 mov %edx,(%eax) 25c287: c7 06 00 01 10 00 movl $0x100100,(%esi) 25c28d: c7 46 04 00 02 20 00 movl $0x200200,0x4(%esi) 25c294: 80 66 08 fe andb $0xfe,0x8(%esi) 25c298: 29 ef sub %ebp,%edi 25c29a: e9 57 ff ff ff jmp 25c1f6 <net_rx_action+0x4d> 25c29f: 0f 0b ud2a 25c2a1: eb fe jmp 25c2a1 <net_rx_action+0xf8> 3) 실제 C 코드.... static void net_rx_action(struct softirq_action *h) { struct list_head *list = &__get_cpu_var(softnet_data).poll_list; unsigned long start_time = jiffies; int budget = netdev_budget; void *have; local_irq_disable(); while (!list_empty(list)) { struct napi_struct *n; int work, weight; if (unlikely(budget <= 0 || jiffies != start_time)) goto softnet_break; local_irq_enable(); n = list_entry(list->next, struct napi_struct, poll_list); have = netpoll_poll_lock(n); weight = n->weight; work = 0; if (test_bit(NAPI_STATE_SCHED, &n->state)) work = n->poll(n, weight); WARN_ON_ONCE(work > weight); budget -= work; local_irq_disable(); if (unlikely(work == weight)) { if (unlikely(napi_disable_pending(n))) __napi_complete(n); else list_move_tail(&n->poll_list, list); } netpoll_poll_unlock(have); } out: local_irq_enable(); #ifdef CONFIG_NET_DMA if (!cpus_empty(net_dma.channel_mask)) { int chan_idx; for_each_cpu_mask_nr(chan_idx, net_dma.channel_mask) { struct dma_chan *chan = net_dma.channels[chan_idx]; if (chan) dma_async_memcpy_issue_pending(chan); } } #endif return; softnet_break: __get_cpu_var(netdev_rx_stat).time_squeeze++; __raise_softirq_irqoff(NET_RX_SOFTIRQ); goto out; }
Forums:
커널의 경우는 잘
커널의 경우는 잘 모르겠습니다만,
일반적인 프로그램의 경우 -g 옵션을 주어 디버깅한 경우에는
addr2line 유틸리티를 사용해서 알수 있기는 합니다.
도움얻고 싶다면
도움얻고 싶다면 에러메시지를 그대로 옮겨 적으시고,
공부를 하고 싶은 거라면 Documentation/oops-tracing.txt 와 scripts/ksymoops/README 에서 출발하세요.
OTL
음 ... 그거는...
커널을 Compile the kernel with debug info (CONFIG_DEBUG_INFO) 옵션을
enable 하신 후 build 하신 다음에요(커널 빌드 시 -g 옵션 추가하는 옵션)
objdump -S 을 이용하여 dump 하시면
dump 파일의 어셈코드에 일치하는 C 코드도 따라서 dump가 되요~~~
댓글 달기