리눅스 커널메시지를 이용해서 "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가 되요~~~
댓글 달기