Amazon Best VPN GoSearch

ऑनवर्क्स फ़ेविकॉन

पर्लहैकटिप्स - क्लाउड में ऑनलाइन

उबंटू ऑनलाइन, फेडोरा ऑनलाइन, विंडोज ऑनलाइन एमुलेटर या मैक ओएस ऑनलाइन एमुलेटर पर ऑनवर्क्स फ्री होस्टिंग प्रदाता में पर्लहैकटिप्स चलाएं।

यह कमांड पर्लहैकटिप्स है जिसे हमारे कई मुफ्त ऑनलाइन वर्कस्टेशन जैसे कि उबंटू ऑनलाइन, फेडोरा ऑनलाइन, विंडोज ऑनलाइन एमुलेटर या मैक ओएस ऑनलाइन एमुलेटर का उपयोग करके ऑनवर्क्स फ्री होस्टिंग प्रदाता में चलाया जा सकता है।

कार्यक्रम:

नाम


perlhacktips - पर्ल कोर सी कोड हैकिंग के लिए टिप्स

वर्णन


यह दस्तावेज़ आपको पर्ल कोर सी पर हैकिंग का सर्वोत्तम तरीका सीखने में मदद करेगा
कोड. इसमें सामान्य समस्याएं, डिबगिंग, प्रोफाइलिंग और बहुत कुछ शामिल है।

यदि आपने अभी तक पर्लहैक और पर्लहैकटट नहीं पढ़ा है, तो हो सकता है कि आप पहले वह करना चाहें।

आम समस्याओं


पर्ल स्रोत ANSI C89 नियमों के अनुसार चलता है: कोई C99 (या C++) एक्सटेंशन नहीं। कुछ मामलों में हमें करना होगा
पूर्व-एएनएसआई आवश्यकताओं को ध्यान में रखें। आपको किसी खास बात की परवाह नहीं है
प्लेटफ़ॉर्म पर्ल टूट गया है? मैंने सुना है कि J2EE प्रोग्रामर्स की अभी भी भारी मांग है।

पर्ल वातावरण समस्याओं
· थ्रेडिंग के साथ संकलन नहीं करना

थ्रेडिंग (-Duseithreads) के साथ संकलन फ़ंक्शन प्रोटोटाइप को पूरी तरह से फिर से लिखता है
पर्ल का. बेहतर होगा कि आप उसके साथ अपने बदलावों को आज़माएँ। इसी से सम्बंधित अंतर है
उदाहरण के लिए, "Perl_-less" और "Perl_-ly" API के बीच:

Perl_sv_setiv(aTHX_...);
sv_setiv(...);

पहला संदर्भ में स्पष्ट रूप से गुजरता है, जो उदाहरण के लिए थ्रेडेड के लिए आवश्यक है
बनाता है. दूसरा ऐसा परोक्ष रूप से करता है; उन्हें मिश्रित न करें. अगर आप नहीं हैं तो
aTHX_ में पास होने पर, आपको सबसे पहले एक dTHX (या एक dVAR) करने की आवश्यकता होगी
समारोह.

आगे के लिए पर्लगट्स में "कैसे एकाधिक दुभाषिए और समवर्ती समर्थित हैं" देखें
संदर्भ के बारे में चर्चा.

· -DDEBUGGING के साथ संकलन नहीं किया जा रहा है

डिबगिंग डिफाइन कंपाइलर के लिए अधिक कोड को उजागर करता है, इसलिए चीजों के लिए और अधिक तरीके
गलत जाने के लिए। आपको यह कोशिश करनी चाहिए।

· परिचय (केवल पढ़ने योग्य नहीं) ग्लोबल्स

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

रीड-ओनली (कॉन्स्ट) ग्लोबल्स का परिचय देना ठीक है, जब तक आप उदाहरण के लिए "एनएम" से सत्यापित करते हैं
libperl.a|egrep -v ' [TURtr] '' (यदि आपके "एनएम" में बीएसडी-शैली आउटपुट है) तो आपका डेटा
जोड़ा गया वास्तव में केवल पढ़ने योग्य है। (यदि ऐसा है, तो इसे उसके आउटपुट में नहीं दिखना चाहिए
आदेश।)

यदि आप स्थिर स्ट्रिंग्स चाहते हैं, तो उन्हें स्थिर बनाएं:

स्थिर स्थिरांक चार आदि[] = "...";

यदि आप निरंतर स्ट्रिंग्स की सारणी चाहते हैं, तो सही संयोजन को ध्यान से नोट करें
"स्थिरांक" का:

स्थिर स्थिरांक चार * स्थिरांक यिप्पी[] =
{"हाय", "हो", "सिल्वर"};

किसी भी परिवर्तनीय ग्लोबल्स को पूरी तरह से छिपाने का एक तरीका है (वे सभी ढेर में ले जाये जाते हैं),
संकलन सेटिंग "-DPERL_GLOBAL_STRUCT_PRIVATE"। यह आमतौर पर उपयोग नहीं किया जाता है, लेकिन
परीक्षण के लिए उपयोग किया जा सकता है, इसके बारे में "पृष्ठभूमि और PERL_IMPLICIT_CONTEXT" में और पढ़ें
पर्लगुट्स में।

· आपका नया फ़ंक्शन निर्यात नहीं हो रहा है

कुछ प्लेटफ़ॉर्म (Win32, AIX, VMS, OS/2, कुछ नाम रखने के लिए) को किसी भी फ़ंक्शन की आवश्यकता होती है
सार्वजनिक एपीआई (साझा पर्ल लाइब्रेरी) का हिस्सा स्पष्ट रूप से निर्यात के रूप में चिह्नित किया जाना है।
के बारे में चर्चा देखें एम्बेड.pl पर्लगुट्स में।

· अपना नया फ़ंक्शन निर्यात करना

या तो वास्तविक नई कार्यक्षमता या आपके कठिन रिफैक्टरिंग का नया चमकदार परिणाम
अब तैयार है और सही ढंग से निर्यात किया गया है। तो संभवतः क्या ग़लत हो सकता है?

शायद बस यह कि आपके फ़ंक्शन को पहले स्थान पर निर्यात करने की आवश्यकता नहीं थी। पर्ल
निर्यात कार्यों का एक लंबा और इतना गौरवशाली इतिहास नहीं है जितना इसे नहीं होना चाहिए था।

यदि फ़ंक्शन का उपयोग केवल एक स्रोत कोड फ़ाइल के अंदर किया जाता है, तो इसे स्थिर बनाएं। देखें
के बारे में चर्चा एम्बेड.pl पर्लगुट्स में।

यदि फ़ंक्शन का उपयोग कई फ़ाइलों में किया जाता है, लेकिन केवल पर्ल के आंतरिक के लिए अभिप्रेत है
उपयोग करें (और यह सामान्य मामला होना चाहिए), इसे सार्वजनिक एपीआई पर निर्यात न करें। देखें
के बारे में चर्चा एम्बेड.pl पर्लगुट्स में।

सुवाह्यता समस्याओं
संकलन और/या निष्पादन विफलताओं के निम्नलिखित सामान्य कारण हैं, जो सामान्य नहीं हैं
पर्ल जैसे. सी एफएक्यू सोते समय पढ़ना अच्छा है। कृपया अधिक से अधिक सी के साथ अपने परिवर्तनों का परीक्षण करें
यथासंभव संकलक और प्लेटफ़ॉर्म; हम, वैसे भी करेंगे, और स्वयं को इससे बचाना अच्छा है
सार्वजनिक शर्मिंदगी.

यदि जीसीसी का उपयोग कर रहे हैं, तो आप "-std=c89" विकल्प जोड़ सकते हैं जो उम्मीद है कि इनमें से अधिकांश को पकड़ लेगा
अनपोर्टेबिलिटीज़ (हालांकि यह आपके सिस्टम के हेडर में असंगतताएं भी पकड़ सकता है
फ़ाइलें।)

जीसीसी "-ansi -pedantic" झंडे को सक्षम करने के लिए कॉन्फ़िगर करें "-Dgccansipedantic" ध्वज का उपयोग करें जो
सख्त एएनएसआई नियम लागू करें।

यदि "gcc -Wall" का उपयोग कर रहे हैं तो ध्यान दें कि सभी संभावित चेतावनियाँ नहीं हैं (जैसे "-Wunitialized")
तब तक दिए जाते हैं जब तक आप "-O" का संकलन भी नहीं करते।

ध्यान दें कि यदि जीसीसी का उपयोग कर रहे हैं, तो पर्ल 5.9.5 से शुरू करके पर्ल कोर स्रोत कोड फ़ाइलें (वे)
स्रोत कोड वितरण के शीर्ष स्तर पर, लेकिन उदाहरण के लिए ext/ के अंतर्गत एक्सटेंशन नहीं)
स्वचालित रूप से यथासंभव "-std=c89", "-ansi" के साथ संकलित किया जाता है।
"-पेडेंटिक", और "-W" झंडों का चयन (cflags.SH देखें)।

ऑपरेटिंग सिस्टम के बारे में किसी भी बुरी धारणा से बचने के लिए पर्लपोर्ट का भी ध्यानपूर्वक अध्ययन करें,
फ़ाइल सिस्टम, कैरेक्टर सेट, इत्यादि।

आप कभी-कभी यह देखने के लिए "माइक्रोपर्ल बनाएं" आज़मा सकते हैं कि क्या हम अभी भी पर्ल को संकलित कर सकते हैं
न्यूनतम इंटरफ़ेस के साथ। (रीडमी.माइक्रो देखें।)

यह न मानें कि एक ऑपरेटिंग सिस्टम एक निश्चित कंपाइलर को इंगित करता है।

· पॉइंटर्स को पूर्णांकों में कास्ट करना या पूर्णांकों को पॉइंटर्स में कास्ट करना

