2011-02-09 60 views
39

Phương pháp và công cụ phổ biến nhất và không phổ biến nhất được sử dụng để thực hiện gỡ lỗi trực tiếp trên hạt nhân Linux là gì? Tôi biết rằng Linus cho ví dụ. là against loại gỡ lỗi này cho hạt nhân Linux hoặc ít nhất là và do đó không có gì nhiều được thực hiện theo nghĩa đó trong những năm đó, nhưng thành thật mà đã trôi qua kể từ năm 2000 và tôi quan tâm nếu tâm lý đó đã thay đổi liên quan đến Linux dự án và những gì các phương pháp hiện tại được sử dụng để làm gỡ lỗi trực tiếp trên hạt nhân Linux tại thời điểm này (hoặc địa phương hoặc từ xa)?Gỡ lỗi trực tiếp hạt nhân Linux, cách thực hiện và công cụ nào được sử dụng?

Tham khảo hướng dẫn và hướng dẫn về các kỹ thuật và công cụ được đề cập được hoan nghênh.

+1

Cũng xem lwn.net/Articles/280912 (tìm kiếm cho kgdb) –

+0

Ý anh là gì bởi * sống *? Bạn hiện đang chạy hoặc? Hoặc cũng là một trong một máy ảo? –

Trả lời

22

Một tùy chọn khác là sử dụng trình điều khiển ICE/JTAG và GDB.giải pháp 'phần cứng' Điều này đặc biệt sử dụng với các hệ thống nhúng,

nhưng ví dụ Qemu cung cấp tính năng tương tự:

  • bắt đầu qemu với gdb còn sơ khai 'từ xa' mà lắng nghe trên 'localhost: 1234': qemu -s ... ,

  • sau đó với GDB bạn mở tệp hạt nhân vmlinux được biên dịch với thông tin gỡ lỗi (bạn có thể xem một chuỗi danh sách gửi thư ở nơi họ thảo luận về việc không tối ưu hóa hạt nhân).

  • kết nối GDB và Qemu: target remote localhost:1234

  • thấy bạn sống kernel:

    (gdb) where 
    #0 cpu_v7_do_idle() at arch/arm/mm/proc-v7.S:77 
    #1 0xc0029728 in arch_idle() atarm/mach-realview/include/mach/system.h:36 
    #2 default_idle() at arm/kernel/process.c:166 
    #3 0xc00298a8 in cpu_idle() at arch/arm/kernel/process.c:199 
    #4 0xc00089c0 in start_kernel() at init/main.c:713 
    

không may, sử dụng không gian gỡ lỗi là không thể cho đến nay với GDB (không thông tin danh sách nhiệm vụ, không có lập trình lại MMU để xem các bối cảnh quy trình khác nhau, ...), nhưng nếu bạn ở trong không gian hạt nhân, thì đó là một cách khá thận trọng.

  • info threads sẽ cung cấp cho bạn danh sách và tiểu bang của CPU khác nhau

EDIT:

Bạn có thể biết thêm chi tiết về thủ tục trong PDF này:

Debugging Linux systems using GDB and QEMU .

+0

Tôi đã thử một cái gì đó tương tự như kỹ thuật này Qemu một số thời gian trước đây, nó khá mát mẻ. – Shinnok

19

Theo số wiki, kgdb được hợp nhất vào hạt nhân trong 2.6.26 trong vài năm qua. kgdbremote debugger, vì vậy, bạn activate it in your kernel thì bạn đính kèm gdb vào nó bằng cách nào đó. Tôi nói bằng cách nào đó vì dường như có rất nhiều lựa chọn - xem connecting gdb. Cho rằng kgdb hiện đang ở trong cây nguồn, tôi muốn nói về sau đây là những gì bạn muốn sử dụng.

