2008-10-17 19 views
203

"बस त्रुटि" संदेश का क्या अर्थ है, और यह segfault से अलग कैसे है?बस त्रुटि क्या है?

+2

मैं दोनों के लिए एक सरल स्पष्टीकरण जोड़ना चाहता हूं: सेगमेंटेशन गलती का मतलब है कि आप उस स्मृति तक पहुंचने का प्रयास कर रहे हैं जिसकी आपको अनुमति नहीं है (ई जी। यह आपके प्रोग्राम का हिस्सा नहीं है)। हालांकि, बस त्रुटि पर इसका आमतौर पर मतलब है कि आप उस स्मृति तक पहुंचने का प्रयास कर रहे हैं जो मौजूद नहीं है (ई जी। आप 12 जी पर किसी पते तक पहुंचने का प्रयास करते हैं लेकिन आपके पास केवल 8 जी मेमोरी है) या यदि आप उपयोग करने योग्य मेमोरी की सीमा को पार करते हैं। – xdevs23

उत्तर

189

बस त्रुटियों 86 पर आजकल दुर्लभ हैं और होते हैं, जब आपके प्रोसेसर भी, स्मृति पहुंचने का अनुरोध करने का प्रयास नहीं कर सकते हैं आम तौर पर:

  • वाले पते पर अपने संरेखण आवश्यकताओं को पूरा नहीं करता है के साथ एक प्रोसेसर अनुदेश का उपयोग कर।

विभाजन दोष होते हैं, जब स्मृति जो अपनी प्रक्रिया से संबंधित नहीं है, उन तक पहुंचने वे बहुत आम हैं और आम तौर पर के परिणाम हैं: कुछ है कि पुनः आवंटित की जाती किया गया था करने के लिए एक सूचक का उपयोग कर

  • एक अनियमित इसलिए बोगस पॉइंटर का उपयोग कर।
  • एक शून्य सूचक का उपयोग कर।
  • एक बफर बह रहा है।

पीएस: अधिक सटीक होने के लिए यह पॉइंटर में हेरफेर नहीं कर रहा है जो मुद्दों का कारण बनता है, यह उस स्मृति को एक्सेस कर रहा है जो इसे इंगित करता है (dereferencing)।

+71

वे दुर्लभ नहीं हैं; मैं केवल हार्ड 9 सीखने के तरीके से अभ्यास 9 पर हूं और पहले से ही सामना कर रहा हूं ... – 11684

+11

बस त्रुटियों का एक और कारण (लिनक्स पर) तब होता है जब ऑपरेटिंग सिस्टम भौतिक स्मृति के साथ वर्चुअल पेज को वापस नहीं कर सकता (उदाहरण के लिए विशाल पृष्ठ मेमोरी का उपयोग करते समय कम स्मृति की स्थिति या विशाल पृष्ठों से बाहर।) आमतौर पर mmap (और malloc) केवल वर्चुअल एड्रेस स्पेस को आरक्षित करता है, और कर्नेल मांग पर भौतिक स्मृति निर्दिष्ट करता है (जिसे मुलायम पृष्ठ दोष कहा जाता है।) काफी बड़ा बनाएं malloc, और उसके बाद पर्याप्त लिखो और आपको एक बस त्रुटि मिल जाएगी। – Eloff

+0

मेरे लिए '/ var/cache' युक्त विभाजन बस पूर्ण था https://askubuntu.com/a/915520/493379 – c33s

2

यह आपके ओएस, सीपीयू, कंपाइलर और संभवतः अन्य कारकों पर निर्भर करता है।

सामान्यतः इसका मतलब है कि सीपीयू बस एक आदेश पूरा नहीं कर सका, या एक संघर्ष का सामना करना पड़ा, लेकिन इसका मतलब पर्यावरण और कोड के चलते चीजों की पूरी श्रृंखला हो सकता है।

-Adam

9

