แก้ไขข้อบกพร่อง SDV

คู่มือนี้จะให้ภาพรวมของเครื่องมือและเทคนิคที่จำเป็นสำหรับการแก้ไขข้อบกพร่องของบริการและแอปพลิเคชันที่ทำงานบนแพลตฟอร์ม 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 สมัยใหม่

ทำตามขั้นตอนการตั้งค่าต่อไปนี้

  1. รีสตาร์ท adb เพื่ออนุญาตสิทธิ์รูท (ต้องใช้เพื่อส่งต่อ) ใช้เพื่อตั้งค่า การส่งต่อพอร์ต เรียกใช้คำสั่งต่อไปนี้ในโฮสต์

    adb root
    
  2. หากไบนารีมีสัญลักษณ์การแก้ไขข้อบกพร่อง ให้พุชเวอร์ชันที่ไม่ได้ลบ คุณดูเวอร์ชันที่ไม่ได้ลบข้อมูลออกได้ใน 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

  3. เชื่อมต่อกับไคลเอ็นต์ 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: แสดงมุมมองแบบเรียลไทม์ของกระบวนการที่กำลังทำงานซึ่งจัดเรียงตามการใช้งาน CPU

    adb shell top -m 10  # Show top 10 processes
    
  • procrank: แสดงรายละเอียดการใช้งานหน่วยความจำสำหรับกระบวนการที่เฉพาะเจาะจง หรือทั้งระบบ

    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 ช่วยให้คุณบันทึกเหตุการณ์ของระบบ จุดติดตามระดับแอป และตัวนับประสิทธิภาพ และแสดงภาพเหตุการณ์เหล่านั้นในไทม์ไลน์ได้

ขั้นตอนสำคัญ

  1. เพิ่มจุดติดตามในโค้ด C++ หรือ Rust ดังนี้
    • C++: ใช้ Perfetto SDK กับมาโคร TRACE_EVENT
    • Rust: ใช้ tracing Crate ซึ่งจะปล่อยเหตุการณ์ ATrace ที่เข้ากันได้ กับ Perfetto
  2. สร้างไฟล์การกำหนดค่า textproto เพื่อระบุแหล่งข้อมูล (เช่น ftrace, track_event) หมวดหมู่ และแท็ก
  3. ใช้สคริปต์ record_android_trace (external/perfetto/tools/record_android_trace) กับไฟล์การกำหนดค่า เพื่อบันทึกการติดตามจากอุปกรณ์
  4. เปิดไฟล์การติดตามที่สร้างขึ้นใน 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 ของอุปกรณ์