लिनक्स कर्नेल स्टैक ओवरफ़्लो पर सेगफॉल्ट क्यों उत्पन्न करता है? यह डीबगिंग को बहुत अजीब बना सकता है जब अस्थायी सरणी के प्रवाह में सी या फोर्टन निर्माण में आवंटन होता है। निश्चित रूप से रनटाइम के लिए यह अधिक उपयोगी त्रुटि उत्पन्न करने के लिए संभव है।स्टैक ओवरफ़्लो पर सेगफॉल्ट
उत्तर
"कर्नेल" (यह वास्तव में आपके कोड को चलाने वाला कर्नेल नहीं है, यह सीपीयू है) यह नहीं जानता कि आपका कोड उस स्मृति को संदर्भित कर रहा है, जिसे स्पर्श करने वाला नहीं है। यह केवल जानता है कि आपने इसे करने की कोशिश की है।
कोड:
char *x = alloca(100);
char y = x[150];
वास्तव में सीपीयू द्वारा मूल्यांकन नहीं किया जा सकता है के रूप में आप एक्स की सीमा से परे तक पहुँचने के लिए कोशिश कर रहा। BTW
char y = *((char*)(0xdeadbeef));
, मैं alloca के उपयोग को हतोत्साहित के बाद से ढेर ढेर (उपयोग malloc बजाय) की तुलना में अधिक सीमित हो जाता है:
आप के साथ ठीक उसी पते के हिट हो सकती है।
एक स्टैक ओवरफ़्लो एक सेगमेंटेशन गलती है। जैसा कि आपने स्मृति की दी गई सीमाओं को तोड़ दिया है जिसे आपने प्रारंभ में आवंटित किया था। सीमित आकार का ढेर, और आप इसे पार कर चुके हैं। आप इसके बारे में wikipedia
इसके अतिरिक्त, एक चीज जो मैंने अतीत में परियोजनाओं के लिए की है, वह है सिग्फॉल्ट पर अपना सिग्नल हैंडलर लिखना (मैन पेज सिग्नल (2) देखें)। मैं आमतौर पर सिग्नल पकड़ा और कंसोल में "घातक त्रुटि हुई" लिखा। मैंने चेकपॉइंट झंडे और डिबगिंग के साथ कुछ और चीजें कीं।
सेगफाल्ट डीबग करने के लिए आप जीडीबी में एक प्रोग्राम चला सकते हैं। उदाहरण के लिए, निम्नलिखित सी कार्यक्रम SEGFAULT देगा: # segfault.c # शामिल # शामिल
int main()
{
printf("Starting\n");
void *foo=malloc(1000);
memcpy(foo, 0, 100); //this line will segfault
exit(0);
}
अगर मैं यह इतना तरह संकलन:
gcc -g -o segfault segfault.c
और उसके बाद तो जैसे यह चलाएँ:
$ gdb ./segfault
GNU gdb 6.7.1
Copyright (C) 2007 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-pc-linux-gnu"...
Using host libthread_db library "/lib/libthread_db.so.1".
(gdb) run
Starting program: /tmp/segfault
Starting
Program received signal SIGSEGV, Segmentation fault.
0x4ea43cbc in memcpy() from /lib/libc.so.6
(gdb) bt
#0 0x4ea43cbc in memcpy() from /lib/libc.so.6
#1 0x080484cb in main() at segfault.c:8
(gdb)
मुझे जीडीबी से पता चला कि लाइन 8 पर एक सेगमेंटेशन गलती थी। बेशक एसए को संभालने के अधिक जटिल तरीके हैं सीके ओवरफ्लो और अन्य मेमोरी त्रुटियां, लेकिन यह पर्याप्त होगा।
बस Valgrind का उपयोग करें। यह आपकी सभी स्मृति आवंटन गलतियों को उत्तेजित सटीकता के साथ इंगित करेगा।
आप वास्तव में सिग्नल हैंडलर का उपयोग करके एक स्टैक ओवरफ़्लो के लिए स्थिति को पकड़ सकते हैं।
सेटअप SIGSEGV (segfault) sigaction का उपयोग कर, इस SO_ONSTACK ध्वज सेट करने के लिए एक संकेत हैंडलर:
ऐसा करने के लिए, आपको दो काम करने चाहिए। यह सिग्नल वितरित करते समय कर्नेल को वैकल्पिक स्टैक का उपयोग करने के लिए निर्देश देता है।
एसआईजीएसईजीवी के लिए हैंडलर का उपयोग करने वाले वैकल्पिक स्टैक को सेट करने के लिए सिग्ल्टस्टैक() को कॉल करें।
फिर जब आप ढेर को बहते हैं, तो कर्नेल सिग्नल देने से पहले आपके वैकल्पिक ढेर पर स्विच करेगा। एक बार आपके सिग्नल हैंडलर में, आप उस पते की जांच कर सकते हैं जो गलती का कारण बनता है और यह निर्धारित करता है कि यह एक स्टैक ओवरफ़्लो था, या नियमित गलती थी।
एक स्टैक ओवरफ़्लो आवश्यक रूप से क्रैश उत्पन्न नहीं करता है। यह चुपचाप आपके प्रोग्राम के डेटा को मिटा सकता है लेकिन निष्पादित करना जारी रखता है।
मैं SIGSEGV हैंडलर क्लुज का उपयोग नहीं करता बल्कि इसके बजाय मूल समस्या को ठीक करता हूं।
यदि आप स्वचालित सहायता चाहते हैं, तो आप जीसीसी के -स्टैक-रक्षक विकल्प का उपयोग कर सकते हैं, जो रनटाइम पर कुछ ओवरफ्लो दिखाएगा और प्रोग्राम को रोक देगा।
valgrind गतिशील स्मृति आवंटन कीड़े के लिए अच्छा है, लेकिन स्टैक त्रुटियों के लिए नहीं है।
कुछ टिप्पणियां उपयोगी हैं, लेकिन समस्या स्मृति आवंटन त्रुटियों की नहीं है। कोड में कोई गलती नहीं है। यह फोर्टन में काफी परेशान है जहां रनटाइम ढेर पर अस्थायी मूल्य आवंटित करता है। इस प्रकार लिखने (एफपी) x, y, z जैसे कमांड को कोई चेतावनी के साथ segfault ट्रिगर कर सकते हैं। इंटेल फोरट्रान कंपाइलर के लिए तकनीकी समर्थन का कहना है कि रनटाइम लाइब्रेरी एक और सहायक संदेश मुद्रित करने का कोई तरीका नहीं है। हालांकि अगर मिगुएल सही है तो यह संभव होना चाहिए जैसा कि वह सुझाता है। तो बहुत बहुत धन्यवाद। शेष प्रश्न यह है कि मैं पहली बार सीजी गलती का पता कैसे ढूंढूं और यह पता लगाना चाहिए कि क्या यह एक स्टैक ओवरफ़्लो या किसी अन्य समस्या से आया है।
अन्य लोगों को जो इस समस्या को पाते हैं, उनके लिए एक कंपाइलर ध्वज है जो ढेर पर एक निश्चित आकार के ऊपर अस्थायी varibles डालता है।
- 1. स्टैक ओवरफ़्लो
- 2. स्टैक ओवरफ़्लो
- 3. स्टैक ओवरफ़्लो
- 4. स्टैक ओवरफ़्लो या क्वारा
- 5. स्टैक ओवरफ़्लो वेब आर्किटेक्चर
- 6. स्टैक ओवरफ़्लो क्या है?
- 7. हास्केल स्टैक ओवरफ़्लो
- 8. स्टैक ओवरफ़्लो तक शेष स्टैक का आकार
- 9. स्टैक ओवरफ़्लो शैली कीवर्ड टैग
- 10. रिकर्सिव फ़ंक्शन एक स्टैक ओवरफ़्लो
- 11. एफ # बनाम ओकैम: स्टैक ओवरफ़्लो
- 12. AppDomain.FirstChanceException और स्टैक ओवरफ़्लो अपवाद
- 13. ऑपरेटर अधिभार एक स्टैक ओवरफ़्लो
- 14. स्टैक ओवरफ़्लो और बफर ओवरफ़्लो के बीच क्या अंतर है?
- 15. जावा रेगेक्स स्टैक ओवरफ़्लो पर मर जाता है: बेहतर संस्करण
- 16. स्टैक ओवरफ़्लो पर यादृच्छिक डिफ़ॉल्ट "gravatars" कैसे उत्पन्न करें?
- 17. निरंतर-शैली-प्रोग्रामिंग प्रवण स्टैक ओवरफ़्लो
- 18. स्टैक आकार की निगरानी करके स्टैक ओवरफ़्लो को कैसे रोकें?
- 19. सी # सेट में स्टैक ओवरफ़्लो त्रुटि/
- 20. रैपर DLLs में स्टैक ओवरफ़्लो से बचें
- 21. हास्केल में स्टैक ओवरफ़्लो से कैसे बचें?
- 22. स्टैक ओवरफ़्लो का कारण क्या है?
- 23. आईडीई में स्टैक ओवरफ़्लो एकीकृत करें?
- 24. glgenFramebuffers में सेगफॉल्ट
- 25. WMD (स्टैक ओवरफ़्लो) संपादक को कस्टम बटन जोड़ना
- 26. स्टैक ओवरफ़्लो-स्टाइल टिप्पणियों को लागू करने के विचार
- 27. स्टैक ओवरफ़्लो जैसे क्लीन यूआरएल कैसे प्राप्त करें?
- 28. सी ++ प्रोग्राम में स्टैक ओवरफ़्लो के लक्षण क्या हैं?
- 29. स्टैक ओवरफ़्लो कैसे अपने एसईओ-अनुकूल यूआरएल उत्पन्न करता है?
- 30. क्रैकिंग प्रक्रिया से स्टैक ओवरफ़्लो अपवाद को रोकें
हालांकि कट्टर हेरफेर के लिए स्टैकस्पेस बहुत तेज है। बस थोड़ी देर का उपयोग करें। इसके अलावा, किसी भी alloca करने से पहले "Getrlimit" की जांच करें। सुनिश्चित करें कि आपके पास पर्याप्त जगह शेष है! –