Skip to content

Tracing và debug Linux kernel

Debug kernel khác debug ứng dụng ở chỗ kernel không có debugger bên ngoài tiến trình: khi kernel dừng thì cả hệ thống dừng, và khi kernel lỗi thì thường không còn công cụ nào chạy để quan sát. Vì vậy kernel có nhiều nhóm công cụ, mỗi nhóm phù hợp một giai đoạn của quá trình tìm lỗi. Trang này trình bày cách phân nhóm các công cụ, so sánh các nhóm theo mức can thiệp vào hệ thống, hướng dẫn chọn công cụ theo triệu chứng, rồi liệt kê các cấu hình kernel cần có sẵn trước khi debug. Chi tiết từng công cụ nằm ở các trang con.

Phân nhóm công cụ

Các công cụ được chia theo câu hỏi mà chúng trả lời, từ nhẹ nhất đến nặng nhất.

Nhóm Câu hỏi trả lời Công cụ Trang
Log Kernel đang báo gì printk, dmesg, dynamic debug printk và kernel log, Dynamic Debug
Tracing Kernel đang làm gì, theo thứ tự nào, mất bao lâu ftrace, kprobe, uprobe, tracepoint FTrace, Tracepoint và trace events
Chẩn đoán lỗi Lỗi xảy ra ở dòng code nào Oops, call trace, bộ phát hiện lỗi (KASAN, lockdep, kmemleak) Đọc Oops và Panic
Live debug Trạng thái biến và thanh ghi tại thời điểm dừng KGDB, kdb, JTAG KGDB và kdb, JTAG Debug
Post-mortem Trạng thái hệ thống ngay trước khi chết kdump, pstore và ramoops Kernel Crash Dump (kdump)

Ba nhóm đầu hoạt động khi kernel còn chạy bình thường và có thể dùng trên hệ thống đang vận hành. Live debug cần dừng kernel hoặc dừng CPU. Post-mortem chỉ có tác dụng sau khi lỗi đã xảy ra, nên phải cấu hình từ trước.

So sánh theo mức can thiệp

Tiêu chí Log Tracing Live debug bằng KGDB Live debug bằng JTAG Post-mortem
Dừng được kernel Không Không Có Có Không áp dụng
Cần phần cứng thêm Không Không Cổng serial hoặc mạng Bộ JTAG và kết nối tới SoC Vùng RAM dành riêng hoặc vùng lưu trữ
Dùng được khi kernel treo cứng Không Không Chỉ khi vẫn vào được debugger Có Có, nếu có cơ chế kích hoạt panic
Ảnh hưởng thời gian chạy Thấp đến trung bình, tùy lượng log Thấp khi tắt, tăng theo số event bật Nặng, hệ thống dừng khi vào debugger Nặng, CPU dừng khi gặp breakpoint Không ảnh hưởng khi chạy bình thường
Phù hợp với lỗi timing Thấp Cao Thấp Thấp Không áp dụng

Các mức "thấp", "cao" ở bảng là so sánh tương đối giữa các nhóm, không phải số đo. Mức ảnh hưởng thực tế phụ thuộc cấu hình và khối lượng event, nên cần đo lại trên hệ thống cụ thể trước khi dùng trong môi trường sản phẩm.

Chọn công cụ theo triệu chứng

Triệu chứng Bắt đầu bằng Bước tiếp theo
Driver không probe hoặc probe lỗi, chưa rõ nguyên nhân Dynamic debug cho driver đó, đọc log bằng dmesg FTrace với function tracer để xem luồng gọi
Kernel in oops hoặc panic Đọc Oops và Panic để giải mã call trace Bật bộ phát hiện lỗi nếu lỗi là hỏng bộ nhớ
Hệ thống treo, không in gì Bật watchdog và kdump để biến trạng thái treo thành panic JTAG nếu kernel không còn phản hồi
Cần biết hàm nào chiếm nhiều thời gian FTrace với function_graph hoặc perf Giới hạn bộ lọc về hàm nghi ngờ
Cần xem giá trị biến tại một điểm mà không sửa code Kprobe qua ftrace KGDB nếu cần dừng và xem nhiều biến
Cần step từng dòng trong kernel KGDB trên QEMU để làm quen KGDB trên board qua serial, hoặc JTAG
Lỗi chỉ xuất hiện trên thiết bị ngoài hiện trường Cấu hình pstore, ramoops và kdump từ trước Phân tích dump hoặc log thu được
Lỗi xảy ra rất sớm khi boot, chưa có console earlycon và initcall_debug, xem Log boot JTAG

Với phần lớn lỗi, thứ tự hợp lý là đi từ nhóm nhẹ đến nhóm nặng: đọc log, rồi trace để thu hẹp vùng nghi ngờ, rồi mới dùng live debug trên đoạn code đã xác định.

flowchart TD
    A[Có lỗi trên kernel] --> B{Kernel còn chạy}
    B -- Có --> C{Đã biết vùng code nghi ngờ}
    C -- Chưa --> D[Log và tracing để thu hẹp vùng]
    C -- Rồi --> E[Live debug hoặc kprobe trên vùng đó]
    B -- Không, có oops hoặc panic --> F[Đọc oops, giải mã call trace]
    B -- Không, treo không log --> G[kdump, watchdog hoặc JTAG]
    F --> H{Đủ dữ kiện}
    H -- Chưa --> I[kdump và phân tích bằng crash]

Cấu hình kernel cần có sẵn

Phần lớn công cụ trên yêu cầu bật cấu hình khi build kernel. Nếu thiếu thì phải build lại, nên cần quyết định trước khi triển khai.

Cấu hình Dùng cho
CONFIG_DEBUG_INFO Thông tin debug trong vmlinux, cần cho gdb, crash và giải mã địa chỉ về dòng code
CONFIG_KALLSYMS Tên symbol trong call trace và trong ftrace
CONFIG_DEBUG_FS Giao diện debugfs, nơi nhiều công cụ tạo file điều khiển
CONFIG_FTRACE và các tracer con ftrace, xem FTrace
CONFIG_DYNAMIC_DEBUG Dynamic debug, xem Dynamic Debug
CONFIG_KGDB KGDB và kdb, xem KGDB và kdb
CONFIG_CRASH_DUMP Cơ chế kdump, xem Kernel Crash Dump (kdump)

Danh sách đầy đủ và các tùy chọn đi kèm nằm ở từng trang con tương ứng.

Các trang có hậu tố (WIP) trong nav đã có chỗ đứng nhưng chưa có nội dung: eBPF và bpftrace, perf trong kernel, Đo độ trễ bằng tracing, Bộ phát hiện lỗi bộ nhớ và đồng bộ, Debug bộ nhớ kernel, Fault injection, debugfs và truy cập thanh ghi.

Liên quan

Tài liệu tham khảo