शून्य निष्कासन(U8* p)
{
चतुर्थ मैं = पी;

or

शून्य निष्कासन(U8* p)
{
चतुर्थ मैं = (चतुर्थ)पी;

दोनों खराब हैं, टूटे हुए हैं और ले जाने योग्य नहीं हैं। उपयोग PTR2IV() मैक्रो जो इसे सही करता है।
(इसी तरह, वहाँ भी हैं PTR2UV(), PTR2NV(), INT2PTR(), तथा NUM2PTR().)

· फ़ंक्शन पॉइंटर्स और डेटा पॉइंटर्स के बीच कास्टिंग

तकनीकी रूप से फ़ंक्शन पॉइंटर्स और डेटा पॉइंटर्स के बीच कास्टिंग अप्राप्य है
और अपरिभाषित, लेकिन व्यावहारिक रूप से यह काम करता प्रतीत होता है, लेकिन आपको इसका उपयोग करना चाहिए
एफपीटीआर2डीपीटीआर() और DPTR2FPTR() मैक्रोज़. कभी-कभी आप यूनियनों के साथ भी गेम खेल सकते हैं।

· मान लिया गया sizeof(int) == sizeof(long)

ऐसे प्लेटफ़ॉर्म हैं जहां लॉन्ग 64 बिट हैं, और प्लेटफ़ॉर्म जहां इंट्स 64 बिट हैं, और
जबकि हम आपको आश्चर्यचकित करने के लिए निकले हैं, यहां तक ​​​​कि ऐसे प्लेटफ़ॉर्म भी जहां शॉर्ट्स 64 बिट हैं। यह सब है
सी मानक के अनुसार कानूनी। (दूसरे शब्दों में, "लॉन्ग लॉन्ग" पोर्टेबल तरीका नहीं है
64 बिट्स निर्दिष्ट करने के लिए, और "लॉन्ग लॉन्ग" से अधिक व्यापक होने की भी गारंटी नहीं है
"लंबा"।)

इसके बजाय, IV, UV, IVSIZE, I32SIZE इत्यादि परिभाषाओं का उपयोग करें। जैसी चीजों से बचें
I32 क्योंकि वे हैं नहीं होने की गारंटी है ठीक ठीक 32 बिट्स, वे हैं at कम से कम 32 बिट,
न ही उनके होने की गारंटी है int or लंबा. यदि आपको वास्तव में स्पष्ट रूप से 64-बिट की आवश्यकता है
चर, I64 और U64 का उपयोग करें, लेकिन केवल तभी जब HAS_QUAD द्वारा संरक्षित हो।

· यह मानते हुए कि कोई किसी भी प्रकार के डेटा के लिए किसी भी प्रकार के पॉइंटर को डीरेफ़रेंस कर सकता है

चार *पी = ...;
लंबी टट्टू = *पी; /* खराब */

बहुत से प्लेटफ़ॉर्म, बिल्कुल सही, आपको टट्टू के बजाय एक कोर डंप देंगे यदि पी
ऐसा होता है कि सही ढंग से संरेखित नहीं किया गया है।

· लवल्यू कास्ट

(int)*p = ...; /* खराब */

बस पोर्टेबल नहीं है. अपना लैवल्यू सही प्रकार का बनाएं, या शायद अस्थायी का उपयोग करें
चर, या यूनियनों के साथ गंदी चालें।

· मान लीजिए कुछ भी संरचनाओं के बारे में (विशेष रूप से जिन्हें आप नियंत्रित नहीं करते हैं, जैसे कि वे)।
सिस्टम हेडर से आ रहा है)

· किसी संरचना में एक निश्चित क्षेत्र मौजूद होता है

· जिनके बारे में आप जानते हैं उनके अलावा कोई अन्य क्षेत्र मौजूद नहीं है

· यह कि कोई फ़ील्ड निश्चित हस्ताक्षर, आकार या प्रकार का है

· यह कि फ़ील्ड एक निश्चित क्रम में हैं

· जबकि सी संरचना परिभाषा में निर्दिष्ट आदेश की गारंटी देता है,
विभिन्न प्लेटफार्मों के बीच परिभाषाएँ भिन्न हो सकती हैं

· कि आकार (संरचना) या संरेखण हर जगह समान हैं

· फ़ील्ड को संरेखित करने के लिए फ़ील्ड के बीच पैडिंग बाइट्स हो सकते हैं -
बाइट्स कुछ भी हो सकते हैं

· संरचनाओं को आवश्यक अधिकतम संरेखण के अनुसार संरेखित करना आवश्यक है
फ़ील्ड्स द्वारा - जो मूल प्रकारों के लिए आमतौर पर समकक्ष होता है
का आकार() क्षेत्र का

· यह मानते हुए कि वर्ण सेट ASCIIIish है

पर्ल ईबीसीडीआईसी प्लेटफॉर्म के तहत संकलित और चला सकता है। पेरलेबसीडिक देखें। यह पारदर्शी है
अधिकांश भाग के लिए, लेकिन क्योंकि वर्ण सेट अलग-अलग हैं, इसलिए आपको संख्यात्मक का उपयोग नहीं करना चाहिए
(दशमलव, अष्टाधारी, न ही हेक्स) वर्णों को संदर्भित करने के लिए स्थिरांक। आप सुरक्षित रूप से 'ए' कह सकते हैं,
लेकिन 0x41 नहीं. आप सुरक्षित रूप से '\n' कह सकते हैं, लेकिन "\012" नहीं। हालाँकि, आप मैक्रोज़ का उपयोग कर सकते हैं
में परिभाषित किया गया यूटीएफ8.एच किसी भी कोड बिंदु को पोर्टेबल रूप से निर्दिष्ट करने के लिए। "LATIN1_TO_NATIVE(0xDF)" है
किसी भी प्लेटफ़ॉर्म पर कोड बिंदु होने जा रहा है जिसका अर्थ है लैटिन छोटा अक्षर SHARP S
आप इसे चला रहे हैं (ASCII प्लेटफ़ॉर्म पर यह बिना कोई अतिरिक्त कोड जोड़े संकलित होता है, इसलिए
उन पर शून्य प्रदर्शन प्रभाव है)। "LATIN1_TO_NATIVE" के लिए स्वीकार्य इनपुट
0x00 से 0xFF तक हैं। यदि आपका इनपुट उस सीमा में होने की गारंटी नहीं है, तो उपयोग करें
इसके बजाय "UNICODE_TO_NATIVE"। "NATIVE_TO_LATIN1" और "NATIVE_TO_UNICODE" का अनुवाद करें
उल्टी दिशा।

यदि आपको किसी ऐसे वर्ण की स्ट्रिंग प्रस्तुति की आवश्यकता है जिसका कोई स्मरणीय नाम नहीं है
सी में, आपको इसे सूची में जोड़ना चाहिए रीजेन/यूनिकोड_कॉन्स्टैंट्स.पीएल, और पर्ल है
वर्तमान प्लेटफ़ॉर्म के आधार पर, आपके लिए "#define" बनाएँ।

ध्यान दें कि "हैफू" और करने के लिएफू" मैक्रोज़ में सुविधाजनक.एच मूल कोड पर ठीक से काम करें
बिंदु और तार.

साथ ही, ASCII में रेंज 'A' - 'Z' 26 अपर केस अल्फाबेटिक का एक अटूट क्रम है
पात्र। ईबीसीडीआईसी में यह सत्य नहीं है। न ही 'a' से 'z' के लिए. लेकिन '0' - '9' एक है
दोनों प्रणालियों में अटूट सीमा। अन्य श्रेणियों के बारे में कुछ भी न मानें। (ध्यान दें कि
नियमित अभिव्यक्ति पैटर्न में श्रेणियों की विशेष हैंडलिंग इसे पर्ल कोड में प्रदर्शित करती है
उपरोक्त सभी श्रेणियाँ अखंडित हैं।)

मौजूदा कोड में कई टिप्पणियाँ EBCDIC की संभावना को नजरअंदाज करती हैं, और हो भी सकती हैं
इसलिए गलत है, भले ही कोड काम करता हो। यह वास्तव में सफल लोगों को श्रद्धांजलि है
पूर्व परिवर्तन किए बिना ईबीसीडीआईसी को संभालने में सक्षम होने का पारदर्शी सम्मिलन
मौजूदा कोड.

यूटीएफ-8 और यूटीएफ-ईबीसीडीआईसी दो अलग-अलग एन्कोडिंग हैं जिनका उपयोग यूनिकोड कोड बिंदुओं को दर्शाने के लिए किया जाता है
बाइट्स के अनुक्रम के रूप में। मैक्रोज़ समान नाम (लेकिन अलग-अलग परिभाषाएँ) के साथ
यूटीएफ8.एच और utfebcdic.h कॉलिंग कोड को यह सोचने की अनुमति देने के लिए उपयोग किया जाता है कि केवल वहाँ है
ऐसी ही एक एन्कोडिंग. इसे लगभग हमेशा "utf8" के रूप में संदर्भित किया जाता है, लेकिन इसका अर्थ है
ईबीसीडीआईसी संस्करण भी। फिर, कोड में टिप्पणियाँ गलत भी हो सकती हैं
कोड ही सही है. उदाहरण के लिए, UTF-8 "अपरिवर्तनीय वर्ण" की अवधारणा
ASCII और EBCDIC के बीच अंतर. ASCII प्लेटफ़ॉर्म पर, केवल वे वर्ण जो ऐसा नहीं करते
उच्च-क्रम बिट सेट हैं (अर्थात् जिनके क्रम-निर्देश सख्त ASCII, 0 - 127 हैं) हैं
अपरिवर्तनीय, और कोड में प्रलेखन और टिप्पणियाँ अक्सर ऐसा मान सकती हैं
किसी चीज़ का जिक्र करते हुए, कहें, "हिबिट"। स्थिति अलग है और इतनी सरल नहीं है
EBCDIC मशीनों पर, लेकिन जब तक कोड स्वयं "NATIVE_IS_INVARIANT()" का उपयोग करता है
मैक्रो उचित रूप से, यह काम करता है, भले ही टिप्पणियाँ गलत हों।

जैसा कि पर्लहैक में "टेस्टिंग" में बताया गया है, परीक्षण स्क्रिप्ट लिखते समय, फ़ाइल
टी/charset_tools.pl इसमें दोनों पर मान्य परीक्षण लिखने के लिए कुछ उपयोगी कार्य शामिल हैं
ASCII और EBCDIC प्लेटफॉर्म। हालाँकि, कभी-कभी एक परीक्षण किसी फ़ंक्शन का उपयोग नहीं कर सकता है और यह है
प्लेटफ़ॉर्म के आधार पर अलग-अलग परीक्षण संस्करण रखना असुविधाजनक है। 20 हैं
कोड बिंदु जो वर्तमान में पर्ल द्वारा मान्यता प्राप्त सभी 4 वर्ण सेटों में समान हैं
(3 ईबीसीडीआईसी कोड पेज प्लस आईएसओ 8859-1 (एएससीआईआई/लैटिन1))। ऐसे में इनका उपयोग किया जा सकता है
परीक्षण, हालाँकि इस बात की बहुत कम संभावना है कि पर्ल अभी उपलब्ध हो सकेगा
एक और चरित्र सेट, आपके परीक्षण को तोड़ रहा है। इनमें से एक को छोड़कर सभी कोड बिंदु C0 हैं
वर्णों को नियंत्रित करें. सबसे महत्वपूर्ण नियंत्रण जो समान हैं वे हैं "\0", "\r",
और "\N{VT}" ("\cK", "\x0B", "\N{U+0B}", या "\013" के रूप में भी निर्दिष्ट)। द सिंगल
गैर-नियंत्रण U+00B6 पिलक्रो साइन है। जो नियंत्रण समान हैं उनका बिट भी समान है
स्ट्रिंग की UTF4ness की परवाह किए बिना, सभी 8 वर्ण सेटों में पैटर्न
उन्हें। U+B6 के लिए बिट पैटर्न गैर-UTF4 स्ट्रिंग्स के लिए सभी 8 में समान है, लेकिन भिन्न है
प्रत्येक में जब इसकी युक्त स्ट्रिंग UTF-8 एन्कोडेड है। केवल अन्य कोड यही इंगित करता है
4xDC और 0xFC जोड़ी में सभी 0 वर्ण सेटों में कुछ प्रकार की समानता है।
ये सब मिलकर डायरेसिस के साथ अपरकेस और लोअरकेस लैटिन अक्षर यू का प्रतिनिधित्व करते हैं, लेकिन कौन सा
ऊपरी है और जो निचला है उसे उलटा किया जा सकता है: 0xDC लैटिन1 में पूंजी है और 0xFC है
छोटा अक्षर, जबकि 0xFC EBCDIC में बड़ा अक्षर है और 0xDC छोटा अक्षर है। यह
फैक्टोइड का उपयोग केस असंवेदनशील परीक्षणों को लिखने में किया जा सकता है जो कि समान हैं
सभी 4 वर्ण सेट.

· यह मानते हुए कि कैरेक्टर सेट सिर्फ ASCII है

ASCII एक 7 बिट एन्कोडिंग है, लेकिन बाइट्स में 8 बिट होते हैं। 128 अतिरिक्त अक्षर
स्थान के आधार पर अलग-अलग अर्थ होते हैं। कोई लोकेल अनुपस्थित, वर्तमान में ये
अतिरिक्त वर्णों को आम तौर पर असाइन नहीं किया गया माना जाता है, और यह प्रस्तुत किया गया है
कुछ समस्याएं। इसे 5.12 से बदला जा रहा है ताकि ये पात्र ऐसा कर सकें
लैटिन-1 (आईएसओ-8859-1) माना जाएगा।

· #define और #ifdef को मिलाना

#बर्गल(x) को परिभाषित करें... \
#ifdef BURGLE_OLD_STYLE /* खराब */
...इसे पुराने तरीके से करें...\
#else
...इसे नए तरीके से करें...\
#endif

आप सीपीपी निर्देशों को पोर्टेबल रूप से "स्टैक" नहीं कर सकते। उदाहरण के लिए उपरोक्त में आपको दो की आवश्यकता है
अलग सेंधमारी() #परिभाषित, प्रत्येक #ifdef शाखा के लिए एक।

· #endif या #else के बाद गैर-टिप्पणी सामग्री जोड़ना

#ifdef SNOSH
...
#अन्य !SNOSH /* खराब */
...
#endif SNOSH /* बुरा */

#endif और #else के बाद उनके बाद कुछ भी गैर-टिप्पणी नहीं हो सकती। अगर आप
क्या हो रहा है इसका दस्तावेजीकरण करना चाहते हैं (जो एक अच्छा विचार है, खासकर यदि शाखाएँ हैं
लंबा), (सी) टिप्पणियों का उपयोग करें:

#ifdef SNOSH
...
#अन्यथा /* !स्नोश*/
...
#endif /*SNOSH*/

जीसीसी विकल्प "-वेंडीफ़-लेबल्स" खराब संस्करण के बारे में चेतावनी देता है (प्रारंभ पर डिफ़ॉल्ट रूप से)।
पर्ल 5.9.4 से)।

