แก้ไขข้อบกพร่อง 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 แสดงบันทึกจากบริการของระบบ, Agent และแพ็กเกจบริการ ดังนี้

# 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
  • บันทึกของ Launcher ของ Cuttlefish: cuttlefish/instances/cvd-1/logs/launcher.log (มีประโยชน์สำหรับการแก้ไขข้อบกพร่องในสภาพแวดล้อมของ Cuttlefish เอง)

คุณสามารถใช้เครื่องมือบรรทัดคำสั่งมาตรฐาน เช่น cat, less หรือ tail -f เพื่อดูไฟล์เหล่านี้แบบเรียลไทม์ได้

โต้ตอบกับเชลล์และระบบไฟล์

รับสิทธิ์เข้าถึง Shell เพื่อเรียกใช้คำสั่งบนอุปกรณ์โดยตรง ตรวจสอบสถานะกระบวนการ และไปยังส่วนต่างๆ ของระบบไฟล์ โดยทำดังนี้

# 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 เพื่อย้ายไฟล์ระหว่างเครื่องโฮสต์และอุปกรณ์ ใช้ตัวเลือกนี้เพื่อติดตั้งใช้งานสคริปต์ทดสอบ อัปเดตการกำหนดค่า หรือเรียกข้อมูล Crash Dump

# 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 for Platform โปรดดูแก้ไขข้อบกพร่องและทดสอบและแก้ไขข้อบกพร่องของโค้ดแพลตฟอร์ม)

  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
    
  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 --help

วิเคราะห์ Crash Dump (Tombstone)

เมื่อบริการขัดข้อง ระบบจะสร้างไฟล์ tombstone ใน /data/tombstones/ ไฟล์นี้ประกอบด้วยสแต็กเทรซ แผนผังหน่วยความจำ และข้อมูลสำคัญอื่นๆ

ดึงไฟล์ Tombstone แล้วใช้เครื่องมือที่รองรับสัญลักษณ์ (เช่น 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 ซึ่งคล้ายกับ Linux perf

กรณีการใช้งานทั่วไป

  • การทำโปรไฟล์ 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 ของอุปกรณ์