स्रोत कोड लाइनों के लिए कर्नेल स्टैक ट्रेस


20

नीचे दिए गए कर्नेल स्टैक ट्रेस को देखते हुए, आप कोड की विशिष्ट लाइन का निर्धारण कैसे करते हैं, जहां समस्या हुई थी?

kernel:  [<ffffffff80009a14>] __link_path_walk+0x173/0xfb9
kernel:  [<ffffffff8002cbec>] mntput_no_expire+0x19/0x89
kernel:  [<ffffffff8000eb94>] link_path_walk+0xa6/0xb2
kernel:  [<ffffffff80063c4f>] __mutex_lock_slowpath+0x60/0x9b
kernel:  [<ffffffff800238de>] __path_lookup_intent_open+0x56/0x97
kernel:  [<ffffffff80063c99>] .text.lock.mutex+0xf/0x14
kernel:  [<ffffffff8001b222>] open_namei+0xea/0x712
kernel:  [<ffffffff8006723e>] do_page_fault+0x4fe/0x874
kernel:  [<ffffffff80027660>] do_filp_open+0x1c/0x38
kernel:  [<ffffffff8001a061>] do_sys_open+0x44/0xbe
kernel:  [<ffffffff8005d28d>] tracesys+0xd5/0xe0

जबकि मुझे फंक्शन कॉल को खोजने में कोई परेशानी नहीं है - लेकिन __link_path_walk के साथ-साथ एक वास्तविक लाइन नंबर के लिए एक ऑफसेट का अनुवाद करना मुश्किल हिस्सा है।

यह मानते हुए कि यह एक मानक वितरण-प्रदान कर्नेल के लिए है जिसके लिए मुझे सटीक संस्करण और बिल्ड नंबर पता है, आवश्यक मेटाडेटा लाने और संबंधित लुकअप करने के लिए क्या प्रक्रिया है?

जवाबों:


12

vmlinuxडिबगिंग प्रतीकों के साथ एक अनस्ट्रिप्ड को देखते हुए (आमतौर पर "लाइनक्स-डेवेल" या "लाइनक्स-हेडर" आपके कर्नेल संस्करण से मेल खाते हुए पैकेज शामिल हैं), आप addr2lineस्रोत फ़ाइलों में पतों का अनुवाद करने के लिए बिनुटिल्स के साथ शामिल प्रोग्राम का उपयोग कर सकते हैं ।

इस कॉल ट्रेस पर विचार करें:

Call Trace:
 [<ffffffff8107bf5d>] ? finish_task_switch+0x3d/0x120
 [<ffffffff815f3130>] __schedule+0x3b0/0x9d0
 [<ffffffff815f3779>] schedule+0x29/0x70
 [<ffffffff815f2ccc>] schedule_hrtimeout_range_clock.part.24+0xdc/0xf0
 [<ffffffff81076440>] ? hrtimer_get_res+0x50/0x50
 [<ffffffff815f2c6f>] ? schedule_hrtimeout_range_clock.part.24+0x7f/0xf0
 [<ffffffff815f2cf9>] schedule_hrtimeout_range_clock+0x19/0x60
 [<ffffffff815f2d53>] schedule_hrtimeout_range+0x13/0x20
 [<ffffffff811a8aa9>] poll_schedule_timeout+0x49/0x70
 [<ffffffff811aa203>] do_sys_poll+0x423/0x550
 [<ffffffff814eaf8c>] ? sock_recvmsg+0x9c/0xd0
 [<ffffffff811a8c50>] ? poll_select_copy_remaining+0x140/0x140
 [<ffffffff811a8c50>] ? poll_select_copy_remaining+0x140/0x140
 [<ffffffff811a8c50>] ? poll_select_copy_remaining+0x140/0x140
 [<ffffffff811a8c50>] ? poll_select_copy_remaining+0x140/0x140
 [<ffffffff811a8c50>] ? poll_select_copy_remaining+0x140/0x140
 [<ffffffff811a8c50>] ? poll_select_copy_remaining+0x140/0x140
 [<ffffffff811a8c50>] ? poll_select_copy_remaining+0x140/0x140
 [<ffffffff811a8c50>] ? poll_select_copy_remaining+0x140/0x140
 [<ffffffff811a8c50>] ? poll_select_copy_remaining+0x140/0x140
 [<ffffffff811aa3fe>] SyS_poll+0x5e/0x100
 [<ffffffff816015d2>] system_call_fastpath+0x16/0x1b

फिर फोन करने वाले का poll_select_copy_remainingपता इसके साथ पाया जा सकता है:

$ addr2line -e /tmp/vmlinux ffffffff811a8c50
/tmp/linux-3.15-rc8/fs/select.c:209

मेरे आतंक स्टैक के निशान पूरे पते नहीं दिखाते हैं, केवल फंक + लाइन है। क्या इसे सक्षम करने के लिए कोई विन्यास है?
सिरो सेंटिल्ली 新疆 改造 iro i

