हमने Chrome 92 में, मेमोरी इंस्पेक्टर टूल को लॉन्च किया है. यह लीनियर मेमोरी बफ़र की जांच करने के लिए इस्तेमाल किया जाता है. इस लेख में, हम C/C++ डीबगिंग के लिए इंस्पेक्टर को बेहतर बनाने के तरीके और इस दौरान आने वाली तकनीकी चुनौतियों के बारे में चर्चा करेंगे.
अगर आपने C/C++ डीबगिंग और मेमोरी इंस्पेक्टर का इस्तेमाल पहले कभी नहीं किया है, तो यहां कुछ काम की ब्लॉग पोस्ट दी गई हैं:
- क्या आपको मेमोरी की गहराई से डीबग करने में दिलचस्पी है? पेश है मेमोरी इंस्पेक्टर लेख पढ़ें.
- क्या आपको C/C++ डीबगिंग टूल के पूरे सुइट के बारे में जानकारी चाहिए? आधुनिक टूल की मदद से WASM को डीबग करना और WebAssembly को तेज़ी से डीबग करना लेख पढ़ें.
परिचय
मेमोरी इंस्पेक्टर, लीनियर मेमोरी बफ़र के लिए डीबग करने के ज़्यादा बेहतर विकल्प उपलब्ध कराता है. C/C++ के मामले में, WebAssembly मेमोरी में C/C++ मेमोरी ऑब्जेक्ट की जांच की जा सकती है.
आस-पास मौजूद WebAssembly मेमोरी में अपने ऑब्जेक्ट के बाइट को पहचानना मुश्किल था. आपको ऑब्जेक्ट का साइज़ पता होना चाहिए और ऑब्जेक्ट की शुरुआत से बाइट की गिनती करनी होगी. नीचे दिए गए स्क्रीनशॉट में, 10 एलिमेंट वाले int32
कलेक्शन का पहला बाइट चुना गया है. हालांकि, यह तुरंत पता नहीं चलता कि कौनसे अन्य बाइट कलेक्शन से जुड़े हैं. क्या यह अच्छा नहीं होगा, अगर ऑब्जेक्ट से जुड़े सभी बाइट को तुरंत पहचाना जा सके?
मेमोरी इंस्पेक्टर में ऑब्जेक्ट को हाइलाइट करना
Chrome 107 से, मेमोरी इंस्पेक्टर, C/C++ मेमोरी ऑब्जेक्ट के सभी बाइट को हाइलाइट करता है. इससे, उन्हें आस-पास मौजूद मेमोरी से अलग करने में मदद मिलती है.
मेमोरी इंस्पेक्टर के काम करने का तरीका जानने के लिए, नीचे दिया गया वीडियो देखें. मेमोरी इंस्पेक्टर में ऐरे x
को दिखाने पर, मेमोरी व्यूअर में हाइलाइट की गई मेमोरी दिखती है. साथ ही, उसके ठीक ऊपर एक नई चिप दिखती है. यह चिप, हाइलाइट की गई मेमोरी का नाम और टाइप याद दिलाता है. ऑब्जेक्ट की मेमोरी पर जाने के लिए, चिप पर क्लिक करें. चिप पर कर्सर घुमाने पर, क्रॉस आइकॉन दिखेगा. हाइलाइट हटाने के लिए उस पर क्लिक करें.
जब जांचे जा रहे ऑब्जेक्ट के बाहर कोई बाइट चुना जाता है, तो आपका ध्यान भटकने से बचाने के लिए, हाइलाइट हट जाती है. फिर से फ़ोकस करने के लिए, ऑब्जेक्ट के किसी भी बाइट या चिप पर फिर से क्लिक करें.
ऑब्जेक्ट को हाइलाइट करने की सुविधा, सिर्फ़ ऐरे तक सीमित नहीं है. स्ट्रक्चर, ऑब्जेक्ट, और पॉइंटर की जांच भी की जा सकती है. इन बदलावों से, C/C++ ऐप्लिकेशन की मेमोरी को एक्सप्लोर करना पहले से ज़्यादा आसान हो गया है!
क्या आपको इसे आज़माना है? आपको ये काम करने होंगे:
- आपके पास Chrome 107 या इसके बाद का वर्शन हो.
- C/C++ DWARF एक्सटेंशन इंस्टॉल करें.
- DevTools >
सेटिंग > प्रयोग > WebAssemble डीबगिंग: DWARF सहायता चालू करें में जाकर, DWARF डीबगिंग की सुविधा चालू करें.
- यह डेमो पेज खोलें.
- पेज पर दिए गए निर्देशों का पालन करें.
डीबग करने का उदाहरण
इस सेक्शन में, एक टॉय बग के बारे में जानें. इससे आपको यह समझने में मदद मिलेगी कि C/C++ को डीबग करने के लिए, मेमोरी इंस्पेक्टर का इस्तेमाल कैसे किया जा सकता है. नीचे दिए गए कोड सैंपल में, प्रोग्रामर ने इंटेजर कलेक्शन बनाया है. साथ ही, आखिरी एलिमेंट चुनने के लिए पॉइंटर अंकगणित का इस्तेमाल करने का फ़ैसला लिया है. माफ़ करें, प्रोग्रामर ने पॉइंटर की गिनती में गलती की है और अब प्रोग्राम आखिरी एलिमेंट के बजाय, बेमतलब की वैल्यू प्रिंट करता है.
#include <iostream>
int main()
{
int numbers[] = {1, 2, 3, 4};
int *ptr = numbers;
int arraySize = sizeof(numbers)/sizeof(int);
int* lastNumber = ptr + arraySize; // Can you notice the bug here?
std::cout <<../ *lastNumber <<../ '\n';
return 0;
}
प्रोग्रामर, समस्या को डीबग करने के लिए मेमोरी इंस्पेक्टर का इस्तेमाल करता है. इस डेमो को देखकर, इस बारे में ज़्यादा जानें! वे सबसे पहले मेमोरी इंस्पेक्टर में ऐरे की जांच करते हैं और देखते हैं कि numbers
ऐरे में सिर्फ़ पूर्णांक 1
, 2
, 3
, और 4
हैं, जैसा कि उम्मीद थी.
इसके बाद, वे स्कोप पैनल से lastNumber
वैरिएबल दिखाते हैं और देखते हैं कि पॉइंटर, ऐरे के बाहर मौजूद किसी पूर्णांक पर ले जाता है! इस जानकारी के आधार पर, प्रोग्रामर को पता चलता है कि उन्होंने लाइन 8 पर पॉइंटर ऑफ़सेट की गलत गिनती की है. यह ptr + arraySize - 1
होना चाहिए था.
यह एक छोटा उदाहरण है, लेकिन इससे पता चलता है कि ऑब्जेक्ट को हाइलाइट करने से, मेमोरी ऑब्जेक्ट का साइज़ और पोज़िशन असरदार तरीके से कैसे पता चलती है. इससे आपको यह समझने में मदद मिलती है कि आपके C/C++ ऐप्लिकेशन की मेमोरी में क्या हो रहा है.
DevTools यह कैसे तय करता है कि क्या हाइलाइट करना है
इस सेक्शन में, हम उन टूल के नेटवर्क के बारे में जानेंगे जिनकी मदद से C/C++ को डीबग किया जा सकता है. खास तौर पर, आपको यह जानकारी मिलेगी कि DevTools, V8, C/C++ DWARF एक्सटेंशन, और Emscripten, Chrome में C/C++ को कैसे डीबग करते हैं.
DevTools में C/C++ की गड़बड़ी को ठीक करने की सुविधा का पूरा फ़ायदा पाने के लिए, आपको इन दो चीज़ों की ज़रूरत है:
- Chrome में इंस्टॉल किया गया C/C++ DWARF एक्सटेंशन
- C/C++ सोर्स फ़ाइलें, इस ब्लॉग पोस्ट में दिए गए निर्देशों के मुताबिक, नए Emscripten कंपाइलर की मदद से WebAssembly में कंपाइल की गई हों
लेकिन क्यों? Chrome का JavaScript और WebAssembly इंजन V8, C या C++ को चलाने का तरीका नहीं जानता. हालांकि, C/C++ को WebAssembly में बदलने वाले कंपाइलर Emscripten की मदद से, C या C++ में बनाए गए ऐप्लिकेशन को WebAssembly के तौर पर कंपाइल किया जा सकता है और उन्हें ब्राउज़र में चलाया जा सकता है!
कंपाइल करने के दौरान, emscripten आपकी बाइनरी में DWARF डीबग डेटा को एम्बेड करेगा. इस डेटा से, एक्सटेंशन को यह पता लगाने में मदद मिलती है कि आपके C/C++ वैरिएबल से कौनसे WebAssembly वैरिएबल मेल खाते हैं. इस तरह, DevTools आपको C++ वैरिएबल दिखा सकता है, भले ही V8 में WebAssembly चल रही हो. अगर आपको DWARF डीबग डेटा का उदाहरण देखना है, तो यह ब्लॉग पोस्ट देखें.
तो lastNumber
को ज़ाहिर करने पर क्या होता है? मेमोरी आइकॉन पर क्लिक करते ही, DevTools यह जांच करता है कि आपको किस वैरिएबल की जांच करनी है. इसके बाद, यह एक्सटेंशन से lastNumber
के डेटा टाइप और जगह के बारे में क्वेरी करता है. एक्सटेंशन से जानकारी मिलने के बाद, मेमोरी इंस्पेक्टर मेमोरी का ज़रूरी हिस्सा दिखा सकता है. साथ ही, ऑब्जेक्ट का साइज़ भी दिखा सकता है.
अगर आपने पिछले उदाहरण में lastNumber
को देखा है, तो आपको पता चल सकता है कि हमने lastNumber: int *
की जांच की है, लेकिन मेमोरी इंस्पेक्टर में मौजूद चिप में *lastNumber: int
दिखता है. ऐसा क्यों है? आपको दिखाए गए ऑब्जेक्ट के टाइप की जानकारी देने के लिए, इंस्पेक्टर C++ स्टाइल के पॉइंटर डीरेफ़रंसिंग का इस्तेमाल करता है! किसी पॉइंटर की जांच करने पर, आपको पता चलेगा कि वह किस चीज़ पर ले जाता है.
डीबगर के चरणों पर हाइलाइट को बनाए रखना
मेमोरी इंस्पेक्टर में किसी ऑब्जेक्ट को दिखाने और डीबगर के साथ आगे बढ़ने पर, इंस्पेक्टर हाइलाइट को तब तक बनाए रखता है, जब तक उसे लगता है कि वह अब भी लागू है. शुरुआत में, हमने इस सुविधा को अपने रोडमैप में शामिल नहीं किया था. हालांकि, हमें जल्द ही पता चला कि इससे डीबग करने के आपके अनुभव पर असर पड़ता है. कल्पना करें कि आपको हर चरण के बाद, ऐरे की फिर से जांच करनी पड़े, जैसा कि नीचे दिए गए वीडियो में दिखाया गया है!
जब डीबगर किसी नए ब्रेकपॉइंट पर पहुंचता है, तो मेमोरी इंस्पेक्टर, V8 और पिछले हाइलाइट से जुड़े वैरिएबल के एक्सटेंशन के लिए फिर से क्वेरी करता है. इसके बाद, यह ऑब्जेक्ट की जगहों और टाइप की तुलना करती है. अगर दोनों पैटर्न एक जैसे हैं, तो हाइलाइट बनी रहती है. ऊपर दिए गए वीडियो में, ऐरे x
में लिखने के लिए for-loop का इस्तेमाल किया गया है. इन कार्रवाइयों से ऐरे का टाइप या पोज़िशन नहीं बदलती, इसलिए यह हाइलाइट रहता है.
आपको शायद यह जानना हो कि इससे पॉइंटर पर क्या असर पड़ता है. अगर आपके पास हाइलाइट किया गया कोई पॉइंटर है और उसे किसी दूसरे ऑब्जेक्ट पर फिर से असाइन किया जाता है, तो हाइलाइट किए गए ऑब्जेक्ट की पुरानी और नई पोज़िशन अलग-अलग हो जाती है. साथ ही, हाइलाइट हट जाती है. जिस ऑब्जेक्ट पर फ़िलहाल कर्सर है वह WebAssembly मेमोरी में कहीं भी हो सकता है. साथ ही, हो सकता है कि उसका पिछली मेमोरी लोकेशन से कोई लेना-देना न हो. इसलिए, नई मेमोरी लोकेशन पर जाने के बजाय, हाइलाइट हटाना बेहतर होता है. स्कोप पैनल में, पॉइंटर के मेमोरी आइकॉन पर क्लिक करके, उसे फिर से हाइलाइट किया जा सकता है.
नतीजा
इस लेख में, C/C++ को डीबग करने के लिए, मेमोरी इंस्पेक्टर में किए गए सुधारों के बारे में बताया गया है. हमें उम्मीद है कि इन नई सुविधाओं की मदद से, C/C++ ऐप्लिकेशन की मेमोरी को डीबग करना आसान हो जाएगा! अगर आपको इसे और बेहतर बनाने के लिए सुझाव हैं, तो गड़बड़ी की शिकायत करें!
अब क्या होगा
ज़्यादा जानने के लिए, ये देखें: