फ़्रेट्रेस का उपयोग करना

लिनक्स कर्नेल के अंदर क्या चल रहा है यह समझने के लिए एफट्रेस एक डिबगिंग टूल है। निम्नलिखित अनुभाग बुनियादी फ़ट्रेस कार्यक्षमता, एट्रेस के साथ फ़ट्रेस उपयोग (जो कर्नेल घटनाओं को कैप्चर करता है), और गतिशील फ़ट्रेस का विवरण देता है।

उन्नत फ़ट्रेस कार्यक्षमता पर विवरण के लिए जो सिस्ट्रेस से उपलब्ध नहीं है, फ़ट्रेस दस्तावेज़ को <kernel tree>/Documentation/trace/ftrace.txt पर देखें।

एट्रेस के साथ कर्नेल घटनाओं को कैप्चर करना

एट्रेस ( frameworks/native/cmds/atrace ) कर्नेल घटनाओं को कैप्चर करने के लिए ftrace का उपयोग करता है। बदले में, systrace.py (या Catapult के बाद के संस्करणों में run_systrace.py) डिवाइस पर atrace चलाने के लिए adb का उपयोग करता है। एट्रेस निम्नलिखित कार्य करता है:

  • एक प्रॉपर्टी ( debug.atrace.tags.enableflags ) सेट करके यूजर-मोड ट्रेसिंग सेट करता है।
  • उपयुक्त फ़ट्रेस sysfs नोड्स पर लिखकर वांछित फ़ट्रेस कार्यक्षमता को सक्षम करता है। हालाँकि, चूँकि ftrace अधिक सुविधाओं का समर्थन करता है, आप स्वयं कुछ sysfs नोड्स सेट कर सकते हैं और फिर atrace का उपयोग कर सकते हैं।

बूट-टाइम ट्रेसिंग के अपवाद के साथ, संपत्ति को उचित मूल्य पर सेट करने के लिए एट्रेस का उपयोग करने पर भरोसा करें। संपत्ति एक बिटमास्क है और उचित हेडर (जो एंड्रॉइड रिलीज के बीच बदल सकता है) को देखने के अलावा सही मान निर्धारित करने का कोई अच्छा तरीका नहीं है।

फ़ुट्रेस ईवेंट सक्षम करना

Ftrace sysfs नोड्स /sys/kernel/tracing में हैं और ट्रेस इवेंट को /sys/kernel/tracing/events में श्रेणियों में विभाजित किया गया है।

प्रति-श्रेणी के आधार पर ईवेंट सक्षम करने के लिए, उपयोग करें:

echo 1 > /sys/kernel/tracing/events/irq/enable

प्रति-घटना के आधार पर घटनाओं को सक्षम करने के लिए, उपयोग करें:

echo 1 > /sys/kernel/tracing/events/sched/sched_wakeup/enable

यदि अतिरिक्त घटनाओं को sysfs नोड्स पर लिखकर सक्षम किया गया है, तो उन्हें एट्रेस द्वारा रीसेट नहीं किया जाएगा। क्वालकॉम डिवाइस लाने के लिए एक सामान्य पैटर्न kgsl (जीपीयू) और mdss (डिस्प्ले पाइपलाइन) ट्रेसप्वाइंट को सक्षम करना और फिर एट्रेस या सिस्ट्रेस का उपयोग करना है:

adb shell "echo 1 > /sys/kernel/tracing/events/mdss/enable"
adb shell "echo 1 > /sys/kernel/tracing/events/kgsl/enable"
./systrace.py sched freq idle am wm gfx view binder_driver irq workq ss sync -t 10 -b 96000 -o full_trace.html