Vì vậy, nó trông giống như Linus đã nhập. Tuy nhiên, tôi sẽ nhấn mạnh lập luận của mình - bạn nên biết những gì bạn đang làm và biết hệ thống tốt. Đây là vùng đất của hạt nhân. Nếu có điều gì sai, bạn không nhận được segfault, bạn sẽ nhận được bất kỳ điều gì từ một số vấn đề không rõ ràng sau này cho toàn bộ hệ thống bị hỏng. Đây là rồng. Tiến hành cẩn thận, bạn đã được cảnh báo.

+2

+1 cho rồng, làm cho nó âm thanh anh hùng hơn. :-D – Shinnok

+0

Tôi đã đánh cắp cái đó từ Mark Shuttleworth (người sáng lập Canonical). http://www.markshuttleworth.com/. –

+0

Linus là khá trên nhãn hiệu theo ý kiến ​​của tôi. Một điều khác cần xem xét là một số lỗi sẽ phá vỡ kgdb, có thể theo những cách tinh tế - bạn có thể tin tưởng nó không :) – mpe

11

Một công cụ tốt khác để gỡ lỗi "trực tiếp" là đầu dò kprobes/dynamic.

Điều này cho phép bạn xây dựng động các mô-đun nhỏ bé chạy khi một số địa chỉ nhất định được thực hiện - giống như một điểm ngắt.

Ưu điểm lớn trong số đó là:

  1. Họ không ảnh hưởng đến hệ thống - tức là khi một vị trí được đánh - nó chỉ excecutes mã - nó không ngăn chặn toàn bộ hạt nhân.
  2. Bạn không cần hai hệ thống khác nhau kết nối với nhau (mục tiêu và debug) giống như với kgdb

Nó là tốt nhất để làm những việc như đánh một breakpoint, và nhìn thấy những gì dữ liệu giá trị, hoặc kiểm tra nếu mọi thứ đã được thay đổi/ghi đè, vv Nếu bạn muốn "bước qua mã" - nó không làm điều đó.

4

Thực ra, trò đùa là Linux đã có trình gỡ lỗi trong hạt nhân kể từ 2.2.12, xmon, nhưng chỉ dành cho kiến ​​trúc powerpc (thực ra là sau đó là ppc).

Nó không phải là trình gỡ rối cấp nguồn và nó gần như hoàn toàn không có giấy tờ, nhưng vẫn còn.

http://lxr.linux.no/linux-old+v2.2.12/arch/ppc/xmon/xmon.c#L119

+1

"kdb" là x86 tương đương với "xmon". – Brad

3

Là một người viết mã hạt nhân rất nhiều tôi phải nói rằng tôi chưa bao giờ sử dụng kgdb, và hiếm khi sử dụng kprobes, vv

Nó vẫn thường là cách tiếp cận tốt nhất để ném vào một số chiến lược printks. Trong các hạt nhân gần đây hơn trace_printk là một cách hay để làm điều đó mà không cần spam dmesg.

-3

kgdb và gdb gần như là usel ess để gỡ lỗi hạt nhân vì mã được tối ưu hóa như vậy nó không có liên quan đến nguồn gốc và nhiều varuiables được tối ưu hóa. Điều này làm cho steppijng, do đó bước qua nguồn là không thể, kiểm tra các biến là không thể và do đó là cực điểm.

Thực ra nó tồi tệ hơn vô ích, nó thực sự cung cấp cho bạn thông tin sai lệch nên tách ra là mã bạn đang ollooking vào mã chạy thực tế.

Và không, bạn không thể tắt tối ưu hóa trong hạt nhân, nó không biên dịch.

Tôi phải nói, đến từ môi trường hạt nhân của cửa sổ, việc thiếu trình gỡ lỗi phong nha là anoying, cho rằng có mã rác ngoài đó để duy trì.

+0

Bạn thậm chí có nghe chính mình không? –

+0

tạo cấu hình ---> "Kernel hacking" -> "Compile-time checks and compiler options" -> "Biên dịch hạt nhân với thông tin gỡ lỗi" – Sergei

+0

Đó không phải là vấn đề với hạt nhân, nhưng bất kỳ chương trình nào được tạo bởi trình biên dịch tối ưu hóa đầy đủ. Đúng, hạt nhân Linux không thể dễ dàng được xây dựng mà không tối ưu hóa, nhưng bạn có thể kích hoạt CONFIG_READABLE_ASM. – rsaxvc

