2012-02-11 7 views
7

कभी कभी हम कुछ डिबग प्रिंट हमारे कोड में इस तरहक्या स्टडआउट और stderr के साथ बफरिंग अक्षम करना सुरक्षित है?

printf("successfully reached at debug-point 1\n"); 

some code is here 

printf("successfully reached at debug-point 2"); 

Here segmantaion fault occur due to some reason 

अब इस हालत में डाल केवल डिबग-point1 stdio डिबग सूत्री पर प्रिंट 2 प्रिंट बफर stdio लिए लिखा गया था, लेकिन इसके प्लावित नहीं है क्योंकि यह फ्लॉप हो जाएगा \n मिलता तो हम सोचते हैं कि दुर्घटना के बाद डिबग-point1

इस से आते से अधिक करने के लिए अगर मैं stdio और इस तरह से की तरह stderr धारा के साथ को निष्क्रिय बफरिंग विकल्प

setvbuf(stdout, NULL, _IONBF, 0); 
setvbuf(stderr, NULL, _IONBF, 0); 

तो यह है पाए जाते हैं ऐसा करने के लिए सुरक्षित है?

क्यों सभी स्ट्रीम डिफ़ॉल्ट लाइन buffered द्वारा हैं?

संपादित करें:

आमतौर पर क्या किसी भी फाइल स्ट्रीम के लिए डिफ़ॉल्ट आवंटित बफर द्वारा इस तरह के आकार है? मुझे लगता है कि यह ओएस निर्भर है। मैं लिनक्स के बारे में जानना चाहूंगा?

उत्तर

3

क्यों सब धारा डिफ़ॉल्ट लाइन द्वारा हैं बफ़र

वे प्रदर्शन कारणों से बफ़र कर रहे हैं। पुस्तकालय सिस्टम कॉल करने से बचने के लिए कड़ी मेहनत करता है क्योंकि इसमें लंबा समय लगता है। और उनमें से सभी डिफ़ॉल्ट रूप से buffered नहीं हैं। उदाहरण के लिए stderrआमतौर पर unbuffered और stdout लाइन-बफर्ड केवल तभी होता है जब यह एक tty को संदर्भित करता है।

तो क्या यह सुरक्षित है?

बफरिंग को अक्षम करना सुरक्षित है लेकिन मुझे कहना होगा कि यह सबसे अच्छी डीबगिंग तकनीक नहीं है।

2

उह, ठीक है। आप गलत हैं। इस कारण से सटीक रूप से, stderr डिफ़ॉल्ट रूप से buffered नहीं है।

संपादित करें: इसके अलावा, एक सामान्य सुझाव के रूप में, printf एस के बजाय डीबगर ब्रेकपॉइंट्स का उपयोग करने का प्रयास करें। जीवन को बहुत आसान बनाता है।

6

एक संभावित तरीका bool dodebug वैश्विक ध्वज होना चाहिए और उदाहरण के लिए मैक्रो परिभाषित करना संभव है।

#ifdef NDEBUG 
#define debugprintf(Fmt,...) do{} while(0) 
#else 
#define debugprintf(Fmt,...) do {if (dodebug) {     \ 
    printf("%s:%d " Fmt "\n", __FILE__, __LINE__, ##__VA_ARGS__); \ 
    fflush(stdout); }} while(0) 
#endif 
अपने कोड के अंदर

फिर, कुछ

debugprintf("here i=%d", i); 
बेशक

, यदि आप उपरोक्त मैक्रो में, fprintf बजाय कर सकता है ... सूचना fflush और प्रारूप के साथ जोड़ दिया न्यू लाइन है।

प्रदर्शन कारणों से बफरिंग को अक्षम करना शायद टालना चाहिए।

2

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

 
$ gcc -o segfault -g segfault.c # compile with -g to get debugging symbols 
$ ulimit -c unlimited    # allow core dumps to be written 
$ ./segfault      # run the program 
Segmentation fault (core dumped) 
$ gdb -q segfault /cores/core.3632 # On linux, the core dump will exist in 
            # whatever directory was current for the 
            # process at the time it crashed. Usually 
            # this is the directory from which you ran 
            # the program. 
Reading symbols for shared libraries .. done 
Reading symbols for shared libraries . done 
Reading symbols for shared libraries .. done 
#0 0x0000000100000f3c in main() at segfault.c:5 
5    return *x;   <--- Oh, my, the segfault occured at line 5 
(gdb) print x      <--- And it's because the program dereferenced 
$1 = (int *) 0x0      ... a NULL pointer. 
2

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

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