· किसी एनम सूची के अंतिम तत्व के बाद अल्पविराम लगाना

एनम रंग {
सेरुलियन,
चार्टरेस,
सिनेबार, /* ख़राब */
};

पोर्टेबल नहीं है. अंतिम अल्पविराम छोड़ें.

यह भी ध्यान रखें कि क्या एनम्स अंतर्निहित रूप से इनट्स में रूपांतरित होते हैं, इसके बीच भिन्नता होती है
कंपाइलर्स, आपको (int) की आवश्यकता हो सकती है।

· //-टिप्पणियों का उपयोग करना

// यह फ़ंक्शन ज़ोर्कलेटर को बामफ़ूडल करता है। /* खराब */

वह C99 या C++ है। पर्ल C89 है. कई सी द्वारा //-टिप्पणियों का उपयोग करने की चुपचाप अनुमति है
कंपाइलर लेकिन ANSI C89 सख्ती (जो हम करना पसंद करते हैं) को क्रैंक करने से इसका कारण बनता है
विफल होने के लिए संकलन.

· घोषणाओं और कोड को मिलाना

शून्य ज़ोर्कलेटर()
{
इंट एन = 3;
set_zorkmids(n); /* खराब */
पूर्णांक क्यू = 4;

वह C99 या C++ है। कुछ सी कंपाइलर इसकी अनुमति देते हैं, लेकिन आपको ऐसा नहीं करना चाहिए।

जीसीसी विकल्प "-डब्ल्यूडिक्लेरेशन-आफ्टर-स्टेटमेंट्स" ऐसी समस्याओं के लिए स्कैन करता है (डिफ़ॉल्ट रूप से चालू)।
पर्ल 5.9.4 से शुरू करके)।

· अंदर चर का परिचय के लिए()

for(int i = ...; ...; ...) { /* BAD */

वह C99 या C++ है। हालाँकि इसे C89 में रखना वास्तव में बहुत अच्छा होगा,
अफसोस, हम लूप वेरिएबल के दायरे को सीमित नहीं कर सकते।

· हस्ताक्षरित चार पॉइंटर्स को अहस्ताक्षरित चार पॉइंटर्स के साथ मिलाना

int foo(char *s) { ... }
...
अहस्ताक्षरित चार *t = ...; /* या U8* t = ... */
पैर); /* खराब */

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

· मैक्रोज़ जिनमें स्ट्रिंग स्थिरांक और उनके तर्क स्ट्रिंग के सबस्ट्रिंग के रूप में होते हैं
स्थिर

#FOO(n) प्रिंटफ को परिभाषित करें('संख्या = %d\n', n) /* बुरा */
FOO; (10)

उसके लिए पूर्व-एएनएसआई शब्दार्थ के बराबर था

प्रिंटफ ("10ंबर = %d\10");

जो संभवतः वह नहीं है जिसकी आप अपेक्षा कर रहे थे। दुर्भाग्य से कम से कम एक उचित
सामान्य और आधुनिक सी कंपाइलर यहां, AIX में, "वास्तविक बैकवर्ड संगतता" करता है
अभी भी क्या होता है, भले ही बाकी AIX कंपाइलर बहुत ख़ुशी से C89 है।

· गैर-बुनियादी सी प्रकारों के लिए प्रिंटफ प्रारूपों का उपयोग करना

चतुर्थ मैं = ...;
प्रिंटफ ("i = %d\n", i); /* खराब */

हालाँकि यह गलती से किसी प्लेटफ़ॉर्म पर काम कर सकता है (जहाँ IV एक "int" होता है),
सामान्य तौर पर यह नहीं हो सकता. IV कुछ बड़ा हो सकता है. इससे भी बुरी स्थिति है
अधिक विशिष्ट प्रकार (पर्ल के कॉन्फ़िगरेशन चरण द्वारा परिभाषित)। कॉन्फ़िग.एच):

Uid_t कौन = ...;
प्रिंटफ ("कौन = %d\n", कौन); /* खराब */

यहां समस्या यह है कि Uid_t न केवल "int"-व्यापी नहीं हो सकता है, बल्कि यह हो भी सकता है
अहस्ताक्षरित, ऐसी स्थिति में बड़े यूआईडी को नकारात्मक मान के रूप में मुद्रित किया जाएगा।

इसका कोई सरल समाधान नहीं है क्योंकि printf ()सीमित बुद्धि है, लेकिन
कई प्रकारों के लिए सही प्रारूप उपलब्ध है जैसे कि 'f' या '_f' प्रत्यय के साथ
उदाहरण:

IVdf /* IV दशमलव में */
UVxf /* UV हेक्साडेसिमल है */

प्रिंटफ ("i = %"IVdf"\n", i); /* IVdf एक स्ट्रिंग स्थिरांक है। */

Uid_t_f /* Uid_t दशमलव में */

प्रिंटफ ("कौन = %"Uid_t_f"\n", कौन);

या आप "पर्याप्त विस्तृत" प्रकार में कास्टिंग करने का प्रयास कर सकते हैं:

प्रिंटफ ("i = %"IVdf"\n", (IV)something_every_small_and_signed);

यह भी याद रखें कि %p प्रारूप को वास्तव में एक शून्य सूचक की आवश्यकता होती है:

यू8* पी = ...;
प्रिंटफ ("पी = %पी\एन", (शून्य*)पी);

ऐसी समस्याओं के लिए gcc विकल्प "-Wformat" स्कैन करता है।

· आंख मूंदकर विविध मैक्रोज़ का उपयोग करना

जीसीसी ने उन्हें कुछ समय के लिए अपने स्वयं के सिंटैक्स के साथ रखा था, और C99 उन्हें एक के साथ लाया
मानकीकृत वाक्यविन्यास. पूर्व का उपयोग न करें, और बाद का उपयोग केवल तभी करें जब
HAS_C99_VARIADIC_MACROS परिभाषित किया गया है।

· आंख मूंदकर va_list पास करना

सभी प्लेटफ़ॉर्म va_list को आगे के varargs (stdarg) फ़ंक्शंस में पास करने का समर्थन नहीं करते हैं।
का उपयोग करके va_list को कॉपी करना सही काम है Perl_va_copy() यदि NEED_VA_COPY
परिभाषित किया गया है।

· जीसीसी कथन अभिव्यक्तियों का उपयोग करना

वैल = ({...;...;...}); /* खराब */

हालाँकि यह एक अच्छा विस्तार है, लेकिन यह पोर्टेबल नहीं है। पर्ल कोड निश्चित रूप से उनका उपयोग करता है यदि
कुछ अतिरिक्त गति प्राप्त करने के लिए उपलब्ध है (अनिवार्य रूप से इनलाइनिंग के एक फंकी रूप के रूप में), लेकिन आप
नहीं करना चाहिए.

· मैक्रो में कई कथनों को एक साथ बांधना

मैक्रोज़ STMT_START और STMT_END का उपयोग करें.

STMT_START {
...
} STMT_END

· ऑपरेटिंग सिस्टम या संस्करणों के लिए परीक्षण जब सुविधाओं के लिए परीक्षण किया जाना चाहिए

#ifdef __FOONIX__ /* ख़राब */
फू = क्वक्स();
#endif

जब तक कि आप 100% निश्चितता के साथ यह न जान लें क्वक्स() केवल के लिए सदैव उपलब्ध है
"फूनिक्स" ऑपरेटिंग सिस्टम और वह उपलब्ध है और के लिए सही ढंग से काम कर रहा है सब अतीत,
वर्तमान, और "फूनिक्स" के भविष्य के संस्करण, उपरोक्त बहुत गलत है। ये तो और भी है
सही है (हालाँकि अभी भी सही नहीं है, क्योंकि नीचे एक संकलन-समय जाँच है):

#ifdef में_QUUX है
फू = क्वक्स();
#endif

HAS_QUUX को वहां कैसे परिभाषित किया जाता है जहां इसकी आवश्यकता है? ठीक है, अगर फ़ूनिक्स होता है
कॉन्फिगर स्क्रिप्ट को चलाने में सक्षम होने के लिए पर्याप्त यूनिक्सी बनें, और कॉन्फिगर सिखाया गया है
पता लगाने और परीक्षण के बारे में क्वक्स(), HAS_QUUX को सही ढंग से परिभाषित किया जाएगा। अन्य में
प्लेटफ़ॉर्म, संबंधित कॉन्फ़िगरेशन चरण उम्मीद से ऐसा ही करेगा।