आप एट्रेस या सिस्ट्रेस के बिना भी एफट्रेस का उपयोग कर सकते हैं, जो तब उपयोगी होता है जब आप केवल कर्नेल ट्रेस चाहते हैं (या यदि आपने उपयोगकर्ता-मोड ट्रेसिंग प्रॉपर्टी को हाथ से लिखने के लिए समय निकाला है)। केवल फ़ट्रेस चलाने के लिए:

  1. बफ़र आकार को आपके ट्रेस के लिए पर्याप्त बड़े मान पर सेट करें:
    echo 96000 > /sys/kernel/tracing/buffer_size_kb
    
  2. ट्रेसिंग सक्षम करें:
    echo 1 > /sys/kernel/tracing/tracing_on
    
  3. अपना परीक्षण चलाएँ, फिर ट्रेसिंग अक्षम करें:
    echo 0 > /sys/kernel/tracing/tracing_on
    
  4. ट्रेस डंप करें:
    cat /sys/kernel/tracing/trace > /data/local/tmp/trace_output
    

ट्रेस_आउटपुट ट्रेस को टेक्स्ट फॉर्म में देता है। कैटापुल्ट का उपयोग करके इसकी कल्पना करने के लिए, GitHub से कैटापुल्ट रिपॉजिटरी प्राप्त करें और ट्रेस2html चलाएं:

catapult/tracing/bin/trace2html ~/path/to/trace_file

डिफ़ॉल्ट रूप से, यह उसी निर्देशिका में trace_file.html लिखता है।

सहसंबद्ध घटनाएँ

कैटापुल्ट विज़ुअलाइज़ेशन और फ़ट्रेस लॉग को एक साथ देखना अक्सर उपयोगी होता है; उदाहरण के लिए, कुछ फ़ट्रेस ईवेंट (विशेष रूप से विक्रेता-विशिष्ट वाले) कैटापुल्ट द्वारा देखे नहीं जाते हैं। हालाँकि, कैटापुल्ट के टाइमस्टैम्प या तो ट्रेस में पहली घटना के सापेक्ष होते हैं या एट्रेस द्वारा डंप किए गए एक विशिष्ट टाइमस्टैम्प के सापेक्ष होते हैं, जबकि कच्चे फ़ट्रेस टाइमस्टैम्प लिनक्स कर्नेल में एक विशेष पूर्ण घड़ी स्रोत पर आधारित होते हैं।

कैटापुल्ट इवेंट से दिए गए फ़ट्रेस इवेंट को खोजने के लिए:

  1. कच्चा फ़ट्रेस लॉग खोलें. सिस्ट्रेस के हाल के संस्करणों में निशान डिफ़ॉल्ट रूप से संपीड़ित होते हैं:
    • यदि आपने अपने सिस्ट्रेस को --no-compress के साथ कैप्चर किया है, तो यह BEGIN TRACE से शुरू होने वाले अनुभाग में HTML फ़ाइल में है।
    • यदि नहीं, तो ट्रेस को अनकंप्रेस करने के लिए कैटापुल्ट ट्री ( tracing/bin/html2trace ) से html2trace चलाएँ।
  2. कैटापुल्ट विज़ुअलाइज़ेशन में सापेक्ष टाइमस्टैम्प ढूंढें।
  3. ट्रेस की शुरुआत में tracing_mark_sync युक्त एक पंक्ति ढूंढें। इसे कुछ इस तरह दिखना चाहिए:
    <5134>-5134  (-----) [003] ...1    68.104349: tracing_mark_write: trace_event_clock_sync: parent_ts=68.104286
    

    यदि यह लाइन मौजूद नहीं है (या यदि आपने एट्रेस के बिना एफट्रेस का उपयोग किया है), तो समय एफट्रेस लॉग में पहली घटना से सापेक्ष होगा।
    1. parent_ts (सेकंड में) के मान में संबंधित टाइमस्टैम्प (मिलीसेकंड में) जोड़ें।
    2. नया टाइमस्टैम्प खोजें.

ये कदम आपको इवेंट में (या कम से कम बहुत करीब) पहुंचा देंगे।

गतिशील फ़ट्रेस का उपयोग करना