मेरा मानना ​​है कि गिरी SIGBUS को जन्म देती है जब एक आवेदन प्रदर्शन डेटा डेटा बस में मिसलिग्न्मेंट। मुझे लगता है कि कि चूंकि अधिकांश [?] आधुनिक compilers सबसे प्रोसेसर के लिए पैड/प्रोग्रामर के लिए डेटा संरेखित, प्राचीन काल (कम से कम) की संरेखण मुसीबतों को कम किया है, और इसलिए एक भी अक्सर SIGBUS नहीं देखता इन दिनों (AFAIK)।

से: Here

+0

आप अपने कोड के साथ कर रहे गंदे चाल पर निर्भर करता है। यदि आप पॉइंटर गणित की तरह कुछ मूर्खतापूर्ण करते हैं और फिर किसी समस्या मोड तक पहुंच के लिए टाइपकास्ट करते हैं (यानी आप एक uint8_t सरणी सेट करते हैं, तो एक, दो, या तीन को सरणी के पॉइंटर में जोड़ते हैं और फिर टाइपकास्ट करते हैं तो आप एक BUS त्रुटि/संरेखण ट्रैप को ट्रिगर कर सकते हैं। एक छोटा, int, या लंबा और अपमानजनक परिणाम तक पहुंचने का प्रयास करें।) X86 सिस्टम आपको वास्तविक प्रदर्शन दंड के बावजूद ऐसा करने देगा। * कुछ * एआरएमवी 7 सिस्टम आपको ऐसा करने देंगे - लेकिन अधिकांश एआरएम, एमआईपीएस, पावर इत्यादि आपके ऊपर घूमते हैं। – Svartalf

68

एक segfault स्मृति है कि आप का उपयोग करने की अनुमति नहीं पहुँच रहा है। यह केवल पढ़ने के लिए है, आपके पास अनुमति नहीं है, आदि ...

एक बस त्रुटि स्मृति तक पहुंचने का प्रयास कर रही है जो संभवतः वहां नहीं हो सकती है। आपने उस पते का उपयोग किया है जो सिस्टम के लिए व्यर्थ है, या उस ऑपरेशन के लिए गलत प्रकार का पता है।

2

यह आमतौर पर एक गैर-गठबंधन पहुंच का मतलब है।

भौतिक रूप से मौजूद स्मृति तक पहुंचने का प्रयास बस त्रुटि भी देगा, लेकिन यदि आप एक एमएमयू और एक ओएस के साथ प्रोसेसर का उपयोग कर रहे हैं तो आप इसे नहीं देख पाएंगे, क्योंकि आपने ' आपकी प्रक्रिया की पता स्थान पर मैप की गई कोई भी मौजूद स्मृति नहीं है।

+2

माई आई 7 में निश्चित रूप से एक एमएमयू है, लेकिन मैं अभी भी ओएस एक्स पर सी सीखते समय इस त्रुटि में आया हूं (अनन्य पॉइंटर को 'स्कैनएफ' में पास करना)। क्या इसका मतलब है कि ओएस एक्स मैवरिक्स छोटी है? गैर-बग्गी ओएस पर व्यवहार क्या होता? –

3

बस त्रुटि का एक क्लासिक उदाहरण कुछ आर्किटेक्चर पर है, जैसे कि SPARC (कम से कम कुछ SPARCs, शायद यह बदला गया है), जब आप गलत गठबंधन पहुंच करते हैं। उदाहरण के लिए:

unsigned char data[6]; 
(unsigned int *) (data + 2) = 0xdeadf00d; 

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

+1

मामले में, मेरे पास डेटा था [8]; यह अब 32-बिट आर्किटेक्चर में 4 का एक बहु है। तो, यह गठबंधन है। क्या मुझे अभी भी त्रुटि मिल जाएगी? साथ ही, कृपया समझाएं, क्या पॉइंटर्स के लिए डेटा प्रकार रूपांतरण के लिए यह एक बुरा विचार है। क्या यह एक नाजुक वास्तुकला पर गलत संरेखण त्रुटियों का कारण बन जाएगा। कृपया विस्तृत करें, यह मेरी मदद करेगा। –