एक चुटकी में, यदि आप कॉन्फिगर के शिक्षित होने की प्रतीक्षा नहीं कर सकते, या यदि आपके पास अच्छा है
पता नहीं कहाँ क्वक्स() उपलब्ध हो सकता है, आप अस्थायी रूप से निम्नलिखित प्रयास कर सकते हैं:

#if (परिभाषित(__FOONIX__) || परिभाषित(__BARNIX__))
# HAS_QUUX को परिभाषित करें
#endif

...

#ifdef में_QUUX है
फू = क्वक्स();
#endif

लेकिन किसी भी स्थिति में, सुविधाओं और ऑपरेटिंग सिस्टम को अलग रखने का प्रयास करें।

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

यदि ((s = PerlEnv_getenv("foo") == NULL) {
... /* शून्य केस संभालें */
}
और {
s = SvPVX(sv_2mortal(newSVpv(s, 0)));
}

उपरोक्त उदाहरण केवल तभी काम करता है जब "एस" "एनयूएल"-समाप्त हो; अन्यथा तुम्हें उत्तीर्ण होना पड़ेगा
इसकी लंबाई "newSVpv" तक है।

समस्यात्मक प्रणाली इंटरफेस
· malloc(0) रीयलोक(0), कॉलोक(0, 0) गैर-पोर्टेबल हैं। पोर्टेबल होने के लिए आवंटित करें
कम से कम एक बाइट. (सामान्य तौर पर आपको शायद ही कभी इस निम्न स्तर पर काम करने की आवश्यकता होगी, लेकिन
इसके बजाय विभिन्न मॉलोक रैपर्स का उपयोग करें।)

· एसएनप्रिंटएफ() - रिटर्न प्रकार पोर्टेबल नहीं है। उपयोग my_snprintf() बजाय.

सुरक्षा समस्याओं
अंतिम लेकिन महत्वपूर्ण बात, यहां सुरक्षित कोडिंग के लिए विभिन्न युक्तियां दी गई हैं। इसके लिए पर्लक्लिब भी देखें
किसी को libc/stdio प्रतिस्थापन का उपयोग करना चाहिए।

· उपयोग नहीं करो हो जाता है ()

अन्यथा हम सार्वजनिक रूप से आपका उपहास करेंगे। गंभीरता से।

· उपयोग नहीं करो tmpfile ()

उपयोग mkstemp() बजाय.

· उपयोग नहीं करो स्ट्रैपी() or स्ट्रैटकैट() or strncpy() or स्ट्रनकैट()

उपयोग my_strlcpy() और my_strlcat() इसके बजाय: वे या तो मूल कार्यान्वयन का उपयोग करते हैं,
या पर्ल का स्वयं का कार्यान्वयन (आईएनएन के सार्वजनिक डोमेन कार्यान्वयन से उधार लिया गया)।

· उपयोग नहीं करो स्प्रिंटफ () or बनामप्रिंटफ ()

यदि आप वास्तव में केवल सादे बाइट स्ट्रिंग्स चाहते हैं, तो उपयोग करें my_snprintf() और my_vsnprintf()
इसके बजाय, जिसका उपयोग करने का प्रयास किया जाएगा एसएनप्रिंटएफ() और vsnprintf() यदि वे सुरक्षित एपीआई हैं
उपलब्ध। यदि आप सादे बाइट स्ट्रिंग से अधिक शानदार चीज़ चाहते हैं, तो "Perl_form"() का उपयोग करें
या एसवी और "Perl_sv_catpvf()"।

ध्यान दें कि glibc "printf()", "sprintf()", आदि glibc संस्करण 2.17 से पहले खराब हैं।
वे ऐसी स्ट्रिंग बनाने के लिए परिशुद्धता के साथ "%s" प्रारूप की अनुमति नहीं देंगे जो मान्य नहीं है
UTF-8 यदि प्रोग्राम का वर्तमान अंतर्निहित स्थान UTF-8 है। जो होता है वही होता है
%s और उसके ऑपरेंड को बिना किसी सूचना के छोड़ दिया गया है।
.

· उपयोग नहीं करो एटोई ()

उपयोग grok_atoUV() बजाय. एटोई () अतिप्रवाह पर अपरिभाषित व्यवहार है, और नहीं हो सकता
वृद्धिशील पार्सिंग के लिए उपयोग किया जाता है। यह लोकेल से भी प्रभावित होता है, जो बुरा है।

· उपयोग नहीं करो स्ट्रटोल() or स्ट्रटौल()

उपयोग grok_atoUV() बजाय. स्ट्रटोल() or स्ट्रटौल() (या उनका IV/UV-अनुकूल मैक्रो
भेष बदलना, स्ट्रटोल() और स्ट्रटौल()या, एटोल() और अटौल() स्थानीयता से प्रभावित होते हैं, जो
बुरा है।

डिबगिंग


आप पर्ल का एक विशेष डिबगिंग संस्करण संकलित कर सकते हैं, जो आपको "-डी" का उपयोग करने की अनुमति देता है
पर्ल क्या कर रहा है इसके बारे में अधिक बताने के लिए पर्ल का विकल्प। लेकिन कभी-कभी ऐसा नहीं होता
डिबगर के साथ गोता लगाने के बजाय कोर डंप के स्टैक ट्रेस को देखने का विकल्प
(बग रिपोर्ट में बहुत उपयोगी), या यह पता लगाने की कोशिश कर रहा हूं कि कोर से पहले क्या गलत हुआ
डंप हुआ, या हमें गलत या अप्रत्याशित परिणाम कैसे मिले।

poking at पर्ल
वास्तव में पर्ल के बारे में जानने के लिए, आप शायद डिबगिंग के लिए पर्ल का निर्माण करना चाहेंगे, जैसे
इस:

./कॉन्फ़िगर -d -D ऑप्टिमाइज़=-g
बनाना

"-जी" सी कंपाइलर के लिए एक ध्वज है जो इसे डिबगिंग जानकारी उत्पन्न करने की अनुमति देगा
हमें एक चल रहे प्रोग्राम के माध्यम से आगे बढ़ना है, और यह देखना है कि हम किस सी फ़ंक्शन में हैं (बिना)।
डिबगिंग जानकारी में हम केवल फ़ंक्शन के संख्यात्मक पते देख सकते हैं,
जो बहुत मददगार नहीं है)।

कॉन्फ़िगर "डीबगिंग" संकलन प्रतीक भी चालू हो जाएगा जो सभी को सक्षम बनाता है
पर्ल में आंतरिक डिबगिंग कोड। ऐसी बहुत सी चीज़ें हैं जिनसे आप डिबग कर सकते हैं
यह: perlrun उन सभी को सूचीबद्ध करता है, और उनके बारे में जानने का सबसे अच्छा तरीका उनके बारे में खेलना है
उनके साथ। संभवतः सबसे उपयोगी विकल्प हैं

एल संदर्भ (लूप) स्टैक प्रसंस्करण
टी ट्रेस निष्पादन
o विधि और ओवरलोडिंग समाधान
सी स्ट्रिंग/संख्यात्मक रूपांतरण

डिबगिंग कोड की कुछ कार्यक्षमता XS मॉड्यूल का उपयोग करके प्राप्त की जा सकती है।

-डॉ => पुनः 'डीबग' का उपयोग करें
-Dx => O 'डीबग' का उपयोग करें

का प्रयोग a स्रोत-स्तरीय डिबगर
यदि "-D" का डिबगिंग आउटपुट आपकी मदद नहीं करता है, तो यह पर्ल के माध्यम से कदम उठाने का समय है
स्रोत-स्तरीय डिबगर के साथ निष्पादन।

· हम यहां अपने उदाहरणों के लिए "जीडीबी" का उपयोग करेंगे; सिद्धांत किसी भी डिबगर (कई) पर लागू होंगे
विक्रेता अपने डिबगर को "dbx" कहते हैं), लेकिन आप जिसका उपयोग कर रहे हैं उसके मैनुअल की जाँच करें।

डिबगर को सक्रिय करने के लिए टाइप करें

जीडीबी ./पर्ल

या यदि आपके पास कोर डंप है:

जीडीबी ./पर्ल कोर

आप इसे अपने पर्ल स्रोत ट्री में करना चाहेंगे ताकि डिबगर स्रोत कोड को पढ़ सके।
आपको कॉपीराइट संदेश और उसके बाद संकेत देखना चाहिए।

(GDB)

"सहायता" आपको दस्तावेज़ीकरण में ले जाएगी, लेकिन यहां सबसे उपयोगी आदेश हैं:

· चलाएँ [तर्क]

दिए गए तर्कों के साथ प्रोग्राम चलाएँ।

· फ़ंक्शन_नाम तोड़ें

· ब्रेक सोर्स.सी:xxx

डिबगर को बताता है कि जब हम दोनों में से किसी एक पर पहुंचेंगे तो हम निष्पादन को रोकना चाहेंगे
फ़ंक्शन (लेकिन पर्लगट्स में "आंतरिक फ़ंक्शंस" देखें!) या नामित पंक्ति में
मूल फाइल।

· कदम

प्रोग्राम के माध्यम से एक समय में एक पंक्ति में कदम रखें।

· अगला

फ़ंक्शंस में उतरे बिना, प्रोग्राम के माध्यम से एक समय में एक पंक्ति में कदम बढ़ाता है।

· जारी रखना

अगले ब्रेकप्वाइंट तक चलाएँ।

· खत्म करना

वर्तमान फ़ंक्शन के अंत तक चलाएँ, फिर रुकें।

· 'प्रवेश करना'

बस एंटर दबाने से नवीनतम ऑपरेशन फिर से हो जाएगा - यह एक आशीर्वाद है
स्रोत कोड के मीलों से गुज़रना।

· पी प्रकार

दिए गए तर्क की C परिभाषा प्रिंट करता है।

(जीडीबी) पीटाइप पीएल_ऑप
टाइप = स्ट्रक्चर ऑप {
ओपी *op_next;
ओपी *op_sibparent;
ओपी *(*op_ppaddr)(शून्य);
PADOFFSET op_targ;
अहस्ताक्षरित int op_type : 9;
अहस्ताक्षरित int op_opt : 1;
अहस्ताक्षरित int op_slabbed : 1;
अहस्ताक्षरित int op_savefree : 1;
अहस्ताक्षरित int op_static : 1;
अहस्ताक्षरित int op_folded : 1;
अहस्ताक्षरित int op_spare : 2;
U8 op_flags;
U8 op_private;
} *

· प्रिंट करें

दिए गए C कोड को निष्पादित करें और उसके परिणाम प्रिंट करें। चेतावनी: पर्ल का भारी उपयोग होता है
मैक्रोज़, और जी.डी.बी. आवश्यक रूप से मैक्रोज़ का समर्थन नहीं करता है (बाद में "जीडीबी मैक्रो सपोर्ट" देखें)।
आपको उन्हें स्वयं प्रतिस्थापित करना होगा, या स्रोत कोड फ़ाइलों पर सीपीपी लागू करना होगा (देखें)।
".i लक्ष्य") इसलिए, उदाहरण के लिए, आप नहीं कह सकते

SvPV_nolen(sv) प्रिंट करें

