SDV को डीबग करना

इस गाइड में, SDV प्लैटफ़ॉर्म पर चलने वाली सेवाओं और ऐप्लिकेशन को डीबग करने के लिए ज़रूरी टूल और तकनीकों के बारे में खास जानकारी दी गई है.

डिवाइस से कनेक्ट करना

डिवाइस से कनेक्ट करने और उससे इंटरैक्ट करने के लिए, मुख्य टूल Android डीबग ब्रिज (adb) है. पुष्टि करें कि adb आपके सिस्टम के पाथ में है.

नेटवर्क का इस्तेमाल करके कनेक्ट करना

अगर डिवाइस एक ही नेटवर्क पर है और आपको उसका आईपी पता मालूम है, तो ईथरनेट से कनेक्ट किया जा सकता है. हमारा सिस्टम, adb के लिए सिर्फ़ नेटवर्क कनेक्शन का इस्तेमाल करता है:

# Connect to the device using its IP address and default port
adb connect <device_ip_address>:5555

कई डिवाइसों से कनेक्ट करना

एक ही वर्कस्टेशन से कई डिवाइसों को मैनेज करने के लिए, उन्हें अलग-अलग आईपी पतों से कनेक्ट किया जा सकता है. अगर एक ही होस्ट पर कई वीएम चलाए जाते हैं, तो आपको हर डिवाइस को अलग-अलग पोर्ट असाइन करने होंगे. इसके लिए, हर एसडीवी डिवाइस पर adb डेमॉन को कॉन्फ़िगर करना ज़रूरी है, ताकि वह किसी यूनीक पोर्ट पर सिग्नल पा सके. उदाहरण के लिए, पहले डिवाइस के लिए 5555 और दूसरे के लिए 5556. होस्ट को उन पोर्ट को अलग-अलग मेहमानों को फ़ॉरवर्ड करने के लिए भी कॉन्फ़िगर किया जा सकता है:

# 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) - यह जानकारी लॉगकैट में भी दिखती है
# 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] में मिल सकता है. उदाहरण के लिए, system_ext और sdv_core_cf से rpcagent अपलोड करने के लिए, यह कमांड चलाएं:

    adb push out/target/product/sdv_core_cf/symbols/system_ext/bin/rpcagent /data/local/tmp
    

    अब अनस्ट्रिप्ड वर्शन, /data/local/tmp में है.

  3. lldbclient.py सुविधा स्क्रिप्ट का इस्तेमाल करके, LLDB क्लाइंट से कनेक्ट करें:

    # 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 चलाएं. इसे lldb से कनेक्ट करने के लिए, अपने आईडीई का दस्तावेज़ देखें.

क्रैश डंप (टूंबस्टोन) का विश्लेषण करना

जब कोई सेवा क्रैश होती है, तो /data/tombstones/ में टूंबस्टोन फ़ाइल जनरेट होती है. इस फ़ाइल में स्टैक ट्रेस, मेमोरी मैप, और अन्य ज़रूरी जानकारी होती है.

टूंबस्टोन फ़ाइल को पुल करें. इसके बाद, सिंबल की जानकारी देने वाले टूल (जैसे कि lldb या खास स्क्रिप्ट) का इस्तेमाल करके, बाइनरी के अनस्ट्रिप्ड वर्शन के साथ इसका विश्लेषण करें.

परफ़ॉर्मेंस का विश्लेषण करना

एसडीवी, परफ़ॉर्मेंस मेज़रमेंट के लिए कई टूल के साथ काम करता है.

सीपीयू और मेमोरी के इस्तेमाल की जांच करना

  • top: इससे सीपीयू के इस्तेमाल के हिसाब से क्रम में लगाई गई, चालू प्रोसेस की रीयल-टाइम जानकारी मिलती है.

    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++: TRACE_EVENT मैक्रो के साथ Perfetto SDK का इस्तेमाल करें.
    • Rust: tracing क्रेट का इस्तेमाल करें. यह Perfetto के साथ काम करने वाले ATrace इवेंट जनरेट करता है.
  2. डेटा सोर्स (उदाहरण के लिए, ftrace, track_event), कैटगरी, और टैग तय करने के लिए, textproto कॉन्फ़िगरेशन फ़ाइल बनाएं.
  3. डिवाइस से ट्रेस कैप्चर करने के लिए, कॉन्फ़िगरेशन फ़ाइल के साथ record_android_trace स्क्रिप्ट (external/perfetto/tools/record_android_trace) का इस्तेमाल करें.
  4. सिस्टम के व्यवहार का विश्लेषण करने, परफ़ॉर्मेंस से जुड़ी समस्याओं का पता लगाने, और सेवा के इंटरैक्शन को समझने के लिए, जनरेट की गई ट्रेस फ़ाइल को Perfetto के वेब यूज़र इंटरफ़ेस (यूआई) में खोलें.

इंस्ट्रुमेंटेशन, कॉन्फ़िगरेशन, और कलेक्शन के बारे में ज़्यादा जानकारी के लिए, सिस्टम की परफ़ॉर्मेंस के बारे में अहम जानकारी पाने के लिए ट्रेसिंग का इस्तेमाल करना लेख पढ़ें.

प्रोफ़ाइलिंग के लिए Simpleperf का इस्तेमाल करना

Simpleperf, Android पर परफ़ॉर्मेंस प्रोफ़ाइलिंग के लिए एक वर्सटाइल कमांड-लाइन टूल है. यह Linux perf की तरह काम करता है.

इस्तेमाल के सामान्य उदाहरण:

  • सीपीयू प्रोफ़ाइलिंग: उन फ़ंक्शन का पता लगाएं जो सीपीयू का सबसे ज़्यादा समय इस्तेमाल करते हैं.
  • ऑफ़-सीपीयू विश्लेषण: यह विश्लेषण करें कि थ्रेड स्लीपिंग या ब्लॉक क्यों हो रही हैं.
  • हार्डवेयर काउंटर: हार्डवेयर परफ़ॉर्मेंस काउंटर ऐक्सेस करें.

निर्देशों के उदाहरण:

# 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 की अनुमतियां अस्वीकार की गईं

समस्या का ब्यौरा: आपकी सेवा शुरू नहीं हो पाती, किसी फ़ाइल को ऐक्सेस नहीं किया जा सकता या किसी सुविधा का इस्तेमाल नहीं किया जा सकता. साथ ही, आपको dmesg या logcat में avc: denied मैसेज दिखता है.

[ 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

ठीक करें: अनुमति न मिलने के मैसेज में, Android सोर्स ट्री से audit2allow टूल का इस्तेमाल करें. इससे सही .te नीति का नियम जनरेट होता है. इसे आपके डिवाइस के SELinux कॉन्फ़िगरेशन में जोड़ा जा सकता है.