+0

हे। यह इतना अधिक प्रकार का रूपांतरण नहीं है क्योंकि आप पॉइंटर पर टाइप रूपांतरण कर रहे हैं जिस पर आपने पॉइंटर गणित किया है। ऊपर दिए गए कोड पर * ध्यान से * देखो। कंपाइलर ने सावधानीपूर्वक डेटा के लिए अपने पॉइंटर को गठबंधन किया है- और फिर आपने दो बार संदर्भ को ऑफ़सेट करके कंपाइलर पर सबकुछ पेंच किया है और गैर-डवर्ड सीमा होने के बारे में क्या गठबंधन किया जा सकता है, इस पर गठबंधन करने के लिए बहुत अधिक आवश्यकता है। – Svartalf

+0

"Fragile" वह शब्द नहीं है जिसका मैं उपयोग करता हूं।X86 मशीनों और कोड ने लोगों को थोड़ी देर के लिए मूर्खतापूर्ण चीजें मिल रही हैं, यह उनमें से एक है। यदि आपको इस तरह की समस्या हो रही है तो अपने कोड पर पुनर्विचार करें- यह X86 पर शुरू करने के लिए बहुत ही प्रभावशाली नहीं है। – Svartalf

5

आप कुछ कारणों से कोड पेज को पेज़ नहीं किया जा सकता है जब आप सिगबस भी प्राप्त कर सकते हैं।

+4

यह तब होता है जब मैं प्रक्रिया को चलाते समय .so फ़ाइल को अद्यतन करता हूं – poordeveloper

+0

ऐसा करने का एक और कारण यह है कि यदि आप '/ dev/shm' – ilija139

-1

एक ठेठ बफर अतिप्रवाह जो बस त्रुटि में परिणाम है,

{ 
    char buf[255]; 
    sprintf(buf,"%s:%s\n", ifname, message); 
} 

यहाँ अगर दोहरे उद्धरण में स्ट्रिंग ("") के आकार buf आकार की तुलना में अधिक है, यह बस त्रुटि देता है।

+1

हे के आकार से बड़ी फ़ाइल को 'mmap' करने का प्रयास करते हैं ... यदि यह मामला था, तो आपके पास हर समय पढ़ने वाले स्टैक स्मैशिंग शोषण के बजाय BUS त्रुटि चिंताएं होती हैं विंडोज और अन्य मशीनें। बस त्रुटियां "स्मृति" तक पहुंचने के प्रयास के कारण होती हैं जो मशीन बस एक्सेस नहीं कर सकती क्योंकि पता अमान्य है। (इसलिए शब्द "बस" त्रुटि।) यह अमान्य संरेखण सहित कई विफलताओं के कारण हो सकता है, और जैसे-जैसे प्रोसेसर बस लाइनों पर पता नहीं लगा सकता है। – Svartalf

0

ऊपर दिए गए blxtd में जोड़ने के लिए, बस त्रुटियां भी होती हैं जब आपकी प्रक्रिया किसी विशेष 'चर' की स्मृति तक पहुंचने का प्रयास नहीं कर सकती है।

for (j = 0; i < n; j++) { 
       for (i =0; i < m; i++) { 
         a[n+1][j] += a[i][j]; 
       } 
     } 

सूचना 'पाश के लिए' पहले में चर 'i' की 'अनजाने के उपयोग? यही कारण है कि इस मामले में बस त्रुटि उत्पन्न हो रही है।

2

एक बस त्रुटि का एक विशिष्ट उदाहरण मैं सिर्फ जबकि ओएस एक्स पर प्रोग्रामिंग सी का सामना करना पड़ा:

#include <string.h> 
#include <stdio.h> 