1
@CiroSantilli 包子 露 ill ill 法轮功 could शायद आप उस बारे में एक नया प्रश्न पोस्ट कर सकते हैं? आपको अधिक जानकारी शामिल करनी होगी: आर्किटेक्चर (x86-64 / ARM / ...), लिनक्स वितरण, कर्नेल संस्करण और आउटपुट का एक नमूना जो कि आपकी अपेक्षा के अनुरूप नहीं है।
लेकेनस्टाइन

2
ठीक है, प्रतीक केवल तभी दिखाते हैं जब आपके पास होता है CONFIG_KALLSYMS: github.com/cirosantilli/linux-kernel-module-cheat/tree/…
Ciro Santilli 新疆 when when 六四 事件

15

मेरे पास हाथ में एक ~ = आरएचईएल 5 नहीं है, इसलिए दिखाया गया आउटपुट फेडोरा 20 से है, हालांकि यह प्रक्रिया ज्यादातर समान होनी चाहिए ( फ़ंक्शन का नाम बदल गया है )।

आपको kernel-debug-debuginfoअपने कर्नेल (RHEL या व्युत्पन्न डिस्ट्रो मानकर) के लिए उपयुक्त पैकेज स्थापित करना होगा । यह पैकेज एक vmlinuxछवि प्रदान करता है (कर्नेल का एक असम्पीडित छीन लिया गया संस्करण):

# rpm -ql kernel-debug-debuginfo | grep vmlinux
/usr/lib/debug/lib/modules/3.14.7-200.fc20.x86_64+debug/vmlinux

उस छवि को सीधे उपयोग किया जा सकता है gdb

# gdb /usr/lib/debug/lib/modules/3.14.7-200.fc20.x86_64+debug/vmlinux
GNU gdb (GDB) Fedora 7.7.1-13.fc20
Copyright (C) 2014 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
...
Reading symbols from /usr/lib/debug/lib/modules/3.14.7-200.fc20.x86_64+debug/vmlinux...done.
(gdb) disassemble link_path_walk
Dump of assembler code for function link_path_walk:
   0xffffffff81243d50 <+0>:     callq  0xffffffff817ea840 <__fentry__>
   0xffffffff81243d55 <+5>:     push   %rbp
   0xffffffff81243d56 <+6>:     mov    %rsp,%rbp
   0xffffffff81243d59 <+9>:     push   %r15
   0xffffffff81243d5b <+11>:    mov    %rsi,%r15
   0xffffffff81243d5e <+14>:    push   %r14
   0xffffffff81243d60 <+16>:    push   %r13
   0xffffffff81243d62 <+18>:    push   %r12
   0xffffffff81243d64 <+20>:    push   %rbx
   0xffffffff81243d65 <+21>:    mov    %rdi,%rbx
   0xffffffff81243d68 <+24>:    sub    $0x78,%rsp
   0xffffffff81243d6c <+28>:    mov    %gs:0x28,%rax
   0xffffffff81243d75 <+37>:    mov    %rax,0x70(%rsp)
   0xffffffff81243d7a <+42>:    xor    %eax,%eax
   0xffffffff81243d7c <+44>:    movzbl (%rdi),%eax
   0xffffffff81243d7f <+47>:    cmp    $0x2f,%al
   ....

आप छवि objdump(1)पर भी उपयोग कर सकते हैं vmlinux:

# objdump -rDlS /usr/lib/debug/lib/modules/3.14.7-200.fc20.x86_64+debug/vmlinux > vmlinux.out

झंडे हैं:

   -D
   --disassemble-all
       Like -d, but disassemble the contents of all sections, not just those expected to contain instructions.
   -r
   --reloc
       Print the relocation entries of the file.  If used with -d or -D, the relocations are printed interspersed with the
       disassembly.
   -S
   --source
       Display source code intermixed with disassembly, if possible.  Implies -d.
   -l
   --line-numbers
       Label the display (using debugging information) with the filename and source line numbers corresponding to the object
       code or relocs shown.  Only useful with -d, -D, or -r.

आप वहां फ़ंक्शन देख सकते हैं:

ffffffff81243d50 <link_path_walk>:
link_path_walk():
/usr/src/debug/kernel-3.14.fc20/linux-3.14.7-200.fc20.x86_64/fs/namei.c:1729
 *
 * Returns 0 and nd will have valid dentry and mnt on success.
 * Returns error and drops reference to input namei data on failure.
 */
