คู่มือนี้จะให้ภาพรวมของเครื่องมือและเทคนิคที่จำเป็นสำหรับการแก้ไขข้อบกพร่องของบริการและแอปพลิเคชันที่ทำงานบนแพลตฟอร์ม SDV
เชื่อมต่อกับอุปกรณ์
เครื่องมือหลักในการเชื่อมต่อและโต้ตอบกับอุปกรณ์คือ Android Debug Bridge (adb) ตรวจสอบว่า adb อยู่ในเส้นทางของระบบ
เชื่อมต่อโดยใช้เครือข่าย
หากอุปกรณ์อยู่ในเครือข่ายเดียวกันและคุณทราบที่อยู่ IP ของอุปกรณ์ คุณจะ เชื่อมต่อผ่านอีเทอร์เน็ตได้ ระบบของเราใช้การเชื่อมต่อเครือข่ายสำหรับ adb เท่านั้น
# Connect to the device using its IP address and default port
adb connect <device_ip_address>:5555
เชื่อมต่อกับอุปกรณ์หลายเครื่อง
หากต้องการจัดการอุปกรณ์หลายเครื่องจากเวิร์กสเตชันเดียว คุณสามารถเชื่อมต่อกับอุปกรณ์เหล่านั้นผ่านที่อยู่ IP ที่แตกต่างกันได้ หากเรียกใช้ VM หลายรายการในโฮสต์เดียว คุณจะต้องกำหนดพอร์ตที่แตกต่างกันให้กับอุปกรณ์แต่ละเครื่อง ซึ่งต้องกำหนดค่า Daemon ของ adb ในอุปกรณ์ SDV แต่ละเครื่องให้รับฟังในพอร์ตที่ไม่ซ้ำกัน เช่น 5555 สำหรับ อุปกรณ์เครื่องแรกและ 5556 สำหรับอุปกรณ์เครื่องที่ 2 นอกจากนี้ คุณยังกำหนดค่าโฮสต์ให้ส่งต่อ พอร์ตเหล่านั้นไปยังแขกรับเชิญรายอื่นได้ด้วย
# 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
เมื่อเรียกใช้adbคำสั่งต่อๆ ไป คุณจะกำหนดเป้าหมายอุปกรณ์ที่เฉพาะเจาะจงได้โดยใช้แฟล็ก -s พร้อมที่อยู่แบบเต็ม (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
ดูบันทึก
เมื่อบริการล้มเหลวหรือทำงานอย่างไม่คาดคิด ให้ตรวจสอบบันทึกก่อน
ใช้ Logcat (บันทึกของ Android)
logcat จะแสดงบันทึกจากบริการของระบบ เอเจนต์ และแพ็กเกจบริการ
# 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
ใช้ dmesg (บันทึกเคอร์เนล)
dmesg แสดงบันทึกจากเคอร์เนล Linux ซึ่งเป็นสิ่งสำคัญสำหรับการแก้ไขข้อบกพร่องของรายการต่อไปนี้
- ปัญหาเกี่ยวกับฮาร์ดแวร์และไดรเวอร์
- เคอร์เนลแพนิก
- การปฏิเสธ SELinux (
avc: denied) - แสดงใน Logcat ด้วย
# View all kernel messages
adb shell dmesg
# Follow kernel messages in real-time
adb shell dmesg -w
บันทึกการเข้าถึงใน Cuttlefish
เมื่อเรียกใช้ในอุปกรณ์เสมือนจริง Cuttlefish คุณจะเข้าถึงไฟล์บันทึกได้โดยตรงจากระบบไฟล์ของเครื่องโฮสต์ ซึ่งจะเป็นประโยชน์อย่างยิ่งหาก adb ไม่พร้อมใช้งาน
เมื่อเริ่ม Cuttlefish ระบบจะแสดงเส้นทางการแก้ไขข้อบกพร่องทั้งหมด และคุณยังค้นหาเส้นทางเหล่านั้นได้โดยใช้ cvd fleet สำหรับอินสแตนซ์ที่กำลังทำงานทั้งหมด
- Logcat (บันทึกของ Android):
cuttlefish/instances/cvd-1/logs/logcat - บันทึกเคอร์เนล:
cuttlefish/instances/cvd-1/logs/kernel.log - บันทึกตัวเรียกใช้ Cuttlefish:
cuttlefish/instances/cvd-1/logs/launcher.log(มีประโยชน์สำหรับการแก้ไขข้อบกพร่องของสภาพแวดล้อม Cuttlefish เอง)
คุณสามารถใช้เครื่องมือบรรทัดคำสั่งมาตรฐาน เช่น cat, less หรือ tail -f เพื่อ
ดูไฟล์เหล่านี้แบบเรียลไทม์
โต้ตอบกับเชลล์และระบบไฟล์
รับสิทธิ์เข้าถึงเชลล์เพื่อเรียกใช้คำสั่งในอุปกรณ์โดยตรง ตรวจสอบสถานะกระบวนการ และไปยังระบบไฟล์
# 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>
ดำเนินการกับระบบไฟล์
ใช้ adb push และ adb pull เพื่อย้ายไฟล์ระหว่างเครื่องโฮสต์กับอุปกรณ์ ใช้คำสั่งนี้เพื่อทำให้สคริปต์ทดสอบใช้งานได้ อัปเดตการกำหนดค่า หรือเรียกข้อมูลการทิ้งหน่วยความจำเมื่อเกิดข้อขัดข้อง
# 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 .
แก้ไขข้อบกพร่องของแอปพลิเคชัน (C++/Rust)
คุณสามารถแก้ไขข้อบกพร่องของแอปพลิเคชันได้ทั้งแบบออนไลน์และออฟไลน์
ใช้ lldb สำหรับการแก้ไขข้อบกพร่องแบบเรียลไทม์
lldb เป็นดีบักเกอร์เริ่มต้นใน Android Studio และมักเป็นตัวเลือกที่ต้องการสำหรับการพัฒนา C++ และ Rust สมัยใหม่
ทำตามขั้นตอนการตั้งค่าต่อไปนี้
รีสตาร์ท adb เพื่ออนุญาตสิทธิ์รูท (ต้องใช้เพื่อส่งต่อ) ใช้เพื่อตั้งค่า การส่งต่อพอร์ต เรียกใช้คำสั่งต่อไปนี้ในโฮสต์
adb rootหากไบนารีมีสัญลักษณ์การแก้ไขข้อบกพร่อง ให้พุชเวอร์ชันที่ไม่ได้ลบ คุณดูเวอร์ชันที่ไม่ได้ลบข้อมูลออกได้ใน
out/target/product/[SDV_FLAVOR]/symbols/[PARTITION]/bin/[EXECUTABLE]เช่น หากต้องการอัปโหลดrpcagentจากsystem_extและsdv_core_cfให้เรียกใช้คำสั่งต่อไปนี้adb push out/target/product/sdv_core_cf/symbols/system_ext/bin/rpcagent /data/local/tmpตอนนี้เวอร์ชันที่ไม่ได้ลบข้อมูลออกจะอยู่ใน
/data/local/tmpเชื่อมต่อกับไคลเอ็นต์ LLDB โดยใช้สคริปต์ความสะดวก
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 2759สคริปต์นี้เชื่อมต่อ lldb จากระยะไกล หากต้องการดูแฟล็กทั้งหมดที่ใช้ได้ ให้เรียกใช้
lldbclient.pyโปรดดูเอกสารประกอบของ IDE เพื่อเชื่อมต่อกับ lldb
วิเคราะห์ Crash Dump (Tombstone)
เมื่อบริการขัดข้อง ระบบจะสร้างไฟล์ tombstone ใน /data/tombstones/
ไฟล์นี้มีสแต็กเทรซ แผนที่หน่วยความจำ และข้อมูลสำคัญอื่นๆ
ดึงไฟล์หลุมศพ จากนั้นใช้เครื่องมือที่รับรู้สัญลักษณ์ (เช่น lldb หรือสคริปต์เฉพาะ) เพื่อวิเคราะห์ไฟล์ดังกล่าวด้วยไบนารีเวอร์ชันที่ไม่ได้ลบ
วิเคราะห์ประสิทธิภาพ
SDV รองรับเครื่องมือหลายอย่างสำหรับการวัดประสิทธิภาพ
ตรวจสอบการใช้งาน CPU และหน่วยความจำ
top: แสดงมุมมองแบบเรียลไทม์ของกระบวนการที่กำลังทำงานซึ่งจัดเรียงตามการใช้งาน CPUadb shell top -m 10 # Show top 10 processesprocrank: แสดงรายละเอียดการใช้งานหน่วยความจำสำหรับกระบวนการที่เฉพาะเจาะจง หรือทั้งระบบadb shell procrank
ใช้ dumpsys สำหรับสถานะบริการ
dumpsys เป็นเครื่องมือที่มีประสิทธิภาพในการค้นหาสถานะภายในของบริการระบบ Android
# List all available services
adb shell dumpsys -l
# Dump the state of a specific service or agent
adb shell dumpsys <service_name>
ใช้ Torq เพื่อวิเคราะห์ประสิทธิภาพ
torq เป็นเครื่องมือบรรทัดคำสั่งที่ช่วยลดความซับซ้อนของงานการจัดทำโปรไฟล์และการติดตามใน Android ซึ่งช่วยให้เรียกใช้ Simpleperf, Perfetto และงานทั่วไปอื่นๆ ได้ในระหว่าง การวิเคราะห์ประสิทธิภาพของระบบ
ใช้ Perfetto สำหรับการติดตาม
Perfetto เป็นเครื่องมือมาตรฐานสำหรับการติดตามทั่วทั้งระบบใน Android Perfetto ช่วยให้คุณบันทึกเหตุการณ์ของระบบ จุดติดตามระดับแอป และตัวนับประสิทธิภาพ และแสดงภาพเหตุการณ์เหล่านั้นในไทม์ไลน์ได้
ขั้นตอนสำคัญ
- เพิ่มจุดติดตามในโค้ด C++ หรือ Rust ดังนี้
- C++: ใช้ Perfetto SDK กับมาโคร
TRACE_EVENT - Rust: ใช้
tracingCrate ซึ่งจะปล่อยเหตุการณ์ ATrace ที่เข้ากันได้ กับ Perfetto
- C++: ใช้ Perfetto SDK กับมาโคร
- สร้างไฟล์การกำหนดค่า textproto เพื่อระบุแหล่งข้อมูล (เช่น
ftrace,track_event) หมวดหมู่ และแท็ก - ใช้สคริปต์
record_android_trace(external/perfetto/tools/record_android_trace) กับไฟล์การกำหนดค่า เพื่อบันทึกการติดตามจากอุปกรณ์ - เปิดไฟล์การติดตามที่สร้างขึ้นใน Perfetto Web UI เพื่อวิเคราะห์ลักษณะการทำงานของระบบ ระบุคอขวด และทําความเข้าใจการโต้ตอบของบริการ
ดูวิธีการโดยละเอียดเกี่ยวกับการวัดผล การกำหนดค่า และการรวบรวมได้ที่ใช้การติดตามเพื่อรับข้อมูลเชิงลึกเกี่ยวกับประสิทธิภาพของระบบ
ใช้ Simpleperf สำหรับการสร้างโปรไฟล์
Simpleperf เป็นเครื่องมือบรรทัดคำสั่งอเนกประสงค์สำหรับการสร้างโปรไฟล์ประสิทธิภาพใน Android ซึ่งคล้ายกับ perf ของ Linux
กรณีการใช้งานทั่วไป
- การสร้างโปรไฟล์ CPU: ระบุฟังก์ชันที่ใช้เวลา CPU มากที่สุด
- การวิเคราะห์นอก CPU: วิเคราะห์สาเหตุที่ทำให้เธรดอยู่ในโหมดสลีปหรือถูกบล็อก
- ตัวนับฮาร์ดแวร์: เข้าถึงตัวนับประสิทธิภาพของฮาร์ดแวร์
ตัวอย่างคำสั่ง
# 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 มีเหตุการณ์และตัวเลือกอื่นๆ อีกมากมาย โปรดดูเอกสารประกอบที่ครอบคลุมในคู่มือ Simpleperf
การปฏิเสธ SELinux
อาการ: บริการเริ่มทำงาน เข้าถึงไฟล์ หรือใช้ความสามารถไม่สำเร็จ
และคุณเห็นavc: deniedข้อความใน dmesg หรือ 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
การแก้ไขข้อบกพร่องอย่างรวดเร็ว (สําหรับการพัฒนาเท่านั้น)
คุณปิดใช้การบังคับใช้ SELinux ชั่วคราวเพื่อดูว่าปัญหาได้รับการแก้ไขหรือไม่ ซึ่งยืนยันว่าปัญหาเกิดจากกฎนโยบาย 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
แก้ไข: เครื่องมือ audit2allow จากโครงสร้างแหล่งที่มาของ Android ในข้อความการปฏิเสธ
ซึ่งจะสร้างกฎนโยบาย .te ที่ถูกต้องเพื่อเพิ่มลงในการกำหนดค่า SELinux ของอุปกรณ์