Sử dụng ftrace

ftrace là một công cụ gỡ lỗi để hiểu những gì đang diễn ra bên trong nhân Linux. Các phần sau đây mô tả chi tiết 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 kernel) và ftrace động.

Để biết chi tiết về chức năng ftrace nâng cao không có sẵn từ systrace, hãy tham khảo tài liệu ftrace tại <kernel tree>/Documentation/trace/ftrace.txt .

Ghi lại các sự kiện kernel bằng atrace

atrace ( frameworks/native/cmds/atrace ) sử dụng ftrace để ghi lại các sự kiện kernel. Đổi lại, systrace.py (hoặc run_systrace.py trong các phiên bản sau của Catapult ) sử dụng adb để chạy atrace trên thiết bị. atrace thực hiện như sau:

  • Thiết lập theo dõi chế độ người dùng bằng cách đặt thuộc tính ( debug.atrace.tags.enableflags ).
  • Kích hoạ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 nên bạn có thể tự thiết lập một số nút sysfs sau đó sử dụng atrace.

Ngoại trừ việc 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 là 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).

Kích hoạt sự kiện ftrace

Các nút sysfs ftrace nằm trong /sys/kernel/tracing và các sự kiện trace được chia thành các danh mục trong /sys/kernel/tracing/events .

Để bật các sự kiện trên cơ sở từng danh mục, hãy sử dụng:

echo 1 > /sys/kernel/tracing/events/irq/enable

