2010-01-18 13 views
10

पर सिगबस डीबगिंग लिनक्स में जेनेरिक x86 उपयोगकर्तालैंड एप्लिकेशन पर सिगबस (बस त्रुटि) का कारण क्या हो सकता है? ऑनलाइन चर्चा करने में मेरी सारी चर्चा मेमोरी संरेखण त्रुटियों के संबंध में है, जो मैं समझता हूं कि वास्तव में x86 पर लागू नहीं होता है।x86 लिनक्स

(मेरे कोड एक Geode पर चल रहा है, मामले में किसी भी प्रासंगिक प्रोसेसर विशेष quirks देखते हैं।)

उत्तर

13

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

आपकी सबसे अच्छी शर्त दोषपूर्ण निर्देश (सिगबस सिंक्रोनस) की पहचान करने के लिए डीबगर का उपयोग कर रही है, और यह देखने की कोशिश कर रही है कि वह क्या करने का प्रयास कर रहा था।

+1

डीबगर ने दिखाया कि SIGBUS फ़ंक्शन में प्रवेश करने के तुरंत बाद हुआ था। हो सकता है कि मेरे पास कुछ स्मृति भ्रष्टाचार हो, या शायद फ़ंक्शन पैरामीटर में से एक खराब है? अगर त्रुटि फिर से होती है तो मुझे अधिक जानकारी के लिए डिबगर में डिस्सेप्लर की जांच करनी होगी। –

+1

@ जोश - यह देखने के लिए जांचें कि वास्तविक असफल निर्देश क्या है - यदि यह पुश या पॉप है, तो आपका स्टैक पॉइंटर दूषित हो गया है। अगर यह कुछ और है, तो निर्देश में पता मुद्दा है। –

0

86 लिनक्स पर एक बस त्रुटि का एक आम कारण भिन्नता कुछ है कि वास्तव में एक नहीं है करने के लिए प्रयास कर रहा है सूचक, या एक जंगली सूचक है। उदाहरण के लिए, पॉइंटर को प्रारंभ करने में विफल रहता है, या पॉइंटर के लिए मनमाने ढंग से पूर्णांक असाइन करना और फिर dereference करने का प्रयास करना आम तौर पर एक सेगमेंटेशन गलती या बस त्रुटि उत्पन्न करेगा।

संरेखण x86 पर लागू होता है। भले ही x86 पर स्मृति बाइट-एड्रेसेबल है (इसलिए आपके पास किसी भी पते पर चार पॉइंटर हो सकता है), यदि आपके पास उदाहरण के लिए 4-बाइट पूर्णांक के लिए पॉइंटर है, तो पॉइंटर को गठबंधन किया जाना चाहिए।

आपको अपना प्रोग्राम जीडीबी में चलाया जाना चाहिए और यह निर्धारित करना चाहिए कि समस्या का निदान करने के लिए कौन सी सूचक पहुंच बस त्रुटि उत्पन्न कर रही है।

+4

पूर्णांक की अनलिखित पहुंच x86 पर काम करती है। – Joshua

+5

एसएसई निर्देशों के लिए नहीं –

+3

सभी एसएसई लोड/स्टोर निर्देशों को गठबंधन और असाइन किए गए संस्करण हैं। एसएसई (128-बिट) एक्सेस के लिए, वे वास्तव में समकालीन इंटेल आर्किटेक्चर पर पूर्ण गति से चलते हैं, इसलिए अनौपचारिक चालों को बिना शर्त के उपयोग करने के लिए कोई वास्तविक जुर्माना नहीं है (जब तक कि आप उस स्तर तक ऑप्टिमाइज़ नहीं कर रहे हैं कि गठबंधन चाल निर्देशों की छोटी लंबाई है महत्वपूर्ण, जो असंभव है)। –

15

SIGBUS मेमोरी संरेखण दोषों के अलावा कुछ कारणों से लिनक्स में हो सकता है - उदाहरण के लिए, यदि आप मैप किए गए फ़ाइल के अंत से mmap क्षेत्र तक पहुंचने का प्रयास करते हैं।