लेकिन आपको कहना होगा

Perl_sv_2pv_nolen(sv) प्रिंट करें

आपके लिए "मैक्रो डिक्शनरी" उपयोगी हो सकती है, जिसे आप "सीपीपी" कहकर तैयार कर सकते हैं
-डीएम पर्ल.सी | क्रमबद्ध करें"। फिर भी, सीपीपी उन मैक्रोज़ को आपके लिए पुनरावर्ती रूप से लागू नहीं किया जाएगा।

जी.डी.बी. मैक्रो समर्थन
के हाल के संस्करण जी.डी.बी. इसमें काफी अच्छा मैक्रो समर्थन है, लेकिन इसका उपयोग करने के लिए आपको इसकी आवश्यकता होगी
डिबगिंग जानकारी में शामिल मैक्रो परिभाषाओं के साथ पर्ल को संकलित करने के लिए। का उपयोग करते हुए जीसीसी
संस्करण 3.1, इसका अर्थ है "-Doptimize=-g3" के साथ कॉन्फ़िगर करना। अन्य कंपाइलर इसका उपयोग कर सकते हैं
भिन्न स्विच (यदि वे डिबगिंग मैक्रोज़ का बिल्कुल भी समर्थन करते हैं)।

उतारना पर्ल जानकारी संरचनाएं
इस स्थूल नरक से बचने का एक तरीका डंपिंग फ़ंक्शंस का उपयोग करना है डंप.सी; इन
कुछ हद तक आंतरिक डेवेल::पीक की तरह काम करते हैं, लेकिन वे ओपी और अन्य संरचनाओं को भी कवर करते हैं
जिसे आप पर्ल से प्राप्त नहीं कर सकते। चलिए एक उदाहरण लेते हैं. हम "$a = $b + $c" का प्रयोग करेंगे
पहले इस्तेमाल किया गया था, लेकिन इसे थोड़ा संदर्भ दें: "$b = "6XXXX"; $c = 2.3;"। एक अच्छा कहाँ है
रुकने और इधर-उधर ताक-झांक करने की जगह?

"pp_add" के बारे में क्या, जिस फ़ंक्शन की हमने पहले "+" ऑपरेटर को लागू करने के लिए जांच की थी:

(जीडीबी) Perl_pp_add को तोड़ें
1x0f पर ब्रेकप्वाइंट 46249: फ़ाइल pp_hot.c, लाइन 309।

ध्यान दें कि हम "Perl_pp_add" का उपयोग करते हैं न कि "pp_add" का - perlguts में "आंतरिक कार्य" देखें। साथ
ब्रेकप्वाइंट सही जगह पर है, हम अपना प्रोग्राम चला सकते हैं:

(जीडीबी) रन -ई '$बी = "6XXXX"; $सी = 2.3; $ए = $बी + $सी'

जैसे ही जीडीबी प्रासंगिक स्रोत फ़ाइलों और पुस्तकालयों में पढ़ता है, बहुत सारा कबाड़ चला जाएगा, और
फिर:

ब्रेकप्वाइंट 1, Perl_pp_add () pp_hot.c:309 पर
309 डीएसपी; डेटागेट; प्रयत्नAMAGICbin(जोड़ें,opASSIGN);
(जीडीबी) चरण
311 dPOPTOPnnrl_ul;
(GDB)

हमने पहले कोड के इस बिट को देखा था, और हमने कहा था कि "dPOPTOPnnrl_ul" दो की व्यवस्था करता है
"एनवी" को "बाएँ" और "दाएँ" में रखा जाएगा - आइए इसे थोड़ा विस्तारित करें:

#define dPOPTOPnnrl_ul NV दाएँ = POPn; \
एसवी *लेफ्ट्सवी = टॉप्स; \
NV बाएँ = USE_LEFT(leftsv) ? एसवीएनवी(लेफ्ट्सवी): 0.0

"पीओपीएन" एसवी को स्टैक के शीर्ष से लेता है और इसका एनवी या तो सीधे प्राप्त करता है (यदि
"SvNOK" सेट है) या "sv_2nv" फ़ंक्शन को कॉल करके। "टॉप्स" से अगला एसवी लेता है
स्टैक के शीर्ष पर - हाँ, "POPn" "TOPs" का उपयोग करता है - लेकिन इसे हटाता नहीं है। फिर हम "SvNV" का उपयोग करते हैं
पहले की तरह ही "leftsv" से NV प्राप्त करें - हाँ, "POPn" "SvNV" का उपयोग करता है।

चूँकि हमारे पास $b के लिए NV नहीं है, इसलिए हमें इसे परिवर्तित करने के लिए "sv_2nv" का उपयोग करना होगा। अगर हम कदम बढ़ाते हैं
फिर, हम स्वयं को वहां पाएंगे:

(जीडीबी) चरण
Perl_sv_2nv (sv=0xa0675d0) sv.c:1669 पर
1669 यदि (!sv)
(GDB)

अब हम एसवी की जांच के लिए "Perl_sv_dump" का उपयोग कर सकते हैं:

(जीडीबी) पर्ल_एसवी_डंप(एसवी) प्रिंट करें
एसवी = PV(0xa057cc0) at 0xa0675d0
आरईएफसीएनटी = 1
झंडे = (POK,pPOK)
पीवी = 0xa06a510 "6XXXX"\0
सीयूआर = 5
एलईएन = 6
$1 = शून्य

हम जानते हैं कि हमें इससे 6 मिलेंगे, तो आइए सबरूटीन समाप्त करें:

(जीडीबी) समाप्त
#0 Perl_sv_2nv (sv=0xa0675d0) से sv.c:1671 पर बाहर निकलने तक चलाएँ
0x462669 Perl_pp_add () में pp_hot.c:311 पर
311 dPOPTOPnnrl_ul;

हम इस ऑप को डंप भी कर सकते हैं: वर्तमान ऑप हमेशा "PL_op" में संग्रहीत होता है, और हम डंप कर सकते हैं
यह "Perl_op_dump" के साथ है। यह हमें B::Debug के समान आउटपुट देगा।