जब सिस्ट्रेस और मानक फ़ट्रेस अपर्याप्त होते हैं, तो एक अंतिम सहारा उपलब्ध होता है: डायनेमिक फ़ट्रेस । डायनेमिक फ़ट्रेस में बूट के बाद कर्नेल कोड को फिर से लिखना शामिल है, और परिणामस्वरूप यह सुरक्षा कारणों से उत्पादन कर्नेल में उपलब्ध नहीं है। हालाँकि, 2015 और 2016 में हर एक कठिन प्रदर्शन बग अंततः डायनेमिक फ़ट्रेस का उपयोग करके उत्पन्न किया गया था। यह निर्बाध नींद को डीबग करने के लिए विशेष रूप से शक्तिशाली है क्योंकि हर बार जब आप निर्बाध नींद को ट्रिगर करने वाले फ़ंक्शन को हिट करते हैं तो आप कर्नेल में एक स्टैक ट्रेस प्राप्त कर सकते हैं। आप इंटरप्ट और प्रीएम्पशन अक्षम वाले अनुभागों को डीबग भी कर सकते हैं, जो मुद्दों को साबित करने के लिए बहुत उपयोगी हो सकता है।

डायनेमिक फ़ट्रेस चालू करने के लिए, अपने कर्नेल के डिफ़ॉन्फ़िग को संपादित करें:

  1. CONFIG_STRICT_MEMORY_RWX हटाएं (यदि यह मौजूद है)। यदि आप 3.18 या नए और आर्म64 पर हैं, तो यह वहां नहीं है।
  2. निम्नलिखित जोड़ें: CONFIG_DYNAMIC_FTRACE=y, CONFIG_FUNCTION_TRACER=y, CONFIG_IRQSOFF_TRACER=y, CONFIG_FUNCTION_PROFILER=y, और CONFIG_PREEMPT_TRACER=y
  3. नए कर्नेल को पुनः बनाएँ और बूट करें।
  4. उपलब्ध ट्रैसर की जांच के लिए निम्नलिखित चलाएँ:
    cat /sys/kernel/tracing/available_tracers
    
  5. कमांड रिटर्न function , irqsoff , preemptoff , और preemptirqsoff पुष्टि करें।
  6. यह सुनिश्चित करने के लिए कि डायनेमिक फ़ट्रेस काम कर रहा है, निम्नलिखित चलाएँ:
    cat /sys/kernel/tracing/available_filter_functions | grep <a function you care about>
    

इन चरणों को पूरा करने के बाद, आपके पास डायनामिक फ़ट्रेस, फ़ंक्शन प्रोफाइलर, आईर्कसॉफ प्रोफाइलर और प्रीमेप्टऑफ प्रोफाइलर उपलब्ध हैं। हम इन विषयों का उपयोग करने से पहले उन पर फ़ट्रेस दस्तावेज़ पढ़ने की दृढ़ता से अनुशंसा करते हैं क्योंकि वे शक्तिशाली लेकिन जटिल हैं। irqsoff और preemptoff मुख्य रूप से यह पुष्टि करने के लिए उपयोगी हैं कि ड्राइवर बहुत लंबे समय तक व्यवधान या प्रीएम्प्शन को बंद छोड़ सकते हैं।

फ़ंक्शन प्रोफाइलर प्रदर्शन संबंधी समस्याओं के लिए सबसे अच्छा विकल्प है और इसका उपयोग अक्सर यह पता लगाने के लिए किया जाता है कि किसी फ़ंक्शन को कहां बुलाया जा रहा है।


यदि फ़ंक्शन प्रोफाइलर का डेटा पर्याप्त विशिष्ट नहीं है, तो आप फ़ंक्शन प्रोफाइलर के साथ फ़ट्रेस ट्रेसप्वाइंट को जोड़ सकते हैं। फ़ट्रेस ईवेंट को हमेशा की तरह बिल्कुल उसी तरह से सक्षम किया जा सकता है, और वे आपके ट्रेस के साथ इंटरलीव हो जाएंगे। यह बहुत अच्छा है अगर किसी विशिष्ट फ़ंक्शन में कभी-कभी लंबी निर्बाध नींद आती है जिसे आप डीबग करना चाहते हैं: जिस फ़ंक्शन को आप चाहते हैं उस पर फ़ट्रेस फ़िल्टर सेट करें, ट्रेसपॉइंट सक्षम करें, ट्रेस लें। आप परिणामी ट्रेस को trace2html के साथ पार्स कर सकते हैं, अपने इच्छित ईवेंट को ढूंढ सकते हैं, फिर कच्चे ट्रेस में पास के स्टैक ट्रेस प्राप्त कर सकते हैं।