static int link_path_walk(const char *name, struct nameidata *nd)
{
ffffffff81243d50:       e8 eb 6a 5a 00          callq  ffffffff817ea840 <__entry_text_start>
ffffffff81243d55:       55                      push   %rbp
ffffffff81243d56:       48 89 e5                mov    %rsp,%rbp
ffffffff81243d59:       41 57                   push   %r15
ffffffff81243d5b:       49 89 f7                mov    %rsi,%r15
ffffffff81243d5e:       41 56                   push   %r14
ffffffff81243d60:       41 55                   push   %r13
ffffffff81243d62:       41 54                   push   %r12
ffffffff81243d64:       53                      push   %rbx
ffffffff81243d65:       48 89 fb                mov    %rdi,%rbx
ffffffff81243d68:       48 83 ec 78             sub    $0x78,%rsp
ffffffff81243d6c:       65 48 8b 04 25 28 00    mov    %gs:0x28,%rax
ffffffff81243d73:       00 00
ffffffff81243d75:       48 89 44 24 70          mov    %rax,0x70(%rsp)
ffffffff81243d7a:       31 c0                   xor    %eax,%eax
/usr/src/debug/kernel-3.14.fc20/linux-3.14.7-200.fc20.x86_64/fs/namei.c:1733
        struct path next;
        int err;

        while (*name=='/')
ffffffff81243d7c:       0f b6 07                movzbl (%rdi),%eax
ffffffff81243d7f:       3c 2f                   cmp    $0x2f,%al
ffffffff81243d81:       75 10                   jne    ffffffff81243d93 <link_path_walk+0x43>
ffffffff81243d83:       0f 1f 44 00 00          nopl   0x0(%rax,%rax,1)
/usr/src/debug/kernel-3.14.fc20/linux-3.14.7-200.fc20.x86_64/fs/namei.c:1734
                name++;
ffffffff81243d88:       48 83 c3 01             add    $0x1,%rbx
/usr/src/debug/kernel-3.14.fc20/linux-3.14.7-200.fc20.x86_64/fs/namei.c:1733
static int link_path_walk(const char *name, struct nameidata *nd)
{
        struct path next;
        int err;

        while (*name=='/')
....

और कोड की वास्तविक रेखा से ऑफसेट का मिलान करें।


2
  1. कर्नेल-डिबगिनफो स्थापित करें
  2. डाउनलोड decode_stacktrace.sh जो कर्नेल सोर्स ट्री में है।
  3. स्टैक डंप आउटपुट को फिर से उपयोगी बनाएं।

    # ./decode_stacktrace.sh /usr/lib/debug/lib/modules/`uname -r`/vmlinux /usr/lib/debug/lib/modules/4.1.12-112.14.14.el7uek.x86_64/ < ./trace > out
    # cat out
    [102820.087367] Call Trace:
    [102820.087371] dump_stack (/usr/src/debug/kernel-4.1.12/linux-4.1.12-112.14.14.el7uek/lib/dump_stack.c:53)
    [102820.087375] warn_slowpath_common (/usr/src/debug/kernel-4.1.12/linux-4.1.12-112.14.14.el7uek/kernel/panic.c:499)
    [102820.087378] warn_slowpath_null (/usr/src/debug/kernel-4.1.12/linux-4.1.12-112.14.14.el7uek/kernel/panic.c:533)
    [102820.087380] af_alg_accept (/usr/src/debug/kernel-4.1.12/linux-4.1.12-112.14.14.el7uek/include/net/sock.h:1689 /usr/src/debug/kernel-4.1.12/linux-4.1.12-112.14.14.el7uek/crypto/af_alg.c:287)
    [102820.087382] alg_accept (/usr/src/debug/kernel-4.1.12/linux-4.1.12-112.14.14.el7uek/crypto/af_alg.c:326)
    [102820.087385] SYSC_accept4 (/usr/src/debug/kernel-4.1.12/linux-4.1.12-112.14.14.el7uek/net/socket.c:1485)
    [102820.087388] ? release_sock (/usr/src/debug/kernel-4.1.12/linux-4.1.12-112.14.14.el7uek/net/core/sock.c:2415)
    [102820.087390] ? alg_setsockopt (/usr/src/debug/kernel-4.1.12/linux-4.1.12-112.14.14.el7uek/crypto/af_alg.c:264)
    [102820.087393] SyS_accept (/usr/src/debug/kernel-4.1.12/linux-4.1.12-112.14.14.el7uek/net/socket.c:1515)
    [102820.087395] system_call_fastpath (/usr/src/debug////////kernel-4.1.12/linux-4.1.12-112.14.14.el7uek/arch/x86/kernel/entry_64.S:277)
    [102820.087397] ---[ end trace 1315ff0b8d6ff7d8 ]---
    

1

यदि addr2line को लाइन नंबर के लिए एक प्रश्न चिह्न प्रिंट करना चाहिए या objdump इनलाइन स्रोत कोड में विफल रहता है और आपके पास एक कस्टम कर्नेल है, तो CONFIG_DEBUG_INFO सेट के साथ कर्नेल को फिर से जोड़ना सुनिश्चित करें। आपको अभी बनाए गए कर्नेल के साथ त्रुटि को पुन: उत्पन्न करने की आवश्यकता हो सकती है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.