Hướng dẫn này cung cấp thông tin tổng quan về các công cụ và kỹ thuật thiết yếu để gỡ lỗi các dịch vụ và ứng dụng chạy trên nền tảng SDV.
Kết nối với thiết bị
Công cụ chính để kết nối và tương tác với thiết bị là Cầu gỡ lỗi Android (adb). Hãy xác minh rằng adb nằm trong đường dẫn của hệ thống.
Kết nối bằng mạng
Nếu thiết bị nằm trên cùng một mạng và bạn biết địa chỉ IP của thiết bị đó, bạn có thể kết nối bằng Ethernet. Hệ thống của chúng tôi chỉ sử dụng các kết nối mạng cho adb:
# Connect to the device using its IP address and default port
adb connect <device_ip_address>:5555
Kết nối với nhiều thiết bị
Để quản lý nhiều thiết bị từ một máy trạm, bạn có thể kết nối với các thiết bị đó thông qua nhiều địa chỉ IP. Nếu chạy nhiều máy ảo trên một máy chủ, bạn cần chỉ định các cổng khác nhau cho từng thiết bị. Bạn cần định cấu hình trình nền adb trên từng thiết bị SDV để nghe trên một cổng riêng biệt, ví dụ: 5555 cho thiết bị đầu tiên và 5556 cho thiết bị thứ hai. Bạn cũng có thể định cấu hình máy chủ để chuyển tiếp các cổng đó đến các khách khác nhau:
# Connect to the first device
adb connect <device_1_ip_address>:5555
# Connect to a second device
adb connect <device_2_ip_address>:5555
# Connect to a second VM on first device on different port
adb connect <device_1_ip_address>:5556
# List all connected devices to verify
adb devices
Khi chạy các lệnh adb tiếp theo, bạn có thể nhắm đến một thiết bị cụ thể bằng cách sử dụng cờ -s với địa chỉ đầy đủ (ip:port):
# Run a shell command on the second VM on first device in the above example
adb -s <device_1_ip_address>:5556 shell
Xem nhật ký
Khi một dịch vụ gặp lỗi hoặc hoạt động không như mong đợi, trước tiên hãy kiểm tra nhật ký.
Sử dụng logcat (nhật ký Android)
logcat hiển thị nhật ký từ các dịch vụ hệ thống, tác nhân và gói dịch vụ:
# View all logs in real-time
adb logcat
# Filter logs by a specific tag (e.g., the name of your service)
adb logcat -s MyServiceTag
# Filter logs by priority (V: Verbose, D: Debug, I: Info, W: Warn, E: Error, F: Fatal)
# This shows only Error and Fatal messages for a specific tag
adb logcat MyServiceTag:E *:S
# Clear old logs before viewing new ones
adb logcat -c && adb logcat
# Show all logs and return
adb logcat -d
# Color logs by level
adb logcat -v color
# Show timestamps as time since boot
adb logcat -v monotonic
Sử dụng dmesg (nhật ký kernel)
dmesg hiển thị nhật ký từ kernel Linux. Điều này rất quan trọng để gỡ lỗi những vấn đề sau:
- Các vấn đề về phần cứng và trình điều khiển
- Lỗi kernel
- Lỗi SELinux (
avc: denied) – cũng xuất hiện trong logcat
# View all kernel messages
adb shell dmesg
# Follow kernel messages in real-time
adb shell dmesg -w
Truy cập nhật ký trên Cuttlefish
Khi chạy trên một thiết bị ảo Cuttlefish, bạn có thể truy cập trực tiếp vào các tệp nhật ký từ hệ thống tệp của máy chủ. Điều này đặc biệt hữu ích nếu adb không dùng được. Khi bạn khởi động Cuttlefish, hệ thống sẽ xuất tất cả các đường dẫn gỡ lỗi và bạn cũng có thể tra cứu các đường dẫn đó bằng cách sử dụng cvd fleet cho tất cả các thực thể đang chạy.
- Logcat (nhật ký Android):
cuttlefish/instances/cvd-1/logs/logcat - Nhật ký kernel:
cuttlefish/instances/cvd-1/logs/kernel.log - Nhật ký trình chạy Cuttlefish:
cuttlefish/instances/cvd-1/logs/launcher.log(hữu ích cho việc gỡ lỗi chính môi trường Cuttlefish)
Bạn có thể sử dụng các công cụ dòng lệnh tiêu chuẩn như cat, less hoặc tail -f để xem các tệp này trong thời gian thực.
Tương tác với shell và hệ thống tệp
Truy cập vào shell để chạy các lệnh trực tiếp trên thiết bị, kiểm tra trạng thái quy trình và di chuyển trong hệ thống tệp:
# Open an interactive shell on the device
adb shell
# From within the shell, you can check running processes
ps -A
# Or check the status of a specific service managed by init
getprop init.svc.<service_name>
Thực hiện các thao tác trên hệ thống tệp
Sử dụng adb push và adb pull để di chuyển tệp giữa máy chủ và thiết bị. Sử dụng lệnh này để triển khai tập lệnh kiểm thử, cập nhật cấu hình hoặc truy xuất kết xuất sự cố:
# Push a file from your computer to the device
adb push my_local_file.txt /data/local/tmp/
# Pull a file from the device to your computer
adb pull /data/tombstones/tombstone_00 .
Gỡ lỗi ứng dụng (C++/Rust)
Bạn có thể gỡ lỗi ứng dụng ở chế độ trực tuyến hoặc ngoại tuyến.
Sử dụng lldb để gỡ lỗi trực tiếp
lldb là trình gỡ lỗi mặc định trong Android Studio và thường được ưu tiên cho quá trình phát triển C++ và Rust hiện đại.
Hãy làm theo các bước thiết lập sau:
Khởi động lại adb để cho phép quyền root (bắt buộc để chuyển tiếp). Sử dụng lệnh này để thiết lập tính năng chuyển tiếp cổng. Trên máy chủ, hãy chạy:
adb rootNếu một tệp nhị phân có biểu tượng gỡ lỗi, hãy đẩy một phiên bản chưa được loại bỏ. Bạn có thể tìm thấy phiên bản chưa được loại bỏ trong
out/target/product/[SDV_FLAVOR]/symbols/[PARTITION]/bin/[EXECUTABLE]. Ví dụ: để tảirpcagentlên từsystem_extvàsdv_core_cf, hãy chạy:adb push out/target/product/sdv_core_cf/symbols/system_ext/bin/rpcagent /data/local/tmpPhiên bản chưa được loại bỏ hiện nằm trong
/data/local/tmp.Kết nối với ứng dụng LLDB bằng tập lệnh tiện lợi
lldbclient.py:# Run and connect a binary on device, run on host: lldbclient.py -r /data/local/tmp/rpcagent # Connect to an existing process with PID 2759 lldbclient.py -p 2759Tập lệnh này kết nối lldb từ xa. Để xem tất cả các cờ hiện có, hãy chạy
lldbclient.py. Tham khảo tài liệu về IDE để kết nối IDE với lldb.
Phân tích kết xuất sự cố (tombstone)
Khi một dịch vụ gặp sự cố, một tệp tombstone sẽ được tạo trong /data/tombstones/.
Tệp này chứa dấu vết ngăn xếp, bản đồ bộ nhớ và các thông tin quan trọng khác.
Kéo tệp tombstone, sau đó sử dụng một công cụ nhận biết biểu tượng (như lldb hoặc một tập lệnh chuyên dụng) để phân tích tệp đó bằng phiên bản chưa được loại bỏ của tệp nhị phân.
Phân tích hiệu suất
SDV hỗ trợ nhiều công cụ đo lường hiệu suất.
Kiểm tra mức sử dụng CPU và bộ nhớ
top: Cung cấp chế độ xem theo thời gian thực về các quy trình đang chạy được sắp xếp theo mức sử dụng CPU.adb shell top -m 10 # Show top 10 processesprocrank: Cung cấp bảng chi tiết về mức sử dụng bộ nhớ cho một quy trình cụ thể hoặc toàn bộ hệ thống.adb shell procrank
Sử dụng dumpsys cho trạng thái dịch vụ
dumpsys là một công cụ mạnh mẽ để truy vấn trạng thái nội bộ của bất kỳ dịch vụ hệ thống Android nào.
# List all available services
adb shell dumpsys -l
# Dump the state of a specific service or agent
adb shell dumpsys <service_name>
Sử dụng torq để phân tích hiệu suất
torq là một công cụ dòng lệnh giúp đơn giản hoá các tác vụ phân tích và theo dõi trên Android. Công cụ này cho phép chạy Simpleperf, Perfetto và các tác vụ thông thường khác trong quá trình phân tích hiệu suất hệ thống.
Sử dụng Perfetto để theo dõi
Perfetto là công cụ tiêu chuẩn để theo dõi trên toàn hệ thống trên Android. Perfetto cho phép bạn ghi lại các sự kiện hệ thống, điểm theo dõi ở cấp ứng dụng và bộ đếm hiệu suất, đồng thời trực quan hoá các sự kiện đó trên dòng thời gian.
Các bước chính:
- Thêm điểm theo dõi vào mã C++ hoặc Rust:
- C++: Sử dụng SDK Perfetto với macro
TRACE_EVENT. - Rust: Sử dụng thùng
tracing, phát ra các sự kiện ATrace tương thích với Perfetto.
- C++: Sử dụng SDK Perfetto với macro
- Tạo tệp cấu hình textproto để chỉ định nguồn dữ liệu (ví dụ:
ftrace,track_event), danh mục và thẻ. - Sử dụng tập lệnh
record_android_trace(external/perfetto/tools/record_android_trace) với tệp cấu hình để ghi lại dấu vết từ thiết bị. - Mở tệp theo dõi đã tạo trong Giao diện người dùng web Perfetto để phân tích hành vi hệ thống, xác định các điểm tắc nghẽn và hiểu các tương tác dịch vụ.
Để biết hướng dẫn chi tiết về việc đo lường, định cấu hình và thu thập, hãy xem bài viết Sử dụng tính năng theo dõi để nắm được thông tin chi tiết về hiệu suất hệ thống.
Sử dụng Simpleperf để phân tích
Simpleperf là một công cụ dòng lệnh linh hoạt để phân tích hiệu suất trên Android, tương tự như Linux perf.
Các trường hợp sử dụng phổ biến:
- Phân tích CPU: Xác định các hàm tiêu thụ nhiều thời gian CPU nhất.
- Phân tích ngoài CPU: Phân tích lý do các luồng đang ở trạng thái ngủ hoặc bị chặn.
- Bộ đếm phần cứng: Truy cập vào bộ đếm hiệu suất phần cứng.
Lệnh mẫu:
# Go to simpleperf scripts
cd system/extras/simpleperf/scripts
# Profile system for 20 seconds and record call graph
./app_profiler.py --system_wide -r "--call-graph fp --duration 20"
# Record a profile for a specific process (PID 1)
./app_profiler.py --pid 1 -r "--call-graph fp --duration 5"
# Pull the profile data
adb pull /data/local/tmp/perf.data .
# Generate a report with symbol resolution
./report_html.py --add_source_code --source_dirs $ANDROID_BUILD_TOP --add_disassembly -o report.html
Simpleperf cung cấp nhiều sự kiện và tuỳ chọn khác. Hãy tham khảo hướng dẫn về Simpleperf để xem tài liệu toàn diện.
Lỗi SELinux
Triệu chứng: Dịch vụ của bạn không khởi động được, không truy cập được vào tệp hoặc không sử dụng được một tính năng,
và bạn thấy thông báo avc: denied trong dmesg hoặc logcat.
[ 123.456] avc: denied { read } for pid=789 comm="my_service" name="some_file" dev="sda1" ino=123 scontext=u:r:my_service_t:s0 tcontext=u:object_r:some_file_t:s0 tclass=file permissive=0
Gỡ lỗi nhanh (chỉ dành cho quá trình phát triển)
Bạn có thể tạm thời tắt chế độ thực thi SELinux để xem vấn đề đã được giải quyết hay chưa. Điều này xác nhận rằng vấn đề là do thiếu quy tắc chính sách SELinux.
# Disabling SELinux requires root permission
adb root
# Set SELinux to permissive mode
adb shell setenforce 0
# Check the current mode (should return "Permissive")
adb shell getenforce
Khắc phục: Công cụ audit2allow từ cây nguồn Android trên thông báo từ chối. Công cụ này tạo quy tắc chính sách .te chính xác để thêm vào cấu hình SELinux của thiết bị.