Để bật các 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 các sự kiện bổ sung đã được kích hoạt bằng cách ghi vào các nút sysfs, chúng sẽ không được đặt lại bởi atrace. Một mẫu phổ biến để mang lại thiết bị Qualcomm là bật các điểm theo dõi kgsl (GPU) và mdss (đường dẫn 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 kernel (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 bằng tay). Để chạy chỉ ftrace:

  1. Đặt kích thước bộ đệm thành giá trị đủ lớn cho dấu vết của bạn:
    echo 96000 > /sys/kernel/tracing/buffer_size_kb
    
  2. Kích hoạt tính năng theo dõi:
    echo 1 > /sys/kernel/tracing/tracing_on
    
  3. Chạy thử nghiệm của bạn, sau đó tắt tính năng theo dõi:
    echo 0 > /sys/kernel/tracing/tracing_on
    
  4. 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 hóa nó 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, điều này ghi trace_file.html vào cùng thư mục.

Sự kiện tương quan

Việc xem xét trực quan hóa Catapult và nhật ký ftrace cùng một lúc thường rất hữu ích; 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 hiển thị. Tuy nhiên, dấu thời gian của Catapult có liên quan đến sự kiện đầu tiên trong dấu vết hoặc với 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 nguồn đồng hồ tuyệt đối cụ thể trong nhân Linux.

Để tìm một sự kiện ftrace nhất định từ sự kiện Catapult:

  1. Mở nhật ký ftrace thô. Dấu vết trong các phiên bản gần đây của systrace được nén theo mặc định:
    • Nếu bạn đã chụp systrace của mình bằng --no-compress , thì đây là tệp html trong phần bắt đầu bằng BEGIN TRACE.
    • Nếu không, hãy chạy html2trace từ cây Catapult ( tracing/bin/html2trace ) để giải nén dấu vết.
  2. Tìm dấu thời gian tương đối trong trực quan hóa Catapult.
  3. Tìm dòng ở đầu dấu vết chứa tracing_mark_sync . Nó sẽ trông giống như thế này:
    <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 đối so với sự kiện đầu tiên trong nhật ký ftrace.
    1. Thêm dấu thời gian tương đối (tính bằng mili giây) vào giá trị tính bằng parent_ts (tính bằng giây).
    2. Tìm kiếm dấu thời gian mới.

Những bước này sẽ đưa bạn đế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 đủ, sẽ có một giải pháp cuối cùng: năng động ftrace . Dynamic ftrace liên quan đến việc viết lại mã hạt nhân sau khi khởi động và kết quả là nó không có sẵn trong hạt nhân sản xuất vì lý do bảo mật. Tuy nhiên, mọi lỗi khó khăn về hiệu suất trong năm 2015 và 2016 cuối cùng đều có nguyên nhân gốc rễ bằng cách sử dụng ftrace động. Nó đặc biệt mạnh mẽ trong việc gỡ lỗi các chế độ ngủ không bị gián đoạn vì bạn có thể nhận được dấu vết ngăn xếp trong kernel mỗi khi bạn nhấn chức năng kích hoạt chế độ ngủ không bị gián đoạn. Bạn cũng có thể gỡ lỗi các phần bị vô hiệu hóa các ngắt và ưu tiên, điều này có thể rất hữu ích cho việc chứng minh vấn đề.

Để bật ftrace động, hãy chỉnh sửa cấu hình mặc định của kernel:

  1. Xóa CONFIG_STRICT_MEMORY_RWX (nếu có). Nếu bạn đang dùng phiên bản 3.18 trở lên và arm64 thì nó không có ở đó.
  2. Thêm các mục sau: CONFIG_DYNAMIC_FTRACE=y, CONFIG_FUNCTION_TRACER=y, CONFIG_IRQSOFF_TRACER=y, CONFIG_FUNCTION_PROFILER=y và CONFIG_PREEMPT_TRACER=y
  3. Xây dựng lại và khởi động kernel mới.
  4. Chạy phần sau để kiểm tra các công cụ theo dõi có sẵn:
    cat /sys/kernel/tracing/available_tracers
    
  5. Xác nhận lệnh trả về function , irqsoff , preemptoffpreemptirqsoff .
  6. Chạy phần 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 thành các bước này, bạn có sẵn ftrace động, trình phân tích hàm, trình phân tích irqsoff và trình phân tích ưu tiên. Chúng tôi thực sự khuyên bạn nên đọc tài liệu ftrace về các chủ đề này trước khi sử dụng chúng vì chúng mạnh mẽ nhưng phức tạp. irqsoff và preemptoff chủ yếu hữu ích trong việc xác nhận rằng trình điều khiển có thể tắt chế độ ngắt hoặc ưu tiên quá lâu.

Trình lược tả hàm là tùy chọn tốt nhất cho các vấn đề về hiệu suất và thường được sử dụng để tìm ra vị trí của hàm được gọi.


Nếu dữ liệu từ trình lược tả 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 lược tả hàm. Các sự kiện ftrace có thể được kích hoạt theo cách giống hệt như bình thường và chúng sẽ được xen kẽ với dấu vết của bạn. Điều này thật tuyệt nếu thỉnh thoảng có một chế độ ngủ kéo dài không bị gián đoạn trong một chức năng cụ thể mà bạn muốn gỡ lỗi: đặt bộ lọc ftrace thành chức năng 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 kết quả 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 phải gỡ lỗi những gì có vẻ là xung đột khóa kernel. Có thêm một tùy chọn kernel đáng thử: CONFIG_LOCK_STAT . Đây là giải pháp cuối cùng vì rất khó để hoạt động trên thiết bị Android vì nó 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 khóa gỡ lỗi, rất hữu ích cho nhiều ứng dụng khác. Mọi người làm việc trong quá trình nâng cấp thiết bị nên tìm ra cách nào đó để tùy chọn đó hoạt động trên mọi thiết bị vì sẽ có lúc bạn nghĩ "Giá như tôi có thể bật LOCK_STAT thì tôi có thể xác nhận hoặc bác bỏ vấn đề này trong vòng năm phút thay vì Năm ngày."


Nếu bạn có thể khởi động kernel bằng tùy chọn cấu hình, việc theo dõi khóa tương tự như ftrace:

  1. Kích hoạt tính năng theo dõi:
    echo 1 > /proc/sys/kernel/lock_stat
    
  2. Chạy thử nghiệm của bạn.
  3. Vô hiệu hóa theo dõi:
    echo 0 > /proc/sys/kernel/lock_stat
    
  4. Xóa dấu vết của bạn:
    cat /proc/lock_stat > /data/local/tmp/lock_stat
    

Để được trợ giúp diễn giải kết quả đầu ra, hãy tham khảo tài liệu lockstat tại <kernel>/Documentation/locking/lockstat.txt .

Sử dụng dấu vết của nhà cung cấp

Trước tiên hãy sử dụng điểm theo dõi ngược dòng, nhưng đôi khi bạn sẽ cần sử dụng đ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 các điểm/danh mục theo dõi cụ thể của thiết bị. Tracepoint đượ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/danh mục theo dõi là:

  • listCategories() tạo ra (vec<TracingCategory> danh mục);
  • EnableCategories(vec<string> Category) tạo ra (Trạng thái trạng thái);
  • vô hiệu hóaAllCategories() tạo ra (Trạng thái trạng thái);
Để biết thêm thông tin, hãy tham khảo định nghĩa HAL và cách triển khai mặc định trong AOSP :