(जीडीबी) पर्ल_ऑप_डंप(पीएल_ओपी) प्रिंट करें
{
13 प्रकार = जोड़ें ===> 14
टार्ग = 1
झंडे = (स्केलर, बच्चे)
{
प्रकार = शून्य ===> (12)
(rv2sv था)
झंडे = (स्केलर, बच्चे)
{
11 प्रकार = gvsv ===> 12
झंडे = (अक्षर)
जीवी = मुख्य::बी
}
}

#इसे बाद में ख़त्म करें#

का प्रयोग जी.डी.बी. सेवा मेरे देखना at विशिष्ट भागों of a कार्यक्रम
उपरोक्त उदाहरण के साथ, आप "Perl_pp_add" खोजना जानते थे, लेकिन अगर वहाँ होता तो क्या होता
हर जगह से इस पर कई कॉलें आईं, या आपको पता ही नहीं चला कि आप क्या कर रहे थे
ढूंढ रहे हैं?

ऐसा करने का एक तरीका यह है कि आप जो खोज रहे हैं उसके निकट कहीं एक दुर्लभ कॉल इंजेक्ट करें। के लिए
उदाहरण के लिए, आप अपनी विधि से पहले "अध्ययन" जोड़ सकते हैं:

अध्ययन;

और जीडीबी में करें:

(जीडीबी) पर्ल_पीपी_स्टडी को तोड़ें

और तब तक आगे बढ़ें जब तक कि आप वह हासिल न कर लें जिसे आप ढूंढ रहे हैं। यह एक लूप में अच्छा काम करता है यदि आप
केवल कुछ पुनरावृत्तियों पर विराम लगाना चाहते हैं:

मेरे $c के लिए (1..100) {
अध्ययन करें यदि $c == 50;
}

का प्रयोग जी.डी.बी. सेवा मेरे देखना at क्या la पार्सर/लेक्सर रहे कर
यदि आप यह देखना चाहते हैं कि आपके कोड को पार्स/लेक्स करते समय पर्ल क्या कर रहा है, तो आप "BEGIN" का उपयोग कर सकते हैं
{}":

"पहले\n" प्रिंट करें;
आरंभ {अध्ययन; }
"बाद\n" प्रिंट करें;

और जीडीबी में:

(जीडीबी) पर्ल_पीपी_स्टडी को तोड़ें

यदि आप यह देखना चाहते हैं कि पार्सर/लेक्सर "if" ब्लॉक और आपकी तरह के अंदर क्या कर रहा है
थोड़ा पेचीदा होने की जरूरत है:

यदि ($a && $b && do { BEGIN { अध्ययन } 1 } && $c) { ... }

स्रोत कोड स्थिर विश्लेषण


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

लिंट, पट्टी
अच्छा पुराना सी कोड गुणवत्ता निरीक्षक, "लिंट", कई प्लेटफार्मों में उपलब्ध है, लेकिन
कृपया ध्यान रखें कि अलग-अलग तरीकों से इसके कई अलग-अलग कार्यान्वयन होते हैं
विक्रेता, जिसका अर्थ है कि झंडे विभिन्न प्लेटफार्मों पर समान नहीं हैं।

"स्प्लिंट" (सिक्योर प्रोग्रामिंग लिंट) नामक एक लिंट संस्करण उपलब्ध है
http://www.splint.org/ इसे किसी यूनिक्स-जैसे प्लेटफ़ॉर्म पर संकलित किया जाना चाहिए।

वहाँ "लिंट" और हैं मेकफ़ाइल में लक्ष्य, लेकिन आपको इसके साथ काम करना पड़ सकता है
झंडे (ऊपर देखें)।

कवरिटी
कवरिटी (http://www.coverity.com/) लिंट के समान और परीक्षण बिस्तर के रूप में एक उत्पाद है
वे समय-समय पर अपने उत्पाद की कई ओपन सोर्स परियोजनाओं की जांच करते हैं, और वे उसे दे देते हैं
दोषपूर्ण डेटाबेस के लिए स्रोत डेवलपर्स को खोलने के लिए खाते।

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

सीपीडी (http://pmd.sourceforge.net/cpd.html) pmd प्रोजेक्ट का हिस्सा है
(http://pmd.sourceforge.net/). pmd मूल रूप से जावा के स्थैतिक विश्लेषण के लिए लिखा गया था
कोड, लेकिन बाद में इसके सीपीडी भाग को सी और सी++ को पार्स करने के लिए भी बढ़ाया गया।

सोर्सफोर्ज साइट से pmd-bin-XYzip () डाउनलोड करें, pmd-XYjar को यहां से निकालें
इसे, और फिर उसे स्रोत कोड पर इस प्रकार चलाएँ:

जावा -सीपी पीएमडी-एक्सवाईजर नेट.सोर्सफोर्ज.पीएमडी.सीपीडी.सीपीडी \
--न्यूनतम-टोकन 100 --फ़ाइलें /some/where/src --भाषा c > cpd.txt

आपकी मेमोरी सीमा समाप्त हो सकती है, ऐसी स्थिति में आपको -Xmx विकल्प का उपयोग करना चाहिए:

जावा -Xmx512M ...

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

"-वॉल" डिफ़ॉल्ट रूप से चालू है।

"-अंसी" (और इसकी साइडकिक, "-पेडेंटिक") हमेशा चालू रहना अच्छा होगा, लेकिन
दुर्भाग्य से वे सभी प्लेटफार्मों पर सुरक्षित नहीं हैं, उदाहरण के लिए वे घातक परिणाम दे सकते हैं
सिस्टम हेडर के साथ टकराव (सोलारिस इसका प्रमुख उदाहरण है)। यदि कॉन्फ़िगर करें
"-Dgccansipedantic" का उपयोग किया जाता है, "cflags" फ्रंटएंड इसके लिए "-ansi -pedantic" का चयन करता है
ऐसे प्लेटफ़ॉर्म जहां उन्हें सुरक्षित माना जाता है।

पर्ल 5.9.4 से शुरू करके निम्नलिखित अतिरिक्त झंडे जोड़े गए हैं:

· "-वेंडीफ़-लेबल"

· "-वेक्स्ट्रा"

· "-घोषणा-पश्चात-कथन"

निम्नलिखित झंडे अच्छे रहेंगे लेकिन उन्हें पहले अपने स्वयं के ऑगियन की आवश्यकता होगी
स्टेबलमास्टर:

· "-Wpointer-arith"

· "-छाया"

· "-Wstrict-प्रोटोटाइप"

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

: of अन्य C संकलनकर्ता
अन्य सी कंपाइलर (हाँ, वहाँ रहे जीसीसी के अलावा अन्य सी कंपाइलर) अक्सर अपने "सख्त" होते हैं
एएनएसआई" या "कुछ पोर्टेबिलिटी एक्सटेंशन के साथ सख्त एएनएसआई" मोड चालू हैं, उदाहरण के लिए सन
वर्कशॉप का अपना "-Xa" मोड चालू है (हालाँकि अंतर्निहित रूप से), या DEC (इन दिनों, HP...) का अपना है
"-std1" मोड चालू।

स्मृति डिबगर


ध्यान दें 1: पुराने मेमोरी डिबगर्स जैसे प्यूरिफाई, वालग्रिंड या थर्ड डिग्री के तहत चल रहा है
निष्पादन को बहुत धीमा कर देता है: सेकंड मिनट बन जाते हैं, मिनट घंटे बन जाते हैं। के लिए
उदाहरण के तौर पर पर्ल 5.8.1 के अनुसार, ext/Encode/t/Unicode.t को बनाने में असाधारण रूप से अधिक समय लगता है
उदाहरण के लिए प्यूरिफाई, थर्ड डिग्री और वेलग्रिंड के तहत पूरा करें। वालग्रिंड के अंतर्गत इससे अधिक समय लगता है
छह घंटे, यहां तक ​​कि एक तेज़ कंप्यूटर पर भी। उक्त परीक्षण कुछ ऐसा कर रहा होगा जो काफी है
मेमोरी डिबगर्स के लिए अमित्र। यदि आपका इंतजार करने का मन नहीं है, तो आप आसानी से हत्या कर सकते हैं
पर्ल प्रक्रिया को दूर करें। मोटे तौर पर वालग्रिंड कारक 10 द्वारा निष्पादन को धीमा कर देता है,
फैक्टर 2 द्वारा एड्रेस सेनिटाइज़र।

ध्यान दें 2: मेमोरी लीक झूठे अलार्म की संख्या को कम करने के लिए (इसके लिए "PERL_DESTRUCT_LEVEL" देखें)।
अधिक जानकारी), आपको पर्यावरण चर PERL_DESTRUCT_LEVEL को 2 पर सेट करना होगा
उदाहरण, इस तरह:

env PERL_DESTRUCT_LEVEL=2 valgrind ./perl -Ilib ...

ध्यान दें 3: ज्ञात मेमोरी लीक तब होते हैं जब eval या के भीतर संकलन-समय त्रुटियां होती हैं
आवश्यकता है, कॉल स्टैक में "S_doeval" देखना इसका एक अच्छा संकेत है। इन लीक को ठीक करना
दुर्भाग्यवश, यह कोई मामूली बात नहीं है, लेकिन अंततः इन्हें ठीक किया जाना चाहिए।

ध्यान दें 4: जब तक पर्ल के साथ निर्माण नहीं किया जाता तब तक डायनालोडर अपने आप पूरी तरह से साफ नहीं होगा
विकल्प "-Accflags=-DDL_UNLOAD_ALL_AT_EXIT" कॉन्फ़िगर करें।

वालग्रिंड
वेलग्रिंड टूल का उपयोग मेमोरी लीक और अवैध ढेर मेमोरी दोनों का पता लगाने के लिए किया जा सकता है
पहुँच। संस्करण 3.3.0 के अनुसार, वैलग्रिंड केवल x86, x86-64 और पावरपीसी पर लिनक्स का समर्थन करता है
और डार्विन (ओएस एक्स) x86 और x86-64 पर)। विशेष "test.valgrind" लक्ष्य का उपयोग किया जा सकता है
वैलग्रिंड के अंतर्गत परीक्षण चलाएँ। पाई गई त्रुटियाँ और मेमोरी लीक नामित फ़ाइलों में लॉग इन हैं
testfile.valgrind और डिफ़ॉल्ट रूप से आउटपुट इनलाइन प्रदर्शित होता है।

उदाहरण उपयोग:

test.valgrind बनाएं

चूंकि वालग्रिंड महत्वपूर्ण ओवरहेड जोड़ता है, इसलिए परीक्षणों को चलने में अधिक समय लगेगा।
इसमें सहायता के लिए वाल्ग्रिंड परीक्षण समर्थन समानांतर में चलाया जा रहा है:

TEST_JOBS=9 test.valgrind . करें

ध्यान दें कि उपरोक्त दो आह्वान पहुंच योग्य स्मृति और लीक के रूप में बहुत शब्दाडंबरपूर्ण होंगे-
जाँच डिफ़ॉल्ट रूप से सक्षम है. यदि आप केवल शुद्ध त्रुटियाँ देखना चाहते हैं, तो प्रयास करें:

VG_OPTS='-q --लीक-चेक=नहीं --शो-रीचेबल=नहीं' TEST_JOBS=9 \
test.valgrind बनाएं

वालग्रिंड एक कैशेग्रिंड टूल भी प्रदान करता है, जिसे पर्ल पर इस प्रकार लागू किया जाता है:

VG_OPTS=--टूल=कैशग्रिंड टेस्ट बनाएं.वैलग्रिंड

चूंकि सिस्टम लाइब्रेरीज़ (विशेष रूप से ग्लिबैक) भी त्रुटियों को ट्रिगर कर रही हैं, वालग्रिंड इसकी अनुमति देता है
दमन फ़ाइलों का उपयोग करके ऐसी त्रुटियों को दबाएँ। डिफ़ॉल्ट दमन फ़ाइल जो आती है
वालग्रिंड के साथ उनमें से बहुतों को पहले ही पकड़ लिया गया है। कुछ अतिरिक्त दमन को परिभाषित किया गया है
टी/पर्ल.supp.

वेलग्रिंड प्राप्त करने और अधिक जानकारी के लिए देखें

http://valgrind.org/

पता सैनिटाइज़र
एड्रेस सैनिटाइजर एक क्लैंग और जीसीसी एक्सटेंशन है, जो v3.1 से क्लैंग और जीसीसी में शामिल है
v4.8. यह अवैध हीप पॉइंटर्स, ग्लोबल पॉइंटर्स, स्टैक पॉइंटर्स और मुफ़्त के बाद उपयोग की जाँच करता है
त्रुटियाँ, और यह इतना तेज़ है कि आप आसानी से अपने डिबगिंग या अनुकूलित पर्ल को संकलित कर सकते हैं
इसके साथ। हालाँकि यह मेमोरी लीक की जाँच नहीं करता है। एड्रेस सेनिटाइजर लिनक्स के लिए उपलब्ध है,
मैक ओएस एक्स और जल्द ही विंडोज़ पर।

एड्रेससेनिटाइज़र के साथ पर्ल बनाने के लिए, आपका कॉन्फिगर आमंत्रण इस तरह दिखना चाहिए:

sh कॉन्फ़िगर करें -des -Dcc=clang \
-Accflags=-faddress-sanitizer -Aldflags=-faddress-sanitizer \
-एल्डफ्लैग्स=-शेयर्ड\ -फैड्रेस-सैनिटाइजर

इन तर्कों का मतलब कहां है:

· -Dcc=क्लैंग

यदि यह आपके क्लैंग निष्पादन योग्य में नहीं है तो इसे पूर्ण पथ से प्रतिस्थापित किया जाना चाहिए
पथ।

· -एसीसीफ्लैग=-फैड्रेस-सैनिटाइजर

एड्रेससेनिटाइज़र के साथ पर्ल और एक्सटेंशन स्रोतों को संकलित करें।

· -एल्डफ्लैग्स=-फैड्रेस-सैनिटाइज़र

पर्ल निष्पादन योग्य को एड्रेससेनिटाइज़र के साथ लिंक करें।

· -Alddlflags=-shared\ -faddress-sanitizer

डायनामिक एक्सटेंशन को एड्रेस सैनिटाइजर के साथ लिंक करें। आपको मैन्युअल रूप से "-shared" निर्दिष्ट करना होगा
क्योंकि "-Alddlflags=-shared" का उपयोग करने से कॉन्फिगर को डिफ़ॉल्ट सेट करने से रोका जा सकेगा
"lddlflags" के लिए मान, जिसमें आमतौर पर "-shared" होता है (कम से कम लिनक्स पर)।

यह सभी देखेंhttp://code.google.com/p/address-sanitizer/wiki/AddressSanitizer>.

रूपरेखा


आपके प्लेटफॉर्म के आधार पर पर्ल प्रोफाइलिंग के विभिन्न तरीके हैं।

निष्पादनयोग्य प्रोफाइलिंग की दो सामान्यतः उपयोग की जाने वाली तकनीकें हैं: सांख्यिकीय समय-नमूना
और बुनियादी ब्लॉक गिनती.

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

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

जीप्रोफ़ रूपरेखा
ग्प्रोफ कई यूनिक्स प्लेटफार्मों में उपलब्ध एक प्रोफाइलिंग टूल है जिसका उपयोग किया जाता है सांख्यिकीय समय-
नमूना. आप इसका प्रोफ़ाइल संस्करण बना सकते हैं पर्ल ध्वज के साथ जीसीसी का उपयोग करके संकलन करके
"-पीजी"। या तो संपादित करें config.श या फिर से चलाएँ कॉन्फ़िगर. पर्ल का प्रोफाइल संस्करण चला रहा हूँ
नामक एक आउटपुट फ़ाइल बनाएगा Gmon.out जिसमें एकत्र किया गया प्रोफाइलिंग डेटा शामिल है
निष्पादन के दौरान.

त्वरित संकेत:

$ sh कॉन्फ़िगर करें -des -Dusedevel -Accflags='-pg' \
-Aldflags='-pg' -Alddlflags='-pg -shared' \
&& पर्ल बनाएं
$ ./perl... # वर्तमान निर्देशिका में gmon.out बनाता है
$ gprof ./perl > बाहर
$ कम बाहर

(आपको संभवतः <-Alddlflags> लाइन में "-shared" जोड़ने की आवश्यकता है जब तक कि RT #118199 न हो जाए
हल किया)

RSI ग्प्रोफ फिर उपकरण एकत्रित डेटा को विभिन्न तरीकों से प्रदर्शित कर सकता है। आम तौर पर ग्प्रोफ
निम्नलिखित विकल्पों को समझता है:

· -ए

प्रोफ़ाइल से स्थिर रूप से परिभाषित फ़ंक्शन को दबाएँ।

· -बी

प्रोफ़ाइल में वर्बोज़ विवरण दबाएँ।

· -ई दिनचर्या

प्रोफ़ाइल से दी गई दिनचर्या और उसके वंशजों को बाहर निकालें।

· -एफ दिनचर्या

प्रोफ़ाइल में केवल दी गई दिनचर्या और उसके वंशजों को प्रदर्शित करें।

· -एस

नामक एक सारांश फ़ाइल जनरेट करें Gmon.sum जिसे बाद में जीप्रोफ़ को दिया जा सकता है
कई रन में डेटा संचित करने के लिए चलता है।

· -जेड

ऐसे रूटीन प्रदर्शित करें जिनका उपयोग शून्य हो।

उपलब्ध कमांड और आउटपुट स्वरूपों की अधिक विस्तृत व्याख्या के लिए, अपना खुद का देखें
का स्थानीय दस्तावेज़ीकरण ग्प्रोफ.

जीसीसी जीसीओवी रूपरेखा
बुनियादी खंड रूपरेखा आधिकारिक तौर पर जीसीसी 3.0 और बाद के संस्करण में उपलब्ध है। आप एक निर्माण कर सकते हैं
का प्रोफ़ाइल संस्करण पर्ल झंडे के साथ जीसीसी का उपयोग करके संकलित करके "-fprofile-arcs
-फ़ेस्ट-कवरेज"। या तो संपादित करें config.श या फिर से चलाएँ कॉन्फ़िगर.

त्वरित संकेत:

$ sh कॉन्फ़िगर करें -des -Dusedevel -Doptimize='-g' \
-Accflags='-fprofile-arcs -ftest-कवरेज' \
-Aldflags='-fprofile-arcs -ftest-कवरेज' \
-Alddlflags='-fprofile-arcs -ftest-कवरेज -शेयर्ड' \
&& पर्ल बनाएं
$ rm -f regexec.c.gcov regexec.gcda
$ ./perl...
$ gcov regexec.c
$ कम regexec.c.gcov

(आपको संभवतः <-Alddlflags> लाइन में "-shared" जोड़ने की आवश्यकता है जब तक कि RT #118199 न हो जाए
हल किया)

पर्ल के प्रोफाइल संस्करण को चलाने से प्रोफाइल आउटपुट उत्पन्न होगा। प्रत्येक के लिए
स्रोत फ़ाइल एक साथ .gcda फ़ाइल बनाई जाएगी.

परिणाम प्रदर्शित करने के लिए आप इसका उपयोग करते हैं जीसीओवी उपयोगिता (यदि आपके पास जीसीसी है तो इसे स्थापित किया जाना चाहिए
3.0 या नया स्थापित)। जीसीओवी इस तरह, स्रोत कोड फ़ाइलों पर चलाया जाता है

जीकोव एसवी.सी

जो कारण बनेगा sv.c.gcov बनाए जाने के लिए। .gcov फ़ाइलों में स्रोत कोड होता है
"#" मार्करों द्वारा इंगित निष्पादन की सापेक्ष आवृत्तियों के साथ एनोटेट किया गया। यदि आप चाहते हैं
उत्पन्न .gcov सभी प्रोफ़ाइल ऑब्जेक्ट फ़ाइलों के लिए फ़ाइलें, आप कुछ इस तरह चला सकते हैं:

`ढूंढें' में फ़ाइल के लिए। -नाम \*.gcno`
do sh -c "cd `dirname $file` && gcov `basename $file .gcno`"
किया

के उपयोगी विकल्प जीसीओवी "-बी" शामिल करें जो मूल ब्लॉक, शाखा और का सारांश देगा
फ़ंक्शन कॉल कवरेज, और "-सी" जो सापेक्ष आवृत्तियों के बजाय वास्तविक का उपयोग करेगा
मायने रखता है. के उपयोग के बारे में अधिक जानकारी के लिए जीसीओवी और जीसीसी के साथ बुनियादी ब्लॉक प्रोफाइलिंग, देखें
नवीनतम जीएनयू सीसी मैनुअल। जीसीसी 4.8 के अनुसार, यह यहीं है
<http://gcc.gnu.org/onlinedocs/gcc/Gcov-Intro.html#Gcov-परिचय>

कई तरह का ट्रिक्स


PERL_DESTRUCT_LEVEL
यदि आप उदाहरण के लिए वेलग्रिंड का उपयोग करके कोई भी परीक्षण स्वयं मैन्युअल रूप से चलाना चाहते हैं, तो कृपया ध्यान दें
वह डिफ़ॉल्ट रूप से पर्ल कर देता है नहीं आवंटित की गई सभी मेमोरी को स्पष्ट रूप से साफ़ करें (जैसे
वैश्विक स्मृति क्षेत्र) लेकिन इसके बजाय देता है बाहर जाएं() पूरे कार्यक्रम का "ध्यान रखें"।
आवंटन, जिसे "वस्तुओं का वैश्विक विनाश" भी कहा जाता है।

पर्ल को पूर्ण सफ़ाई करने के लिए कहने का एक तरीका है: पर्यावरण चर सेट करें
PERL_DESTRUCT_LEVEL को गैर-शून्य मान पर। टी/टेस्ट रैपर इसे 2 पर सेट करता है, और यह
यदि आप "वैश्विक लीक" नहीं देखना चाहते हैं तो आपको भी यही करने की आवश्यकता है: उदाहरण के लिए,
वालग्रिंड के अंतर्गत चल रहा है

env PERL_DESTRUCT_LEVEL=2 valgrind ./perl -Ilib t/foo/bar.t

(ध्यान दें: mod_perl apache मॉड्यूल अपने उद्देश्यों के लिए इस पर्यावरण चर का भी उपयोग करता है
और इसके शब्दार्थ को बढ़ाया। अधिक जानकारी के लिए mod_perl दस्तावेज़ देखें।
साथ ही, उत्पन्न धागे इस चर को मान 1 पर सेट करने के बराबर कार्य करते हैं।)

यदि, दौड़ के अंत में आपको संदेश मिलता है N स्केलर लीक, आप इसके साथ पुनः संकलित कर सकते हैं
"-DDEBUG_LEAKING_SCALARS", जिसके कारण उन सभी लीक हुए एसवी के पते हो जाएंगे
प्रत्येक एसवी को मूल रूप से कहां आवंटित किया गया था, इसके विवरण के साथ डंप किया गया। यह जानकारी
डेवेल::पीक द्वारा भी प्रदर्शित किया जाता है। ध्यान दें कि प्रत्येक एसवी के साथ अतिरिक्त विवरण दर्ज किया गया है
मेमोरी उपयोग बढ़ाता है, इसलिए इसका उपयोग उत्पादन परिवेश में नहीं किया जाना चाहिए। यह भी
मैक्रो से "new_SV()" को वास्तविक फ़ंक्शन में परिवर्तित करता है, ताकि आप अपने पसंदीदा का उपयोग कर सकें
डिबगर यह पता लगाने के लिए कि उन खतरनाक एसवी को कहाँ आवंटित किया गया था।

यदि आप देखते हैं कि आप रनटाइम पर मेमोरी लीक कर रहे हैं, लेकिन न तो वेलग्रिंड और न ही
"-DDEBUG_LEAKING_SCALARS" कुछ भी ढूंढेगा, आप शायद एसवी लीक कर रहे हैं जो अभी भी हैं
पहुंच योग्य है और दुभाषिया के नष्ट होने के दौरान इसे ठीक से साफ किया जाएगा। ऐसे में
मामलों में, "-डीएम" स्विच का उपयोग आपको रिसाव के स्रोत की ओर इंगित कर सकता है। यदि निष्पादन योग्य
"-DDEBUG_LEAKING_SCALARS" के साथ बनाया गया था, "-Dm" इसके अलावा एसवी आवंटन आउटपुट करेगा
स्मृति आवंटन. प्रत्येक एसवी आवंटन में एक अलग क्रमांकन होता है जिसे लिखा जाएगा
एसवी के निर्माण और विनाश पर। इसलिए यदि आप लीक कोड को लूप में निष्पादित कर रहे हैं,
आपको ऐसे एसवी की तलाश करनी होगी जो बनाए गए हों, लेकिन प्रत्येक चक्र के बीच कभी नष्ट न हुए हों। अगर
ऐसा एसवी पाया जाता है, "new_SV()" के भीतर एक सशर्त ब्रेकप्वाइंट सेट करें और इसे केवल ब्रेक करें
जब "PL_sv_serial" लीक होने वाले SV के क्रमांक के बराबर हो। फिर तुम पकड़ लोगे
दुभाषिया ठीक उसी स्थिति में है जहां लीक होने वाला एसवी आवंटित किया गया है, जो कि है
कई मामलों में रिसाव के स्रोत का पता लगाने के लिए पर्याप्त है।

चूँकि "-Dm" आउटपुट के लिए PerlIO परत का उपयोग कर रहा है, यह स्वयं ही काफी कुछ आवंटित कर देगा
एसवी, जो पुनरावृत्ति से बचने के लिए छिपे हुए हैं। यदि आप इसका उपयोग करते हैं तो आप PerlIO परत को बायपास कर सकते हैं
एसवी लॉगिंग इसके बजाय "-DPERL_MEM_LOG" द्वारा प्रदान की गई।

PERL_MEM_LOG
यदि "-DPERL_MEM_LOG" के साथ संकलित किया जाता है, तो मेमोरी और SV आवंटन दोनों लॉगिंग से गुजरते हैं
फ़ंक्शंस, जो ब्रेकपॉइंट सेटिंग के लिए उपयोगी है।

जब तक "-DPERL_MEM_LOG_NOIMPL" भी संकलित नहीं हो जाता, लॉगिंग फ़ंक्शन पढ़ता है
$ENV{PERL_MEM_LOG} यह निर्धारित करने के लिए कि इवेंट को लॉग करना है या नहीं, और यदि हां तो कैसे:

$ENV{PERL_MEM_LOG} =~ /m/ सभी मेमोरी ऑप्स लॉग करें
$ENV{PERL_MEM_LOG} =~ /s/ सभी एसवी ऑप्स लॉग करें
$ENV{PERL_MEM_LOG} =~ /t/ लॉग में टाइमस्टैम्प शामिल करें
$ENV{PERL_MEM_LOG} =~ /^(\d+)/ दिए गए FD पर लिखें (डिफ़ॉल्ट 2 है)

मेमोरी लॉगिंग कुछ हद तक "-Dm" के समान है लेकिन "-DDEBUGGING" से स्वतंत्र है, और a पर
उच्च स्तर पर; के सभी उपयोग न्यूक्स (), नवीनीकरण(), तथा सेफफ्री() कॉल करने वाले के साथ लॉग इन हैं
स्रोत कोड फ़ाइल और लाइन नंबर (और सी फ़ंक्शन नाम, यदि सी कंपाइलर द्वारा समर्थित है)।
इसके विपरीत, "-Dm" सीधे "मॉलोक ()" के बिंदु पर है। एसवी लॉगिंग समान है.

चूँकि लॉगिंग PerlIO का उपयोग नहीं करती है, सभी SV आवंटन लॉग किए जाते हैं और कोई अतिरिक्त SV नहीं होता है
लॉगिंग को सक्षम करके आवंटन पेश किए जाते हैं। यदि संकलित किया गया है
"-DDEBUG_LEAKING_SCALARS", प्रत्येक एसवी आवंटन के लिए क्रम संख्या भी लॉग की जाती है।

DDD के ऊपर जी.डी.बी.
जीडीबी पर डीडीडी फ्रंटएंड के साथ पर्ल को डीबग करने वालों को निम्नलिखित उपयोगी लग सकता है:

आप डेटा रूपांतरण शॉर्टकट मेनू का विस्तार कर सकते हैं, उदाहरण के लिए आप एक एसवी प्रदर्शित कर सकते हैं
IV मान एक क्लिक से, बिना कोई टाइपिंग किए। ऐसा करने के लिए बस संपादित करें ~/.ddd/init
फ़ाइल करें और उसके बाद जोड़ें:

! शॉर्टकट प्रदर्शित करें.
Ddd*gdbप्रदर्शनशॉर्टकट: \
/t () // बिन में कनवर्ट करें\n\
/d () // Dec\n\ में कनवर्ट करें
/x () // हेक्स में कनवर्ट करें\n\
/o () // अक्टूबर में कनवर्ट करें(\n\

निम्नलिखित दो पंक्तियाँ:

((XPV*) (())->sv_any )->xpv_pv // 2pvx\n\
((XPVIV*) (())->sv_any )->xiv_iv // 2ivx

तो अब आप आईवीएक्स और पीवीएक्स लुकअप कर सकते हैं या आप वहां sv_peek "रूपांतरण" प्लग कर सकते हैं:

Perl_sv_peek (my_perl, (एसवी *) ()) // sv_peek

(my_perl थ्रेडेड बिल्ड के लिए है।) बस याद रखें कि हर पंक्ति, लेकिन आखिरी पंक्ति,
\n\ से ख़त्म होना चाहिए

वैकल्पिक रूप से init फ़ाइल को इसके माध्यम से इंटरैक्टिव रूप से संपादित करें: तीसरा माउस बटन -> नया डिस्प्ले ->
मेनू संपादित करें

नोट: आप जीडीबी अनुभाग में अधिकतम 20 रूपांतरण शॉर्टकट परिभाषित कर सकते हैं।

C पश्व-अनुरेखन
कुछ प्लेटफ़ॉर्म पर पर्ल सी लेवल बैकट्रेस (प्रतीकात्मक के समान) को पुनः प्राप्त करने का समर्थन करता है
जीडीबी जैसे डिबगर्स करते हैं)।

बैकट्रेस प्रतीक नामों के साथ सी कॉल फ्रेम का स्टैक ट्रेस लौटाता है
(फ़ंक्शन नाम), ऑब्जेक्ट नाम (जैसे "पर्ल"), और यदि यह हो सकता है, तो स्रोत कोड भी
स्थान (फ़ाइल: लाइन)।

समर्थित प्लेटफ़ॉर्म लिनक्स और ओएस एक्स हैं (कुछ *बीएसडी कम से कम आंशिक रूप से काम कर सकते हैं, लेकिन
उनका अभी तक परीक्षण नहीं किया गया है)।

इस सुविधा का परीक्षण एकाधिक थ्रेड के साथ नहीं किया गया है, लेकिन यह केवल बैकट्रेस दिखाएगा
धागे की बैकट्रेसिंग कर रही है।

सुविधा को "कॉन्फ़िगर -ड्यूसेकबैकट्रेस" के साथ सक्षम करने की आवश्यकता है।

"-Dusecbacktrace" संकलन/लिंक करते समय डिबग जानकारी रखने में भी सक्षम बनाता है
(अक्सर: "-जी")। कई कंपाइलर/लिंकर अनुकूलन और रखरखाव दोनों का समर्थन करते हैं
डिबग जानकारी. प्रतीक नाम और स्रोत के लिए डिबग जानकारी आवश्यक है
स्थानों।

बैकट्रेस के लिए स्थैतिक फ़ंक्शन दृश्यमान नहीं हो सकते हैं।

स्रोत कोड स्थान, भले ही उपलब्ध हों, अक्सर गायब या भ्रामक हो सकते हैं
कंपाइलर में उदाहरण के लिए इनलाइन कोड होता है। ऑप्टिमाइज़र स्रोत कोड और मिलान कर सकता है
ऑब्जेक्ट कोड काफी चुनौतीपूर्ण है।

Linux
आप चाहिए BFD (-lbfd) लाइब्रेरी स्थापित करें, अन्यथा "perl" लिंक करने में विफल हो जाएगा।
बीएफडी को आमतौर पर जीएनयू बिनुटिल्स के हिस्से के रूप में वितरित किया जाता है।

सारांश: "कॉन्फ़िगर करें... -Dusecbacktrace" और आपको "-lbfd" की आवश्यकता है।

ओएस एक्स
स्रोत कोड स्थान समर्थित हैं केवल यदि आपके पास डेवलपर टूल हैं
स्थापित. (बीएफडी है नहीं आवश्यकता है।)

सारांश: "कॉन्फ़िगर करें... -Dusecbacktrace" और डेवलपर टूल इंस्टॉल करना होगा
अच्छा है.

वैकल्पिक रूप से, सुविधा को आज़माने के लिए, आप स्वचालित डंपिंग को सक्षम करना चाह सकते हैं
चेतावनी या क्रोक (डाई) संदेश उत्सर्जित होने से ठीक पहले बैकट्रेस जोड़कर
कॉन्फ़िगर के लिए "-Accflags=-DUSE_C_BACKTRACE_ON_ERROR"।

जब तक उपरोक्त अतिरिक्त सुविधा सक्षम नहीं होती, बैकट्रेस कार्यक्षमता के बारे में कुछ भी नहीं
पर्ल/एक्सएस स्तर को छोड़कर, दृश्यमान है।

इसके अलावा, भले ही आपने इस सुविधा को संकलित करने के लिए सक्षम किया हो, आपको इसे सक्षम करने की आवश्यकता है
रनटाइम में एक पर्यावरण चर के साथ: "PERL_C_BACKTRACE_ON_ERROR=10"। यह एक होना चाहिए
वांछित फ़्रेम गणना बताते हुए, शून्य से अधिक पूर्णांक।

पर्ल स्तर से बैकट्रेस पुनर्प्राप्त करना (उदाहरण के लिए XS एक्सटेंशन का उपयोग करके) बहुत अधिक होगा
किसी की अपेक्षा से कम रोमांचक: आम तौर पर आप "रनॉप्स", "एंटरसब" देखेंगे, और नहीं
और भी बहुत कुछ. इस एपीआई को कॉल करने का इरादा है से अंदर पर्ल कार्यान्वयन, नहीं
पर्ल स्तर के निष्पादन से।

बैकट्रेस के लिए C API इस प्रकार है:

get_c_backtrace
free_c_backtrace
get_c_backtrace_dump
डंप_सी_बैकट्रेस

जहर
यदि आप डिबगर में रहस्यमय तरीके से 0xABABABAB या 0xEFEFEFEF से भरा हुआ मेमोरी क्षेत्र देखते हैं, तो आप
का असर देखने को मिल सकता है ज़हर() मैक्रोज़, पर्लक्लिब देखें।

केवल पढ़ने के लिए ऑप्ट्रीज़
आईथ्रेड्स के अंतर्गत ऑप्ट्री केवल पढ़ने के लिए है। यदि आप इसे लागू करना चाहते हैं, तो लिखने की जाँच करें
बग्गी कोड से एक्सेस, सक्षम करने के लिए "-Accflags=-DPERL_DEBUG_READONLY_OPS" के साथ संकलित करें
कोड जो "एममैप" के माध्यम से ओपी मेमोरी आवंटित करता है, और इसे केवल पढ़ने के लिए सेट करता है जब यह ए से जुड़ा होता है
सबरूटीन. किसी ऑप तक कोई भी लेखन पहुंच "सिगबस" में परिणत होती है और निरस्त हो जाती है।

यह कोड केवल विकास के लिए है, और सभी यूनिक्स के लिए भी पोर्टेबल नहीं हो सकता है
वेरिएंट. साथ ही, यह एक 80% समाधान है, जिसमें यह सभी ऑप्स को केवल पढ़ने योग्य बनाने में सक्षम नहीं है।
विशेष रूप से यह "BEGIN" ब्लॉक से संबंधित ऑप स्लैब पर लागू नहीं होता है।

हालाँकि, 80% समाधान के रूप में यह अभी भी प्रभावी है, क्योंकि इसमें अतीत में बग पकड़े गए हैं।

. is a bool नहीं a बूल?
प्री-सी99 कंपाइलर्स पर, "बूल" को "चार" के बराबर परिभाषित किया गया है। फलस्वरूप असाइनमेंट
किसी भी बड़े प्रकार का "बूल" असुरक्षित है और इसे छोटा किया जा सकता है। "cBOOL" मैक्रो मौजूद है
इसे सही ढंग से ढालने के लिए.

उन प्लेटफ़ॉर्म और कंपाइलर्स पर जहां "बूल" वास्तव में एक बूलियन (C++, C99) है, यह आसान है
कलाकारों को भूलने के लिए. आप संकलित करके "बूल" को "चार" बनने के लिए बाध्य कर सकते हैं
"-Accflags=-DPERL_BOOL_AS_CHAR"। आप कुछ इस तरह "कॉन्फ़िगर" चलाना भी चाह सकते हैं

-Accflags='-Wरूपांतरण -नहीं-चिह्न-रूपांतरण -नहीं-छोटा-64-से-32'

या आपके कंपाइलर के समतुल्य से किसी भी असुरक्षित काट-छांट को पहचानना आसान हो जाता है
ऊपर.

RSI .i लक्ष्य
आप मैक्रोज़ का विस्तार कर सकते हैं फू.सी कह कर फाइल

foo.i बनाओ

जो सीपीपी का उपयोग करके मैक्रोज़ का विस्तार करेगा। नतीजों से डरो मत.

onworks.net सेवाओं का उपयोग करके ऑनलाइन perlhacktips का उपयोग करें


फ्री सर्वर और वर्कस्टेशन

विंडोज और लाइनेक्स एप डाउनलोड करें

लिनक्स कमांड

Ad




×
विज्ञापन
❤️यहां खरीदारी करें, बुक करें या खरीदें - कोई शुल्क नहीं, इससे सेवाएं निःशुल्क बनी रहती हैं।