लॉकस्टैट का उपयोग करना

कभी-कभी, फ़ट्रेस पर्याप्त नहीं होता है और आपको वास्तव में कर्नेल लॉक विवाद को डीबग करने की आवश्यकता होती है। कोशिश करने लायक एक और कर्नेल विकल्प है: CONFIG_LOCK_STAT । यह एक अंतिम उपाय है क्योंकि एंड्रॉइड डिवाइस पर काम करना बेहद मुश्किल है क्योंकि यह कर्नेल के आकार को अधिकांश डिवाइसों की क्षमता से अधिक बढ़ा देता है।

हालाँकि, लॉकस्टैट डिबग लॉकिंग इंफ्रास्ट्रक्चर का उपयोग करता है, जो कई अन्य अनुप्रयोगों के लिए उपयोगी है। डिवाइस लाने पर काम करने वाले प्रत्येक व्यक्ति को उस विकल्प को हर डिवाइस पर काम करने का कोई न कोई तरीका निकालना चाहिए क्योंकि एक समय आएगा जब आप सोचेंगे "काश मैं LOCK_STAT चालू कर पाता, तो मैं इसके बजाय पांच मिनट में समस्या के रूप में इसकी पुष्टि या खंडन कर सकता था पांच दिन।"


यदि आप कॉन्फ़िगरेशन विकल्प के साथ कर्नेल को बूट कर सकते हैं, तो लॉक ट्रेसिंग फ़ट्रेस के समान है:

  1. ट्रेसिंग सक्षम करें:
    echo 1 > /proc/sys/kernel/lock_stat
    
  2. अपना परीक्षण चलाएँ.
  3. ट्रेसिंग अक्षम करें:
    echo 0 > /proc/sys/kernel/lock_stat
    
  4. अपना ट्रेस डंप करें:
    cat /proc/lock_stat > /data/local/tmp/lock_stat
    

परिणामी आउटपुट की व्याख्या करने में सहायता के लिए, <kernel>/Documentation/locking/lockstat.txt पर लॉकस्टैट दस्तावेज़ देखें।

विक्रेता ट्रेसप्वाइंट का उपयोग करना

पहले अपस्ट्रीम ट्रेसप्वाइंट का उपयोग करें, लेकिन कभी-कभी आपको विक्रेता ट्रेसप्वाइंट का उपयोग करने की आवश्यकता होगी:

  { "gfx",        "Graphics",         ATRACE_TAG_GRAPHICS, {
        { OPT,      "events/mdss/enable" },
        { OPT,      "events/sde/enable" },
        { OPT,      "events/mali_systrace/enable" },
    } },

ट्रेसप्वाइंट एचएएल सेवा द्वारा विस्तार योग्य हैं जो आपको डिवाइस विशिष्ट ट्रेस पॉइंट/श्रेणियां जोड़ने की अनुमति देते हैं। ट्रेसपॉइंट्स को पर्फ़ेटो, एट्रेस/सिस्ट्रेस और ऑन-डिवाइस सिस्टम ट्रेसिंग ऐप के साथ एकीकृत किया गया है।

ट्रेसप्वाइंट/श्रेणियों को लागू करने के लिए एपीआई हैं:

  • listCategories() उत्पन्न करता है (vec<TracingCategory> श्रेणियां);
  • EnableCategories(vec<string> श्रेणियाँ) उत्पन्न करता है (स्थिति स्थिति);
  • disableAllCategories() (स्थिति स्थिति) उत्पन्न करता है;
अधिक जानकारी के लिए, AOSP में HAL परिभाषा और डिफ़ॉल्ट कार्यान्वयन देखें: