पीवीएस-स्टूडियो का उपयोग करके एक क्यूटी कार्यक्रम के स्थिर विश्लेषण का अनुभव

छवि यह लेख एक काफी बड़े कार्यक्रम के स्थिर विश्लेषण के मेरे पहले अनुभव का परिणाम है (वर्तमान में स्रोत कोड के साथ 1665 फाइलें)। इसके अलावा, यह Microsoft Visual Studio का उपयोग करने का मेरा पहला अनुभव है। विश्लेषण कार्यक्रम का विकास विशेष रूप से उबंटू, एक्लिप्स सीडीटी, जीसीसी संकलक में किया गया था।



परियोजना की तैयारी



यदि आप "स्टूडियो" में धाराप्रवाह हैं और लंबे समय से सीख चुके हैं कि इसमें क्यूटी परियोजनाएं कैसे विकसित की जाए, तो इस अनुभाग को छोड़ दें, क्योंकि यहाँ VS2010 के लिए एक परियोजना तैयार करने का मेरा तरीका है।



चूंकि मैं क्यूटी ढांचे पर आधारित एक कार्यक्रम विकसित कर रहा हूं, इसलिए मेरी परियोजना में एक .pro फ़ाइल है। यह फ़ाइल प्रोजेक्ट जनरेट करने का आधार है। Qt वेबसाइट ( http://doc.qt.nokia.com/stable/qmake-project-files.html ) बताती है कि क्यूमेक आपको "स्टूडियो" प्रोजेक्ट बनाने की अनुमति देता है। ऐसा करने के लिए, कमांड का उपयोग करें:

$ {QTDIR} \ bin \ qmake.exe -t vcapp -spec $ {QTDIR} \ mkspecs \ win32-msvc2010


तब प्रोजेक्ट फ़ाइल * .vcxproj दिखाई देगी, जिसे "स्टूडियो" द्वारा खोला जाता है। अधिक जोड़तोड़ की आवश्यकता नहीं थी - परियोजना सफलतापूर्वक संकलित है।



पीवीएस-स्टूडियो की स्थापना और विन्यास



स्थापना असंभव के लिए सरल है: डाउनलोड, स्थापित, पुनरारंभ और अब मेनू में पहले से ही वांछित टैब है - पीवीएस-स्टूडियो। मुझे सेटअप के साथ थोड़ी छेड़छाड़ करनी पड़ी। मेरे लिए अज्ञात कारणों से, प्रोजेक्ट का विश्लेषण करते समय (PVS-Studio-> चेक सॉल्यूशन) PVS Qt हैडर फाइल्स (उदाहरण के लिए, QWidget.h या QObject.h) को नहीं ढूँढ सकता है, हालाँकि, फिर से, प्रोजेक्ट बिना त्रुटियों के कम्पाइल होता है। इस स्थिति को ठीक करने के लिए, आपको प्रोजेक्ट सेटिंग्स (प्रोजेक्ट पर राइट-क्लिक करें -> गुण) में जाने की आवश्यकता है, "VC ++ निर्देशिकाएँ" का चयन करें और "डायरेक्टरी शामिल करें" अनुभाग क्यूटी हेडर फ़ाइलों के पथ निर्दिष्ट करें। इसके अलावा, आपको क्यूटी के न केवल रूट फ़ोल्डर को निर्दिष्ट करना होगा, बल्कि आपके द्वारा उपयोग किए जाने वाले मॉड्यूलर सबफ़ोल्डर्स को भी शामिल करना होगा। यही है, अगर .pro फ़ाइल इंगित करती है कि आपकी परियोजना कोर, गुई, xml, sql, नेटवर्क, वेबकिट, opengl मॉड्यूल का उपयोग करती है, तो आपको शामिल करने की आवश्यकता है, जिसमें \ qtcore, inclide \ qtgui शामिल हैं, शामिल हैं \ qtxml, \ qtxmlpatterns, \ qtsql, \ qtnetwork शामिल, \ qtwebkit, \ qtopengl शामिल हैं। इन कार्यों को लागू करने के बाद, पीवीएस-स्टूडियो सही तरीके से काम करना शुरू कर देता है।



स्थैतिक विश्लेषण



विश्लेषण में लगभग 4 घंटे लगे, उस समय मैं स्नोबोर्डिंग कर रहा था। तो, यह पता चला था: श्रेणी 3



इस श्रेणी में, ~ 250 (कुल का 87% प्रतिशत) चेतावनी “V001। 'फ़ाइल' से एक कोड के टुकड़े का विश्लेषण नहीं किया जा सकता है , '' रिपोर्ट करते हुए कि पीवीएस एक विशिष्ट फ़ाइल को पार्स करने में विफल रहा। कई चेतावनियाँ ऑटो-जनरेटेड फाइल्स को संदर्भित करती हैं, जैसे moc * .cpp। यह मेरे लिए अधिक सुविधाजनक होगा यदि पीवीएस ने इन फाइलों को पार्स करने की कोशिश नहीं की।



अगली सबसे लोकप्रिय चेतावनी "V550" है। एक अजीब सटीक तुलना। परिभाषित सटीकता के साथ तुलना का उपयोग करना बेहतर है: फ़ैब्स (ए - बी) <एप्सिलॉन या फैब्स (ए - बी)> एप्सिलॉन" चेतावनियों के विश्लेषण में 8 झूठी सकारात्मकता और 1 सच दिखाया गया।



इस ब्लॉक में निम्नलिखित चेतावनी है: “V126। सलाह दी जाती है कि 'लंबी' प्रकार का आकार LLP64 / LP64 डेटा मॉडल के बीच भिन्न होता है : "

यह नैदानिक ​​संदेश आपको किसी प्रोग्राम में उपयोग किए जाने वाले सभी 'लंबे' प्रकारों को खोजने की सुविधा देता है।

बेशक, एक कार्यक्रम में 'लंबे' प्रकार की उपस्थिति अपने आप में एक त्रुटि नहीं है। लेकिन आपको प्रोग्राम टेक्स्ट के उन सभी अंशों की समीक्षा करने की आवश्यकता हो सकती है जहाँ इस प्रकार का उपयोग तब किया जाता है जब आप पोर्टेबल 64-बिट कोड बनाते हैं जो विंडोज और लिनक्स में अच्छी तरह से काम करना चाहिए।

विंडोज और लिनक्स 64-बिट आर्किटेक्चर के लिए विभिन्न डेटा मॉडल का उपयोग करते हैं। एक डेटा मॉडल का मतलब आधार डेटा प्रकारों जैसे कि इंट, फ्लोट, पॉइंटर आदि के सहसंबंध हैं। Windows LLP64 डेटा मॉडल का उपयोग करता है जबकि Linux LP64 डेटा मॉडल का उपयोग करता है। इन मॉडलों में, 'लंबे' प्रकार के आकार भिन्न होते हैं।

विंडोज (LLP64) में, 'लंबे' प्रकार का आकार 4 बाइट्स है।

लिनक्स (LP64) में, 'लंबे' प्रकार का आकार 8 बाइट्स है।

'लंबे' प्रकार के आकार का अंतर फ़ाइलों के प्रारूपों को असंगत बना सकता है या लिनक्स और विंडोज में निष्पादित कोड विकसित करते समय त्रुटियां पैदा कर सकता है। इसलिए यदि आप चाहें, तो आप उन सभी कोड अंशों की समीक्षा करने के लिए पीवीएस-स्टूडियो का उपयोग कर सकते हैं जहां 'लंबे' प्रकार का उपयोग किया जाता है।
मुझे याद दिलाएं कि मैं क्यूटी ढांचे का उपयोग करता हूं और इसलिए लंबे प्रकार का उपयोग करना आमतौर पर खराब स्वर है, आपको क्रॉस-प्लेटफॉर्म विकास के लिए qint16, qint32 और qint64 का उपयोग करने की आवश्यकता है। एकमात्र सवाल यह है कि इस मामले में पीवीएस का उपयोग पूरे प्रोजेक्ट की खोज से बेहतर कैसे होगा। आखिरकार, ये चेतावनियाँ Viva64 पर लागू होती हैं - एक प्रदत्त उत्पाद। इन चेतावनियों के लिए कोड चेतावनियाँ अक्षम हैं (समझ और संपादन बहुत मुश्किल हो जाता है)।



एक चेतावनी जिसे मैं कार्यक्रम की सत्यता के कारण विश्लेषण नहीं कर सका:

"V111। फ़ंक्शन 'फू' को वेरिएबल संख्याओं के तर्क के साथ। N तर्क ने प्रकार को याद रखा "



श्रेणी 2



इस श्रेणी में एक निराशाजनक स्थिति थी: सामान्य विश्लेषण (मुक्त विश्लेषण) से संबंधित चेतावनी - 4 टुकड़े (कुल का 2% ) और Viva64 से 160 परीक्षण चेतावनी।



विडंबना यह है कि, परीक्षण चेतावनी के शेर का हिस्सा "V112" को संदर्भित करता है। खतरनाक मैजिक नंबर एन का उपयोग किया जाता है , जो कि श्रेणी 3 में भी पाए जाते हैं। किस सिद्धांत से पीवीएस ने श्रेणी 2 में भाग लिया, और श्रेणी 3 में भाग मेरे लिए एक रहस्य है। मेरा मानना ​​है कि इस चेतावनी के विश्लेषक में सुधार किया जाना चाहिए, क्योंकि एक सरसरी निरीक्षण ने ~ 90% झूठी सकारात्मकता दिखाई। मैं यहां तक ​​कहूंगा कि एक भी सच्ची प्रतिक्रिया नहीं मिली। लेकिन मैंने पूरे नमूने की जांच नहीं की, क्योंकि ट्रायलिटी ने चाल चली - मैं थक गया हूं। इस चेतावनी के अनुसार, जादू की संख्या मुख्य रूप से ड्राइंग प्रक्रियाओं में पाई गई थी, जैसे: विभिन्न इंडेंट और ऑफ़सेट सेट करना।



नि : शुल्क प्रवेश अलर्ट:



"V537। 'X' आइटम के उपयोग की शुद्धता की समीक्षा करने पर विचार करें :

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

int x = static_cast <int> (GetX ()) * n;

int y = static_cast <int> (GetX ()) * n;

दूसरी पंक्ति में, GetY () के बजाय गेटएक्स () फ़ंक्शन का उपयोग किया जाता है। यह सही कोड है:

int x = static_cast <int> (GetX ()) * n;

int y = static_cast <int> (GetY ()) * n;

- झूठी सकारात्मक। यहाँ कोड है:

int width = img_in->width();

int height = img_in->height();



if (width > height) {

if (width > maxWidth) {

height = ( int ) (( float ) maxWidth / width * height);

width = maxWidth;

}

} else {

if (height > maxHeight) {

/**/ width = ( int ) (( float ) maxHeight / height * width);

height = maxHeight;

}

}




* This source code was highlighted with Source Code Highlighter .








"V525। समान ब्लॉकों के संग्रह वाले कोड। X, Y, Z, ... को लाइनों N1, N2, N3, में चेक करें



पेड एक्सेस अलर्ट:



"V401। खेतों के क्रम को बदलकर संरचना के आकार को कम किया जा सकता है। आकार को N से K बाइट्स तक कम किया जा सकता है, " :

विश्लेषक ने एक डेटा संरचना का पता लगाया जो मुख्य मेमोरी के अप्रभावी उपयोग को जन्म दे सकता है।

आइए एक संरचना के उदाहरण पर विचार करें जिसे Viva64 अप्रभावी घोषित करेगा:

संरचना LiseElement {

बूल m_isActive;

char * m_pNext;

int m_value;

};

यह संरचना 64-बिट कोड में 24 बाइट्स पर कब्जा कर लेगी, जो डेटा संरेखण से संबंधित है। लेकिन अगर आप खेतों के क्रम को बदलते हैं तो इसका आकार 16 बाइट पर कब्जा कर लेगा। संरचना का अनुकूलित संस्करण निम्नानुसार दिखेगा:

संरचना LiseElement {

char * m_pNext;

int m_value;

बूल m_isActive;

};

...

फिलहाल मैं यह नहीं समझ सकता कि यह कैसे संभव है, लेकिन अगर यह सच है, तो यह बहुत अच्छा है - यह चेतावनी मेरे लिए बहुत उपयोगी है, धन्यवाद।



श्रेणी 1



स्थिति 2 श्रेणी के समान है: केवल 1 मुफ्त चेतावनी और 119 भुगतान किया गया है।



नि : शुल्क चेतावनी:

"V524। यह अजीब है कि 'Foo_1' फ़ंक्शन पूरी तरह से '' Foo_2 'फ़ंक्शन के बराबर है - गलत सकारात्मक:

const qreal और getX () const {

फेंक std :: runtime_error ("असमर्थित संचालन त्रुटि");

}



const असली और getY () const {

फेंक std :: runtime_error ("असमर्थित संचालन त्रुटि");

}





भुगतान की चेतावनी:



"V103। मेम्सेज़ प्रकार से 32-बिट प्रकार के लिए अनुमानित प्रकार रूपांतरण,

"V104। एक अंकगणितीय अभिव्यक्ति में टाइप करने के लिए अनुमानित प्रकार रूपांतरण,

"V110। मेम्सेज़ प्रकार से 32-बिट प्रकार में वापसी मूल्य का अनुमानित प्रकार रूपांतरण,

"V302। 'फू' वर्ग के सदस्य ऑपरेटर [] के पास 32-बिट प्रकार का तर्क है। यहां मेमेसाइज़-प्रकार का उपयोग करें - ये चेतावनी Qt स्रोत कोड में पाए गए, विशेष रूप से qtessolator.cpp फ़ाइल में। ट्रायल होने के कारण सच्चाई का सत्यापन नहीं किया जा सका।



कुछ त्रुटियों के लिए, विशेष रूप से V114 में , PVS-Studio V121 चेतावनियों को दोहराता है । इसलिए, चेतावनियों की सूची में एक ही पंक्ति के संदर्भ में एक ही प्रकार की चेतावनियों के औसत 4 उदाहरण हैं।



परिणाम



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



उपकरण जारी किया गया 6 ( 2.11% ) मुफ्त और 278 ( 97.89% ) भुगतान अलर्ट (बिना तीसरी श्रेणी के)। यह बहुत कम मुक्त हो जाता है, आप इसे आज़मा भी नहीं सकते। V112 (जादू नंबर) से संबंधित चेतावनी एक झूठी सकारात्मक देती है, और उनमें से बहुत कुछ हैं - आप उन्हें जांचने से थक जाते हैं, खासकर जब से वे भुगतान किए जाते हैं।



क्या मैं यह उपकरण खरीदूंगा? दुर्भाग्य से, नहीं। मैंने बड़ी संख्या में झूठी सकारात्मकता के कारण स्थापित करने और विश्लेषण करने में बहुत समय बिताया। लगभग 500 चेतावनियों के लिए एक झूठी सकारात्मक बहुत क्रूर है। आश्चर्यजनक रूप से, एक उपयोगी चेतावनी 3 श्रेणियों में थी (जैसा कि मैंने इसे सबसे गैर-महत्वपूर्ण में समझा था)। ऑटो-जनरेट की गई फ़ाइलों में 250 अलर्ट मिले। मैं एक पूर्व-विन्यास देखना चाहूंगा जो ऐसी फ़ाइलों को प्रसंस्करण से बाहर करता है (उदाहरण के लिए, Qt moc फ़ाइलें)। सबसे अधिक मैं V401 की चेतावनी से खुश था (आप आकार को कम कर सकते हैं)। यह वही है जो मैं खरीदूंगा! मैं उन सभी चेतावनियों को खरीदूंगा जो मुझे आकार को कम करने और अपने आवेदन की गति बढ़ाने की अनुमति देंगी।



आपका धन्यवाद



All Articles