2013-05-03 3 views
6
#include <stdio.h> 
#include <string.h> 

int main() 
{ 
    char arrDst[5] = {0}; 
    char arrSrc[10] = "123456"; 
    memcpy(arrDst, arrSrc, sizeof(arrSrc)); 
    return 0; 
} 

यहां इस कार्यक्रम में यह स्पष्ट है कि स्मृति मेमोरी है।क्या जीसीसी कंपाइलर के पास संकलन समय पर स्मृति भ्रष्टाचार को पहचानने का कोई विकल्प है?

क्या जीसीसी कंपाइलर में कोई विकल्प है जिसके द्वारा मैं संकलन समय पर इस समस्या को पहचान सकता हूं?

नोट: मैंने valgrind --leak-check=full का उपयोग किया, लेकिन इससे मदद नहीं मिलती है।

+3

यह एक स्मृति रिसाव नहीं है: इस मामले में पूर्व शर्त है कि विफल रहता सूची में पहले, लिखने के लिए गंतव्य की वैधता के बारे में है। Valgrind केवल तभी मिल सकता है जब आप 'malloc() ' –

+0

के साथ बफर आवंटित करते हैं, आपको ऐसा क्यों लगता है कि स्मृति भ्रष्टाचार स्पष्ट है? कंपाइलर memcpy के अर्थशास्त्र के लिए कोई धारणा नहीं कर सकता है। – swegi

+0

@ स्वेगी: कंपाइलर जानता है कि 'memcpy' के अर्थशास्त्र क्या हैं; वह नाम सी मानक द्वारा कार्यान्वयन के लिए आरक्षित है, इसलिए यदि आप अपना खुद का 'memcpy' फ़ंक्शन लिखते हैं जो कुछ अलग करता है, तो संकलक को इसे अवहेलना करने की अनुमति है और मान लीजिए कि आप '' फ़ंक्शन को कॉल कर रहे हैं। –

उत्तर

7
$ gcc -Wall -O1 t.c 
In file included from /usr/include/string.h:642:0, 
       from t.c:3: 
In function ‘memcpy’, 
    inlined from ‘main’ at t.c:13:9: 
/usr/include/bits/string3.h:52:3: warning: call to __builtin___memcpy_chk 
    will always overflow destination buffer [enabled by default] 

जीसीसी इनमें से कुछ पहचान सकते हैं। आमतौर पर ऑप्टिमाइज़ेशन (कम से कम -01) और चेतावनियां (-Wall) को चालू करने की आवश्यकता होती है, -Wextra भी जोड़ें)।

+3

'-Wall' डिफ़ॉल्ट होना चाहिए :-) –

+0

@AaronDigulla मैं सहमत हूं। यह बहुत सी चीजें सिखाता है! – Chani

2

यह बड़े कार्यक्रम तुम सच में रुचि रखते हैं करने के लिए पैमाने पर नहीं हो सकता है, लेकिन आप Frama-C के साथ इस त्रुटि पा सकते हैं:

$ frama-c -cpp-command "gcc -C -E -I`frama-c -print-share-path`/libc/ -nostdinc" mem.c `frama-c -print-share-path`/libc/fc_runtime.c -val 
... 
[value] computing for function memcpy <- main. 
    Called from mem.c:13. 
.../libc/string.h:54:[value] Function memcpy: precondition got status invalid. 

इस संदेश का अर्थ है कि आप तर्क है कि अपने अनुबंध को पूरा नहीं करते के साथ memcpy() बुला रहे हैं । यह एक बफर सीमा से अधिक है,

/*@ requires \valid(((char*)dest)+(0..n - 1));                             
    @ requires \valid_read(((char*)src)+(0..n - 1));                            
    @ requires \separated(((char *)dest)+(0..n-1),((char *)src)+(0..n-1));                       
    @ assigns ((char*)dest)[0..n - 1] \from ((char*)src)[0..n-1];                         
    @ assigns \result \from dest;                                 
    @ ensures memcmp((char*)dest,(char*)src,n) == 0;                            
    @ ensures \result == dest;                                  
    @*/ 
extern void *memcpy(void *restrict dest, 
        const void *restrict src, size_t n); 
+1

यह ढांचा दिलचस्प लग रहा है। अगर यह केवल 'पूर्व शर्त' जैसे उपयोगी त्रुटि संदेशों का उत्पादन करेगा \ वैध ((char *) dest) + (0..n - 1)); " असफल '.... :-) –

+1

@AaronDigulla मैं इस सुझाव को फीचर अनुरोध के रूप में दर्ज करूंगा। धन्यवाद! (प्रयोज्यता सही हो रही है। जब आप अक्सर कुछ उपयोग करते हैं तो आप इसे काम करने के तरीके में उपयोग करते हैं और इन दोषों को और नहीं देख सकते हैं) –

+2

इसे प्रयोग करने योग्य बनाने के लिए, मैं सुझाव देता हूं कि प्रत्येक आवश्यकता को एक नाम दें जैसे कि "काफी बड़ा "," src बड़ा पर्याप्त "," कोई ओवरलैप नहीं " –

संबंधित मुद्दे