int main(void) 
{ 
    char buffer[120]; 
    fgets(buffer, sizeof buffer, stdin); 
    strcat("foo", buffer); 
    return 0; 
} 

मामले में आप डॉक्स याद नहीं है strcat पहला तर्क बदलकर पहले करने के लिए दूसरा तर्क संलग्न कर देता है (तर्कों को फ्लिप करें और यह ठीक काम करता है)। लिनक्स पर यह एक सेगमेंटेशन गलती (अपेक्षित के रूप में) देता है, लेकिन ओएस एक्स पर यह बस त्रुटि देता है। क्यूं कर? मैं वास्तव में नहीं जानता।

+0

शायद ढेर ओवरफ्लो सुरक्षा बस त्रुटि को बढ़ाता है। – Joshua

+1

'" foo "' स्मृति के केवल पढ़ने वाले खंड में संग्रहीत है, इसलिए इसे लिखना असंभव है। यह ढेर अतिप्रवाह संरक्षण नहीं होगा, बस स्मृति लिखने की सुरक्षा (यदि आपका प्रोग्राम स्वयं को फिर से लिख सकता है तो यह एक सुरक्षा छेद है)। –

0

मुझे अभी एक कठिन तरीका पता चला है कि एआरएमवी 7 प्रोसेसर पर आप कुछ कोड लिख सकते हैं जो आपको अप्रत्याशित होने पर सेगमेंटेशन गलती देता है, लेकिन -O2 (अधिक अनुकूलित) के साथ संकलित होने पर आपको बस त्रुटि देता है। मैं ubuntu x64 से gcc arm gnueabihf क्रॉस कंपाइलर का उपयोग कर रहा हूं।

3

mmap न्यूनतम POSIX 7 उदाहरण

"बस त्रुटि" होता गिरी एक प्रक्रिया के लिए SIGBUS भेजता है।

एक न्यूनतम उदाहरण है कि यह पैदा करता है क्योंकि ftruncate भुला दिया गया:

#include <fcntl.h> /* O_ constants */ 
#include <unistd.h> /* ftruncate */ 
#include <sys/mman.h> /* mmap */ 

int main() { 
    int fd; 
    int *map; 
    int size = sizeof(int); 
    char *name = "/a"; 

    shm_unlink(name); 
    fd = shm_open(name, O_RDWR | O_CREAT, (mode_t)0600); 
    /* THIS is the cause of the problem. */ 
    /*ftruncate(fd, size);*/ 
    map = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); 
    /* This is what generates the SIGBUS. */ 
    *map = 0; 
} 

रन के साथ:

gcc -std=c99 main.c -lrt 
./a.out 

Ubuntu 14.04 में परीक्षण किया गया।

POSIX describesSIGBUS के रूप में:

एक स्मृति वस्तु का एक अपरिभाषित भाग के लिए प्रवेश।

mmap spec का कहना है कि: पता सीमा के भीतर

संदर्भ पा से शुरू होकर एक वस्तु के अंत में एक SIGBUS संकेत के वितरण में परिणित हो जाएगा निम्नलिखित पूरे पृष्ठों के लिए लेन बाइट्स के लिए जारी है।

और shm_opensays that यह आकार 0 की वस्तुओं उत्पन्न करता है:

साझा स्मृति वस्तु शून्य के आकार की है।

तो *map = 0 पर हम आवंटित ऑब्जेक्ट के अंत से छू रहे हैं।

1

मैक ओएस एक्स पर बस त्रुटि के लिए मेरा कारण यह था कि मैंने स्टैक पर लगभग 1 एमबी आवंटित करने का प्रयास किया था। यह एक धागे में अच्छी तरह से काम करता था, लेकिन ओपनएमपी का उपयोग करते समय यह बस त्रुटि में चला जाता है, क्योंकि मैक ओएस एक्स बहुत सीमित stack size for non-main threads है।

-2

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

2

रूट निर्देशिका 100% पर होने पर मुझे बस त्रुटि मिल रही थी।

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