क्या आप mmap, साझा स्मृति क्षेत्र या इसी तरह के कुछ भी उपयोग कर रहे हैं?

+2

हां, हम साझा स्मृति क्षेत्रों का उपयोग कर रहे हैं। अगली बार जब यह त्रुटि आती है तो मैं उस संभावना की जांच करूंगा। धन्यवाद। –

+0

एमएमएपी का उपयोग किसी भी कार्यक्रम द्वारा मॉलोक को कॉल करने के लिए किया जाता है, क्योंकि आज मॉलोक एमएमएपी के लिए आगे है। –

+0

@ v.oddou: यह अज्ञात mmap है, जिसमें "मैप किए गए फ़ाइल के अंत से परे" की अवधारणा नहीं है। – caf

3

ओह हाँ सिगबस पाने का एक और अजीब तरीका है।

यदि कर्नेल मेमोरी प्रेशर (ओओएम किलर अक्षम होना चाहिए) के कारण कोड पेज में पेज में विफल रहता है या आईओ अनुरोध, सिगबस विफल रहा है।

0

यह पीटा पथ से थोड़ी दूर है, लेकिन आप सिग्बस को एक असाइन किए गए एसएसई 2 (एम 128) लोड से प्राप्त कर सकते हैं।

+2

क्या आप कर सकते हैं? यह आमतौर पर #GP में परिणाम देता है, जो SIGSEGV को मानचित्र करता है। – Ruslan

+1

मुझे माफ़ कर दो, तुम सही हो। – Mischa

6

x86 पर सिगबस (x86_64 सहित) लिनक्स एक दुर्लभ जानवर है। यह mmap एड फ़ाइल, या POSIX द्वारा वर्णित कुछ अन्य स्थितियों के अंत तक पहुंचने के प्रयास से दिखाई दे सकता है।

लेकिन हार्डवेयर दोषों से सिगबस प्राप्त करना आसान नहीं है। अर्थात्, किसी भी निर्देश से अनचाहे पहुंच - चाहे वह सिम हो या नहीं - आमतौर पर SIGSEGV में परिणाम होता है। एसआईजीएसईजीवी में स्टैक ओवरफ्लो परिणाम। एसआईजीएसईजीवी में कैनोलिक फॉर्म नतीजे में न होने वाले पते तक पहुंच भी है। यह सब #GP के कारण उठाया जा रहा है, जो लगभग हमेशा SIGSEGV को मानचित्र करता है।

अब, here're कुछ मायनों SIGBUS पाने के लिए एक सीपीयू अपवाद के कारण:

  1. EFLAGS में एसी बिट सक्षम है, तो पढ़ने के लिए या अनुदेश लिखने किसी भी स्मृति द्वारा असंरेखित पहुंच है। विवरण के लिए this discussion देखें।

  2. स्टैक पॉइंटर रजिस्टर (rsp या rbp) के माध्यम से कैनोलिक उल्लंघन करें, #SS उत्पन्न करना।यहाँ जीसीसी के लिए एक उदाहरण (gcc test.c -o test -masm=intel साथ संकलन) है:

 
int main() 
{ 
    __asm__("mov rbp,0x400000000000000\n" 
      "mov rax,[rbp]\n" 
      "ud2\n"); 
} 
1

यह संक्षिप्त था के रूप में एक "IO अनुरोध विफल" ऊपर उल्लेख किया है, लेकिन मैं इस पर थोड़ा विस्तार करेंगे।

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

यदि आपको इस त्रुटि से सही ढंग से पुनर्प्राप्त करने के लिए अपने आवेदन की आवश्यकता है, तो यह फॉलोकोक का उपयोग करके एमएमएपी से पहले अंतरिक्ष को स्पष्ट रूप से आरक्षित करने का अर्थ है। फॉलोकोक कॉल के बाद इरनो में ईएनओएसपीसी को संभालना सिग्नल से निपटने से बहुत आसान है, खासकर बहु-थ्रेडेड एप्लिकेशन में।