14

Trong khi gỡ lỗi hạt nhân Linux, chúng tôi có thể sử dụng nhiều công cụ, ví dụ, trình gỡ lỗi (KDB, KGDB), bán phá giá khi bị lỗi (LKCD), bộ công cụ truy tìm (LTT, LTTV, LTTng), công cụ hạt nhân tùy chỉnh (dprobes, kprobes). Trong phần sau tôi đã cố gắng tóm tắt hầu hết trong số họ, hy vọng những điều này sẽ giúp ích cho bạn.

Công cụ LKCD (Linux Kernel Crash Dump) cho phép hệ thống Linux ghi nội dung bộ nhớ khi xảy ra sự cố. Các bản ghi này có thể được phân tích thêm cho nguyên nhân gốc rễ của sự cố.Tài nguyên về LKCD

Rất tiếc khi hạt nhân phát hiện một vấn đề, nó in ra thông báo Rất tiếc. Một thông điệp như vậy được tạo ra bởi các câu lệnh printk trong trình xử lý lỗi (arch/*/kernel/traps.c). Một bộ đệm vòng chuyên dụng trong hạt nhân đang được sử dụng bởi các báo cáo printk. Rất tiếc có chứa thông tin như, CPU nơi Oops xảy ra trên, nội dung của thanh ghi CPU, số lượng Rất tiếc, mô tả, ngăn xếp lại dấu vết và những thứ khác. Tài nguyên liên quan đến hạt nhân Oops

Dynamic Probes là một trong những công cụ gỡ lỗi phổ biến cho Linux mà được phát triển bởi IBM. Công cụ này cho phép đặt một "đầu dò" ở hầu hết mọi nơi trong hệ thống, trong cả không gian người dùng và hạt nhân. Đầu dò bao gồm một số mã (được viết bằng ngôn ngữ chuyên dụng, theo định hướng ngăn xếp) được thực thi khi điều khiển chạm vào điểm đã cho. Tài nguyên về Probe động được liệt kê dưới đây

Linux Trace Toolkit là một bản vá hạt nhân và một bộ các tiện ích liên quan mà cho phép truy tìm của các sự kiện trong hạt nhân. Dấu vết bao gồm thông tin thời gian và có thể tạo ra một bức tranh hoàn chỉnh hợp lý về những gì đã xảy ra trong một khoảng thời gian nhất định. Nguồn lực của LTT, LTT Viewer và LTT Next Generation

MEMWATCH là một bộ nhớ nguồn công cụ phát hiện lỗi mở. Nó hoạt động bằng cách xác định MEMWATCH trong câu lệnh gcc và bằng cách thêm một tệp tiêu đề vào mã của chúng tôi. Thông qua điều này chúng ta có thể theo dõi rò rỉ bộ nhớ và bộ nhớ bị hỏng. Tài nguyên về MEMWATCH

ftrace là một khuôn khổ tracing tốt cho Linux kernel. ftrace dấu vết các hoạt động bên trong của hạt nhân. Công cụ này được bao gồm trong hạt nhân Linux trong 2.6.27. Với các plugin tracer khác nhau, ftrace có thể được nhắm vào các tracepoint tĩnh khác nhau, chẳng hạn như lên lịch sự kiện, ngắt, I/O ánh xạ bộ nhớ, chuyển đổi trạng thái nguồn CPU và các hoạt động liên quan đến hệ thống tệp và ảo hóa. Ngoài ra, theo dõi năng động của các cuộc gọi hàm hạt nhân có sẵn, tùy chọn hạn chế cho một tập con của các hàm bằng cách sử dụng các bóng tối, và với khả năng tạo ra các biểu đồ cuộc gọi và cung cấp mức sử dụng ngăn xếp.Bạn có thể tìm thấy hướng dẫn tốt về ftrace tại https://events.linuxfoundation.org/slides/2010/linuxcon_japan/linuxcon_jp2010_rostedt.pdf

ltrace là một tiện ích gỡ lỗi trong Linux, được sử dụng để hiển thị các cuộc gọi mà ứng dụng không gian người dùng thực hiện cho thư viện được chia sẻ. Công cụ này có thể được sử dụng để theo dõi bất kỳ cuộc gọi chức năng thư viện động nào. Nó chặn và ghi lại các cuộc gọi thư viện động được gọi bởi quá trình thực hiện và các tín hiệu được nhận bởi quá trình đó. Nó cũng có thể chặn và in các cuộc gọi hệ thống được thực hiện bởi chương trình.

KDB là debugger trong hạt nhân của hạt nhân Linux. KDB theo giao diện kiểu vỏ đơn giản. Chúng tôi có thể sử dụng nó để kiểm tra bộ nhớ, sổ đăng ký, danh sách quy trình, dmesg và thậm chí thiết lập các điểm dừng để dừng ở một vị trí nhất định. Thông qua KDB chúng ta có thể thiết lập các điểm ngắt và thực thi một số điều khiển chạy hạt nhân cơ bản (Mặc dù KDB không phải là trình gỡ rối mức nguồn). Một số nguồn ích về KDB

KGDB được thiết kế để được sử dụng như một trình gỡ lỗi cấp nguồn cho hạt nhân Linux. Nó được sử dụng cùng với gdb để gỡ lỗi hạt nhân Linux. Cần có hai máy để sử dụng kgdb. Một trong những máy này là máy phát triển và máy kia là máy mục tiêu. Hạt nhân được gỡ lỗi chạy trên máy mục tiêu. Kỳ vọng là gdb có thể được sử dụng để "đột nhập" vào hạt nhân để kiểm tra bộ nhớ, các biến và xem thông tin ngăn xếp cuộc gọi tương tự như cách một nhà phát triển ứng dụng sử dụng gdb để gỡ lỗi một ứng dụng. Có thể đặt các điểm ngắt trong mã hạt nhân và thực hiện một số bước thực hiện hạn chế. Một số nguồn ích về KGDB

3

qemu + GDB bước-by-step thủ tục thử nghiệm trên Ubuntu 16.10 chủ

Để bắt đầu từ đầu một cách nhanh chóng tôi đã thực hiện một tối thiểu Ví dụ QEMU + Buildroot hoàn toàn tự động tại: https://github.com/cirosantilli/linux-kernel-module-cheat Các bước chính được trình bày bên dưới.

Đầu tiên có hệ thống tệp gốc rootfs.cpio.gz.Nếu bạn cần một, xem xét:

Sau đó trên nhân Linux:

git checkout v4.9 
make mrproper 
make x86_64_defconfig 
cat <<EOF >.config-fragment 
CONFIG_DEBUG_INFO=y 
CONFIG_DEBUG_KERNEL=y 
CONFIG_GDB_SCRIPTS=y 
EOF 
./scripts/kconfig/merge_config.sh .config .config-fragment 
make -j"$(nproc)" 
qemu-system-x86_64 -kernel arch/x86/boot/bzImage \ 
        -initrd rootfs.cpio.gz -S -s 

Trên một thiết bị đầu cuối khác, giả sử bạn muốn bắt đầu gỡ lỗi từ start_kernel:

gdb \ 
    -ex "add-auto-load-safe-path $(pwd)" \ 
    -ex "file vmlinux" \ 
    -ex 'set arch i386:x86-64:intel' \ 
    -ex 'target remote localhost:1234' \ 
    -ex 'break start_kernel' \ 
    -ex 'continue' \ 
    -ex 'disconnect' \ 
    -ex 'set arch i386:x86-64' \ 
    -ex 'target remote localhost:1234' 

và chúng tôi đã hoàn tất !!

Đối với các module kernel xem: How to debug Linux kernel modules with QEMU?

Đối với Ubuntu 14.04, GDB 7.7.1, hbreak là cần thiết, break breakpoint phần mềm đã bị lờ đi. Không phải là trường hợp nữa trong 16.10. Xem thêm: https://bugs.launchpad.net/ubuntu/+source/qemu-kvm/+bug/901944

Các lộn xộn disconnect và những gì đến sau nó là để làm việc xung quanh lỗi:

Remote 'g' packet reply is too long: 000000000000000017d11000008ef4810120008000000000fdfb8b07000000000d352828000000004040010000000000903fe081ffffffff883fe081ffffffff00000000000e0000ffffffffffe0ffffffffffff07ffffffffffffffff9fffff17d11000008ef4810000000000800000fffffffff8ffffffffff0000ffffffff2ddbf481ffffffff4600000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007f0300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000801f0000 

chủ đề liên quan:

Xem thêm:

biết đến giới hạn:

0

KGDB + QEMU bước-by-step

KGDB là một hệ thống phụ kernel cho phép bạn bước gỡ lỗi hạt nhân chính nó từ một máy chủ GDB.

My dụ qemu + Buildroot là một cách tốt để có được một hương vị của nó mà không cần phần cứng thực: https://github.com/cirosantilli/linux-kernel-module-cheat/tree/1969cd6f8d30dace81d9848c6bacbb8bad9dacd8#kgdb

Ưu điểm và nhược điểm so với các phương pháp khác:

  • lợi thế vs qemu:
    • bạn thường không có mô phỏng phần mềm cho thiết bị của mình vì nhà cung cấp phần cứng không muốn phát hành các mô hình phần mềm chính xác cho thiết bị của họ
    • cách phần cứng thực nhanh hơn QEMU
  • lợi thế vs JTAG: không cần phần cứng JTAG thêm, dễ dàng hơn để thiết lập
  • nhược vs QEMU và JTAG: chưa tầm nhìn và xâm nhập hơn. KGDB dựa vào một số phần của hạt nhân làm việc để có thể giao tiếp với máy chủ. Vì vậy, ví dụ: nó phá vỡ trong hoảng loạn, bạn không thể xem trình tự khởi động.

Các bước chính là:

  1. Biên dịch hạt nhân với:

    CONFIG_DEBUG_KERNEL=y 
    CONFIG_DEBUG_INFO=y 
    
    CONFIG_CONSOLE_POLL=y 
    CONFIG_KDB_CONTINUE_CATASTROPHIC=0 
    CONFIG_KDB_DEFAULT_ENABLE=0x1 
    CONFIG_KDB_KEYBOARD=y 
    CONFIG_KGDB=y 
    CONFIG_KGDB_KDB=y 
    CONFIG_KGDB_LOW_LEVEL_TRAP=y 
    CONFIG_KGDB_SERIAL_CONSOLE=y 
    CONFIG_KGDB_TESTS=y 
    CONFIG_KGDB_TESTS_ON_BOOT=n 
    CONFIG_MAGIC_SYSRQ=y 
    CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE=0x1 
    CONFIG_SERIAL_KGDB_NMI=n 
    

    Hầu hết những người không bắt buộc, nhưng đây là những gì tôi đã được thử nghiệm.

  2. Thêm vào lệnh qemu của bạn:

    -append 'kgdbwait kgdboc=ttyS0,115200' \ 
    -serial tcp::1234,server,nowait 
    
  3. Run GDB với từ gốc của cây nguồn hạt nhân Linux với:

    gdb -ex 'file vmlinux' -ex 'target remote localhost:1234' 
    
  4. Trong GDB:

    (gdb) c 
    

    và khởi động sẽ kết thúc.

  5. Trong qemu:

    echo g > /proc/sysrq-trigger 
    

    Và GDB nên phá vỡ.

  6. Bây giờ chúng ta đang thực hiện, bạn có thể sử dụng GDB như thường lệ:

    b sys_write 
    c 
    

Tested trong Ubuntu 14.04.

KGDB + Raspberry Pi

Cùng thiết lập chính xác như trên hầu như làm việc trên một Raspberry Pi 2, Raspbian Jessie 2016/05/27.

Bạn chỉ cần phải học cách làm các bước qemu trên Pi, mà có thể dễ dàng Googlable:

  • thêm các tùy chọn cấu hình và biên dịch lại kernel như đã giải thích ở https://www.raspberrypi.org/documentation/linux/kernel/building.md tùy chọn có được không may mất tích trên xây dựng hạt nhân mặc định, đặc biệt là không có biểu tượng gỡ lỗi, do đó cần biên dịch lại.

  • chỉnh sửa cmdline.txt của phân vùng khởi động và thêm:

    kgdbwait kgdboc=ttyAMA0,115200 
    
  • kết nối gdb để nối tiếp với:

    arm-linux-gnueabihf-gdb -ex 'file vmlinux' -ex 'target remote /dev/ttyUSB0' 
    

    Nếu bạn không quen thuộc với sê-ri, hãy kiểm tra này: https://www.youtube.com/watch?v=da5Q7xL_OTo Tất cả những gì bạn cần là một bộ chuyển đổi giá rẻ like this one. Hãy chắc chắn rằng bạn có thể có được một vỏ thông qua nối tiếp để đảm bảo rằng nó đang làm việc trước khi thử ra KGDB.

  • làm:

    echo g | sudo tee /proc/sysrq-trigger 
    

    từ bên trong một phiên SSH, kể từ sê-ri đã được sử dụng bởi GDB.

Với thiết lập này, tôi có thể đặt điểm ngắt trong sys_write, tạm dừng thực thi chương trình, liệt kê nguồn và tiếp tục.

Tuy nhiên, đôi khi tôi đã làm next trong sys_write GDB chỉ treo và in thông báo lỗi này nhiều lần:

Ignoring packet error, continuing... 

vì vậy tôi không chắc chắn nếu có điều gì là sai với thiết lập của tôi, hoặc nếu điều này được dự kiến vì những gì một số quá trình nền đang làm trong hình ảnh Raspbian phức tạp hơn.

Tôi cũng đã được yêu cầu thử và tắt tính năng đa xử lý với tùy chọn khởi động Linux, nhưng tôi chưa thử.

0

chế độ tài Linux (UML)

https://en.wikipedia.org/wiki/User-mode_Linux

ảo hóa khác một phương pháp cho phép mã hạt nhân bước gỡ lỗi.

UML rất khéo léo: được thực hiện dưới dạng ARCH, giống như x86, nhưng thay vì sử dụng hướng dẫn cấp thấp, nó thực hiện các chức năng ARCH với các cuộc gọi hệ thống của người dùng.

Kết quả là bạn có thể chạy mã hạt nhân Linux dưới dạng quy trình người dùng trên máy chủ Linux!

Đầu tiên tạo một rootfs và chạy nó như thể hiện tại: https://unix.stackexchange.com/questions/73203/how-to-create-rootfs-for-user-mode-linux-on-fedora-18/372207#372207

Các um defconfig đặt CONFIG_DEBUG_INFO=y theo mặc định (Yup, đó là một điều phát triển), vì vậy chúng tôi cũng tốt.

On khách:

i=0 
while true; do echo $i; i=$(($i+1)); done 

Mở máy chủ trong vỏ khác:

ps aux | grep ./linux 
gdb -pid "$pid" 

Trong GDB:

break sys_write 
continue 
continue 

Và bây giờ bạn đang kiểm soát số lượng từ GDB, và có thể xem nguồn như mong đợi.

Ưu điểm:

  • chứa đầy đủ trong cây Linux kernel đường chính
  • hơn trọng lượng nhẹ hơn so với thi đua toàn bộ hệ thống QEMU của

Nhược điểm:

  • rất xâm lấn, vì nó thay đổi cách nhân được biên dịch.

    Nhưng API cấp cao hơn bên ngoài ARCH chi tiết cụ thể sẽ không thay đổi.

  • cho là không phải là rất tích cực: Is user mode linux (UML) project stopped?

Xem thêm: https://unix.stackexchange.com/questions/127829/why-would-someone-want-to-run-usermode-linux-uml

Các vấn đề liên quan