ftrace là một công cụ gỡ lỗi để hiểu những gì đang diễn ra bên trong hạt nhân Linux. Các phần sau đây trình bày chi tiết về chức năng ftrace cơ bản, cách sử dụng ftrace với atrace (ghi lại các sự kiện của kernel) và ftrace động.
Để biết thông tin chi tiết về chức năng ftrace nâng cao không có trong systrace, hãy tham khảo tài liệu về ftrace tại <kernel
tree>/Documentation/trace/ftrace.txt
.
Ghi lại sự kiện hạt nhân bằng atrace
atrace (frameworks/native/cmds/atrace
) sử dụng ftrace để ghi lại các sự kiện hạt nhân. Đổi lại, systrace.py (hoặc run_systrace.py trong các phiên bản Catapult sau này) sử dụng adb để chạy atrace trên thiết bị. atrace thực hiện những việc sau:
- Thiết lập tính năng theo dõi ở chế độ người dùng bằng cách đặt một thuộc tính (
debug.atrace.tags.enableflags
). - Bật chức năng ftrace mong muốn bằng cách ghi vào các nút sysfs ftrace thích hợp. Tuy nhiên, vì ftrace hỗ trợ nhiều tính năng hơn, bạn có thể tự đặt một số nút sysfs rồi sử dụng atrace.
Ngoại trừ tính năng theo dõi thời gian khởi động, hãy dựa vào việc sử dụng atrace để đặt thuộc tính thành giá trị thích hợp. Thuộc tính này là một mặt nạ bit và không có cách nào tốt để xác định giá trị chính xác ngoài việc xem tiêu đề thích hợp (có thể thay đổi giữa các bản phát hành Android).
Bật sự kiện ftrace
Các nút sysfs ftrace nằm trong /sys/kernel/tracing
và các sự kiện theo dõi được chia thành các danh mục trong /sys/kernel/tracing/events
.
Để bật sự kiện theo từng danh mục, hãy sử dụng:
echo 1 > /sys/kernel/tracing/events/irq/enable
Để bật sự kiện trên cơ sở từng sự kiện, hãy sử dụng:
echo 1 > /sys/kernel/tracing/events/sched/sched_wakeup/enable
Nếu bạn đã bật các sự kiện bổ sung bằng cách ghi vào các nút sysfs, thì các sự kiện đó sẽ không được đặt lại bằng atrace. Một mẫu phổ biến để khởi động thiết bị Qualcomm là bật các điểm theo dõi kgsl
(GPU) và mdss
(quy trình hiển thị), sau đó sử dụng atrace hoặc systrace:
adb shell "echo 1 > /sys/kernel/tracing/events/mdss/enable"
adb shell "echo 1 > /sys/kernel/tracing/events/kgsl/enable"
./systrace.py sched freq idle am wm gfx view binder_driver irq workq ss sync -t 10 -b 96000 -o full_trace.html
Bạn cũng có thể sử dụng ftrace mà không cần atrace hoặc systrace. Điều này rất hữu ích khi bạn chỉ muốn theo dõi hạt nhân (hoặc nếu bạn đã dành thời gian để viết thuộc tính theo dõi ở chế độ người dùng theo cách thủ công). Cách chỉ chạy ftrace:
- Đặt kích thước bộ đệm thành một giá trị đủ lớn cho dấu vết của bạn:
echo 96000 > /sys/kernel/tracing/buffer_size_kb
- Bật tính năng theo dõi:
echo 1 > /sys/kernel/tracing/tracing_on
- Chạy kiểm thử, sau đó tắt tính năng theo dõi:
echo 0 > /sys/kernel/tracing/tracing_on
- Kết xuất dấu vết:
cat /sys/kernel/tracing/trace > /data/local/tmp/trace_output
trace_output cung cấp dấu vết ở dạng văn bản. Để trực quan hoá dữ liệu này bằng Catapult, hãy lấy kho lưu trữ Catapult từ GitHub và chạy trace2html:
catapult/tracing/bin/trace2html ~/path/to/trace_file
Theo mặc định, thao tác này sẽ ghi trace_file.html
trong cùng thư mục.
Liên kết sự kiện
Bạn thường nên xem đồng thời hình ảnh trực quan của Catapult và nhật ký ftrace; ví dụ: một số sự kiện ftrace (đặc biệt là các sự kiện dành riêng cho nhà cung cấp) không được Catapult trực quan hoá. Tuy nhiên, dấu thời gian của Catapult tương ứng với sự kiện đầu tiên trong dấu vết hoặc với một dấu thời gian cụ thể do atrace kết xuất, trong khi dấu thời gian ftrace thô dựa trên một nguồn đồng hồ tuyệt đối cụ thể trong nhân Linux.
Cách tìm một sự kiện ftrace nhất định từ một sự kiện Catapult:
- Mở nhật ký ftrace thô. Theo mặc định, các dấu vết trong các phiên bản systrace gần đây sẽ được nén:
- Nếu bạn đã ghi lại systrace bằng
--no-compress
, thì tệp này sẽ nằm trong tệp html ở phần bắt đầu bằng BEGIN TRACE (BẮT ĐẦU THEO DÕI). - Nếu không, hãy chạy html2trace từ cây Catapult (
tracing/bin/html2trace
) để giải nén dấu vết.
- Nếu bạn đã ghi lại systrace bằng
- Tìm dấu thời gian tương đối trong hình ảnh trực quan của Catapult.
- Tìm một dòng ở đầu dấu vết chứa
tracing_mark_sync
. Hàm này có dạng như sau:<5134>-5134 (-----) [003] ...1 68.104349: tracing_mark_write: trace_event_clock_sync: parent_ts=68.104286
Nếu dòng này không tồn tại (hoặc nếu bạn đã sử dụng ftrace mà không có atrace), thì thời gian sẽ tương ứng với sự kiện đầu tiên trong nhật ký ftrace.- Thêm dấu thời gian tương đối (tính bằng mili giây) vào giá trị trong
parent_ts
(tính bằng giây). - Tìm dấu thời gian mới.
- Thêm dấu thời gian tương đối (tính bằng mili giây) vào giá trị trong
Sau khi thực hiện các bước này, bạn sẽ có mặt tại sự kiện (hoặc ít nhất là ở rất gần sự kiện).
Sử dụng ftrace động
Khi systrace và ftrace tiêu chuẩn không đủ, bạn có thể sử dụng một biện pháp cuối cùng: ftrace động. Ftrace động liên quan đến việc viết lại mã nhân sau khi khởi động, do đó, tính năng này không có trong nhân phát hành chính thức vì lý do bảo mật. Tuy nhiên, mọi lỗi hiệu suất khó khăn trong năm 2015 và 2016 đều bắt nguồn từ việc sử dụng ftrace động. Tính năng này đặc biệt mạnh mẽ trong việc gỡ lỗi chế độ ngủ không thể gián đoạn vì bạn có thể nhận được dấu vết ngăn xếp trong nhân mỗi khi nhấn vào hàm kích hoạt chế độ ngủ không thể gián đoạn. Bạn cũng có thể gỡ lỗi các phần bị vô hiệu hoá các hoạt động ngắt và can thiệp. Điều này có thể rất hữu ích để chứng minh các vấn đề.
Để bật ftrace động, hãy chỉnh sửa defconfig của hạt nhân:
- Xoá CONFIG_STRICT_MEMORY_RWX (nếu có). Nếu bạn đang sử dụng phiên bản 3.18 trở lên và arm64, thì bạn sẽ không thấy phiên bản này.
- Thêm các tuỳ chọn sau: CONFIG_DYNAMIC_FTRACE=y, CONFIG_FUNCTION_TRACER=y, CONFIG_IRQSOFF_TRACER=y, CONFIG_FUNCTION_PROFILER=y và CONFIG_PREEMPT_TRACER=y
- Tạo lại và khởi động hạt nhân mới.
- Chạy mã sau để kiểm tra các trình theo dõi có sẵn:
cat /sys/kernel/tracing/available_tracers
- Xác nhận lệnh trả về
function
,irqsoff
,preemptoff
vàpreemptirqsoff
. - Chạy các lệnh sau để đảm bảo ftrace động đang hoạt động:
cat /sys/kernel/tracing/available_filter_functions | grep <a function you care about>
Sau khi hoàn tất các bước này, bạn sẽ có ftrace động, trình phân tích tài nguyên hàm, trình phân tích tài nguyên irqsoff và trình phân tích tài nguyên preemptoff. Bạn nên đọc tài liệu về ftrace về các chủ đề này trước khi sử dụng vì chúng rất mạnh mẽ nhưng phức tạp. irqsoff và preemptoff chủ yếu hữu ích để xác nhận rằng trình điều khiển có thể đang tắt các hoạt động ngắt hoặc chiếm quyền ưu tiên quá lâu.
Trình phân tích hàm là lựa chọn tốt nhất cho các vấn đề về hiệu suất và thường được dùng để tìm ra vị trí gọi hàm.
Nếu dữ liệu từ trình phân tích tài nguyên hàm không đủ cụ thể, bạn có thể kết hợp các điểm theo dõi ftrace với trình phân tích tài nguyên hàm. Bạn có thể bật các sự kiện ftrace theo cách giống hệt như bình thường và các sự kiện này sẽ được xen kẽ với dấu vết của bạn.
Điều này rất hữu ích nếu thỉnh thoảng có một giấc ngủ dài không thể gián đoạn trong một hàm cụ thể mà bạn muốn gỡ lỗi: đặt bộ lọc ftrace thành hàm bạn muốn, bật điểm theo dõi, theo dõi. Bạn có thể phân tích cú pháp dấu vết thu được bằng trace2html
, tìm sự kiện bạn muốn, sau đó lấy dấu vết ngăn xếp lân cận trong dấu vết thô.
Sử dụng lockstat
Đôi khi, ftrace là không đủ và bạn thực sự cần gỡ lỗi những gì có vẻ là tranh chấp khoá hạt nhân. Còn một tuỳ chọn nhân khác đáng thử: CONFIG_LOCK_STAT
. Đây là phương án cuối cùng vì rất khó để hoạt động trên các thiết bị Android do phương thức này làm tăng kích thước của hạt nhân vượt quá mức mà hầu hết các thiết bị có thể xử lý.
Tuy nhiên, lockstat sử dụng cơ sở hạ tầng khoá gỡ lỗi, rất hữu ích cho nhiều ứng dụng khác. Mọi người làm việc về việc khởi động thiết bị đều phải tìm ra cách để tuỳ chọn đó hoạt động trên mọi thiết bị vì sẽ có lúc bạn nghĩ rằng "Giá như tôi có thể bật LOCK_STAT
, tôi có thể xác nhận hoặc bác bỏ vấn đề này trong vòng 5 phút thay vì 5 ngày".
Nếu bạn có thể khởi động hạt nhân bằng tuỳ chọn cấu hình, thì tính năng theo dõi khoá sẽ tương tự như ftrace:
- Bật tính năng theo dõi:
echo 1 > /proc/sys/kernel/lock_stat
- Chạy kiểm thử.
- Tắt tính năng theo dõi:
echo 0 > /proc/sys/kernel/lock_stat
- Kết xuất dấu vết:
cat /proc/lock_stat > /data/local/tmp/lock_stat
Để được trợ giúp về cách diễn giải kết quả, hãy tham khảo tài liệu về lockstat tại <kernel>/Documentation/locking/lockstat.txt
.
Sử dụng điểm theo dõi của nhà cung cấp
Trước tiên, hãy sử dụng các điểm theo dõi ngược dòng, nhưng đôi khi bạn sẽ cần sử dụng các điểm theo dõi của nhà cung cấp:
{ "gfx", "Graphics", ATRACE_TAG_GRAPHICS, { { OPT, "events/mdss/enable" }, { OPT, "events/sde/enable" }, { OPT, "events/mali_systrace/enable" }, } },
Điểm theo dõi có thể mở rộng bằng dịch vụ HAL, cho phép bạn thêm điểm/danh mục theo dõi cụ thể cho thiết bị. Điểm theo dõi được tích hợp với perfetto, atrace/systrace và ứng dụng theo dõi hệ thống trên thiết bị.
Các API để triển khai điểm theo dõi/danh mục là:
- listCategories()tạo (vec<TracingCategory> danh mục);
- enableCategories(vec<string> categories) tạo ra (Status status);
- disableAllCategories() tạo ra (Trạng thái trạng thái);