ftrace एक डीबगिंग टूल है. इससे यह समझने में मदद मिलती है कि Linux kernel में क्या हो रहा है. नीचे दिए गए सेक्शन में, ftrace की बुनियादी सुविधाओं, atrace (जो कर्नेल इवेंट कैप्चर करता है) के साथ ftrace के इस्तेमाल, और डाइनैमिक ftrace के बारे में बताया गया है.
systrace में उपलब्ध नहीं होने वाली, ftrace की बेहतर सुविधाओं के बारे में जानने के लिए, <kernel
tree>/Documentation/trace/ftrace.txt
पर ftrace दस्तावेज़ देखें.
atrace की मदद से, कर्नेल इवेंट कैप्चर करना
atrace (frameworks/native/cmds/atrace
), कर्नेल इवेंट कैप्चर करने के लिए ftrace का इस्तेमाल करता है. इसके बाद, systrace.py (या Catapult के बाद के वर्शन में run_systrace.py) डिवाइस पर atrace चलाने के लिए, adb का इस्तेमाल करता है. atrace ये काम करता है:
- प्रॉपर्टी (
debug.atrace.tags.enableflags
) सेट करके, उपयोगकर्ता-मोड ट्रैकिंग सेट अप करता है. - सही ftrace sysfs नोड में लिखकर, मनचाही ftrace सुविधा चालू करता है. हालांकि, ftrace में ज़्यादा सुविधाएं काम करती हैं. इसलिए, कुछ sysfs नोड को खुद से सेट करने के बाद, atrace का इस्तेमाल किया जा सकता है.
बूट-टाइम ट्रैकिंग को छोड़कर, प्रॉपर्टी को सही वैल्यू पर सेट करने के लिए, atrace का इस्तेमाल करें. यह प्रॉपर्टी एक बिटमास्क है. सही वैल्यू का पता लगाने का कोई अच्छा तरीका नहीं है. इसके लिए, सही हेडर देखना ज़रूरी है. यह हेडर, Android रिलीज़ के बीच बदल सकता है.
ftrace इवेंट चालू करना
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 नोड में लिखकर अतिरिक्त इवेंट चालू किए गए हैं, तो atrace की मदद से उन्हें रीसेट नहीं किया जाएगा. Qualcomm डिवाइस को चालू करने के लिए, आम तौर पर kgsl
(GPU) और
mdss
(डिसप्ले पाइपलाइन) ट्रैसपॉइंट चालू किए जाते हैं. इसके बाद, atrace या
systrace का इस्तेमाल किया जाता है:
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
atrace या systrace के बिना भी ftrace का इस्तेमाल किया जा सकता है. यह तब मददगार होता है, जब आपको सिर्फ़ कर्नेल के ट्रैक चाहिए हों या आपने उपयोगकर्ता-मोड ट्रैकिंग प्रॉपर्टी को मैन्युअल तरीके से लिखने में समय लगाया हो. सिर्फ़ ftrace चलाने के लिए:
- बफ़र साइज़ को अपने ट्रेस के लिए ज़रूरत के मुताबिक सेट करें:
echo 96000 > /sys/kernel/tracing/buffer_size_kb
- ट्रैकिंग की सुविधा चालू करना:
echo 1 > /sys/kernel/tracing/tracing_on
- अपना टेस्ट चलाएं, फिर ट्रैकिंग बंद करें:
echo 0 > /sys/kernel/tracing/tracing_on
- ट्रेस को डंप करें:
cat /sys/kernel/tracing/trace > /data/local/tmp/trace_output
trace_output, ट्रैक को टेक्स्ट फ़ॉर्मैट में दिखाता है. Catapult का इस्तेमाल करके इसे विज़ुअलाइज़ करने के लिए, GitHub से Catapult रिपॉज़िटरी पाएं और trace2html चलाएं:
catapult/tracing/bin/trace2html ~/path/to/trace_file
डिफ़ॉल्ट रूप से, यह उसी डायरेक्ट्री में trace_file.html
लिखता है.
इवेंट को जोड़ना
Catapult विज़ुअलाइज़ेशन और ftrace लॉग को एक साथ देखना अक्सर फ़ायदेमंद होता है. उदाहरण के लिए, Catapult कुछ ftrace इवेंट (खास तौर पर, वेंडर के हिसाब से) को विज़ुअलाइज़ नहीं करता. हालांकि, Catapult के टाइमस्टैंप, ट्रैस में पहले इवेंट या atrace के ज़रिए डंप किए गए किसी खास टाइमस्टैंप के हिसाब से होते हैं. वहीं, रॉ ftrace टाइमस्टैंप, Linux kernel में किसी खास ऐब्सोलूट क्लॉक सोर्स पर आधारित होते हैं.
Catapult इवेंट से कोई ftrace इवेंट ढूंढने के लिए:
- रॉ ftrace लॉग खोलें. systrace के हाल ही के वर्शन में, ट्रैस डिफ़ॉल्ट रूप से संकुचित होते हैं:
- अगर आपने
--no-compress
की मदद से अपना systrace कैप्चर किया है, तो यह एचटीएमएल फ़ाइल में, BEGIN TRACE से शुरू होने वाले सेक्शन में मौजूद होगा. - अगर ऐसा नहीं है, तो ट्रैक को अनकंप्रेस करने के लिए, Catapult ट्र्री (
tracing/bin/html2trace
) से html2trace चलाएं.
- अगर आपने
- Catapult विज़ुअलाइज़ेशन में, रिलेटिव टाइमस्टैंप ढूंढें.
- ट्रैस की शुरुआत में,
tracing_mark_sync
वाली लाइन ढूंढें. यह कुछ ऐसा दिखेगा:<5134>-5134 (-----) [003] ...1 68.104349: tracing_mark_write: trace_event_clock_sync: parent_ts=68.104286
अगर यह लाइन मौजूद नहीं है या आपने atrace के बिना ftrace का इस्तेमाल किया है, तो समय, ftrace लॉग में पहले इवेंट के हिसाब से होगा.parent_ts
(सेकंड में) की वैल्यू में, रिलेटिव टाइमस्टैंप (मिलीसेकंड में) जोड़ें.- नया टाइमस्टैंप खोजें.
इन चरणों को पूरा करने के बाद, आपको इवेंट पर या उसके आस-पास पहुंच जाना चाहिए.
डाइनैमिक ftrace का इस्तेमाल करना
अगर systrace और स्टैंडर्ड ftrace काफ़ी नहीं हैं, तो एक आखिरी विकल्प उपलब्ध है: डाइनैमिक ftrace. डाइनैमिक ftrace में, बूट होने के बाद कोर कोड को फिर से लिखना शामिल है. इस वजह से, यह सुरक्षा से जुड़ी वजहों से प्रोडक्शन कोर में उपलब्ध नहीं है. हालांकि, 2015 और 2016 में परफ़ॉर्मेंस से जुड़ी हर मुश्किल गड़बड़ी की वजह, डाइनैमिक ftrace का इस्तेमाल करना था. यह सुविधा, बिना रुकावट के नींद मोड को डीबग करने के लिए खास तौर पर कारगर है. ऐसा इसलिए, क्योंकि बिना रुकावट के नींद मोड को ट्रिगर करने वाले फ़ंक्शन को हर बार हिट करने पर, आपको कर्नेल में स्टैक ट्रेस मिल सकता है. आपके पास, इंटरप्ट और प्रीएमप्शन बंद करके सेक्शन डीबग करने का भी विकल्प है. इससे, समस्याओं का पता लगाने में काफ़ी मदद मिल सकती है.
डाइनैमिक ftrace चालू करने के लिए, अपने कर्नेल के defconfig में बदलाव करें:
- CONFIG_STRICT_MEMORY_RWX को हटाएं (अगर मौजूद है). अगर आपके पास 3.18 या उसके बाद का वर्शन और arm64 है, तो यह सुविधा उपलब्ध नहीं है.
- ये जोड़ें: CONFIG_DYNAMIC_FTRACE=y, CONFIG_FUNCTION_TRACER=y, CONFIG_IRQSOFF_TRACER=y, CONFIG_FUNCTION_PROFILER=y, और CONFIG_PREEMPT_TRACER=y
- नया कर्नेल फिर से बनाएं और उसे बूट करें.
- उपलब्ध ट्रैसर की जांच करने के लिए, यह तरीका अपनाएं:
cat /sys/kernel/tracing/available_tracers
- पुष्टि करें कि यह कमांड
function
,irqsoff
,preemptoff
, औरpreemptirqsoff
दिखाता है. - डाइनैमिक ftrace के काम करने की पुष्टि करने के लिए, यह तरीका अपनाएं:
cat /sys/kernel/tracing/available_filter_functions | grep <a function you care about>
इन चरणों को पूरा करने के बाद, आपके पास डाइनैमिक ftrace, फ़ंक्शन प्रोफ़ाइलर, irqsoff प्रोफ़ाइलर, और preemptoff प्रोफ़ाइलर उपलब्ध होगा. हमारा सख्त सुझाव है कि इनका इस्तेमाल करने से पहले, इन विषयों पर ftrace दस्तावेज़ पढ़ें, क्योंकि ये काफ़ी असरदार, लेकिन जटिल हैं. irqsoff और preemptoff मुख्य रूप से इस बात की पुष्टि करने के लिए काम के हैं कि ड्राइवर, इंटरप्ट को बंद कर रहे हैं या प्रीएमप्शन को बहुत देर तक बंद कर रहे हैं.
फ़ंक्शन प्रोफ़ाइलर, परफ़ॉर्मेंस से जुड़ी समस्याओं के लिए सबसे अच्छा विकल्प है. इसका इस्तेमाल अक्सर यह पता लगाने के लिए किया जाता है कि किसी फ़ंक्शन को कहां से कॉल किया जा रहा है.
अगर फ़ंक्शन प्रोफ़ाइलर का डेटा ज़रूरत के मुताबिक नहीं है, तो फ़ंक्शन प्रोफ़ाइलर के साथ ftrace ट्रैसपॉइंट को जोड़ा जा सकता है. ftrace इवेंट को ठीक उसी तरह चालू किया जा सकता है जिस तरह आम तौर पर किया जाता है. साथ ही, इन्हें आपके ट्रैस के साथ इंटरलीव किया जाएगा.
अगर आपको किसी फ़ंक्शन में, कभी-कभी लंबे समय तक रुकावट के बिना स्लीप मोड में रहने की समस्या को डीबग करना है, तो यह तरीका अपनाएं: अपने पसंदीदा फ़ंक्शन पर ftrace फ़िल्टर सेट करें, ट्रैकपॉइंट चालू करें, और ट्रैक करें. trace2html
का इस्तेमाल करके, ट्रैक से मिले डेटा को पार्स किया जा सकता है. इसके बाद, अपनी पसंद का इवेंट ढूंढें और रॉ ट्रैक में आस-पास के स्टैक ट्रैक पाएं.
lockstat का इस्तेमाल करना
कभी-कभी, ftrace का इस्तेमाल करने से समस्या का पता नहीं चलता. ऐसे में, आपको कर्नेल लॉक कॉन्टेंटेशन को डीबग करना पड़ता है. एक और कर्नेल विकल्प आज़माया जा सकता है:
CONFIG_LOCK_STAT
. यह आखिरी विकल्प है, क्योंकि Android डिवाइसों पर इसे काम कराना काफ़ी मुश्किल होता है. इसकी वजह यह है कि इससे कर्नेल का साइज़, ज़्यादातर डिवाइसों के लिए तय किए गए साइज़ से ज़्यादा हो जाता है.
हालांकि, lockstat, डीबग करने के लिए ऐप्लिकेशन को लॉक करने वाले इंफ़्रास्ट्रक्चर का इस्तेमाल करता है. यह कई अन्य ऐप्लिकेशन के लिए काम का है. डिवाइस को चालू करने पर दिखने वाले विकल्प को हर डिवाइस पर काम करने लायक बनाने के लिए, डिवाइस को चालू करने पर दिखने वाले विकल्प पर काम करने वाले सभी लोगों को कोई तरीका ढूंढना चाहिए. ऐसा इसलिए, क्योंकि ऐसा समय आएगा, जब आपको लगेगा कि "काश LOCK_STAT
को चालू किया जा सकता, तो पांच दिन के बजाय पांच मिनट में इस समस्या की पुष्टि की जा सकती थी या उसे गलत बताया जा सकता था."
अगर कॉन्फ़िगरेशन विकल्प की मदद से कर्नेल को बूट किया जा सकता है, तो लॉक ट्रैकिंग, ftrace जैसी ही होती है:
- ट्रैकिंग की सुविधा चालू करना:
echo 1 > /proc/sys/kernel/lock_stat
- अपना टेस्ट चलाएं.
- ट्रैकिंग बंद करने के लिए:
echo 0 > /proc/sys/kernel/lock_stat
- अपना ट्रेस डंप करें:
cat /proc/lock_stat > /data/local/tmp/lock_stat
नतीजों के बारे में जानने के लिए, <kernel>/Documentation/locking/lockstat.txt
पर lockstat दस्तावेज़ देखें.
वेंडर के ट्रेसपॉइंट का इस्तेमाल करना
सबसे पहले अपस्ट्रीम ट्रेसपॉइंट का इस्तेमाल करें. हालांकि, कभी-कभी आपको वेंडर ट्रेसपॉइंट का इस्तेमाल करना पड़ सकता है:
{ "gfx", "Graphics", ATRACE_TAG_GRAPHICS, { { OPT, "events/mdss/enable" }, { OPT, "events/sde/enable" }, { OPT, "events/mali_systrace/enable" }, } },
HAL सेवा की मदद से, ट्रेसपॉइंट को बढ़ाया जा सकता है. इससे, डिवाइस के हिसाब से ट्रेसपॉइंट/कैटगरी जोड़ी जा सकती हैं. ट्रेसपॉइंट को, perfetto, atrace/systrace, और डिवाइस पर मौजूद सिस्टम ट्रैकिंग ऐप्लिकेशन के साथ इंटिग्रेट किया गया है.
ट्रेसपॉइंट/कैटगरी लागू करने के लिए ये एपीआई इस्तेमाल किए जा सकते हैं:
- listCategories() (vec<TracingCategory> categories) जनरेट करता है;
- enableCategories(vec<string> categories) से (Status status) जनरेट होता है;
- disableAllCategories() (Status status) जनरेट करता है;