2011-03-17 11 views
5

मैं सिग्नल हैंडलर के अंदर कुछ सी ++ फ़ंक्शन कॉल करता हूं और मेरा प्रोग्राम सेगमेंटेशन गलती से समाप्त होता है। जब मैं gdb के साथ जांचता हूं, memcpy() फ़ंक्शन वह है जहां मुझे SIGSEGV मिलता है। मैं जानना चाहता हूं कि memcpy() एक पुनर्वित्त समारोह है या नहीं?क्या memcpy() फ़ंक्शन पुनर्वित्त है?

+0

देखें कि सिग्नल हैंडलर को पॉइंटर मान और लंबाई का उपयोग कहां मिलता है। 'memcpy' सुरक्षित है, लेकिन यदि आप कुछ मुफ्त (somestruct-> डेटा) जैसे कुछ करते हैं; somestruct-> डेटा = 0; somestruct-> लेन = 0; 'तो निश्चित रूप से सिग्नल उस के बीच में हो सकता है। –

उत्तर

1

मुझे नहीं पता कि यह पुनर्विक्रेता क्यों नहीं हो सका। मुझे यकीन नहीं है, लेकिन मुझे लगता है कि आपके द्वारा उपयोग की जाने वाली पुस्तकालयों पर आधारित यह बहुत कुछ है।

11

सबसे अधिक एम्बेडेड प्लेटफ़ॉर्म के अलावा, यह पुनर्विक्रेता होगा। आप SIGSEGV का उल्लेख करते हैं, इसलिए मुझे लगता है कि यह उनमें से एक नहीं है। इस मामले में यह सबसे अधिक संभावना है memcpy() अपराधी नहीं है: यह कॉलर की गलती है। यदि आप खराब पॉइंटर्स (या खराब लंबाई) की प्रतिलिपि बनाने के लिए memcpy() से पूछते हैं तो यह वह होगा जो दोषपूर्ण होगा। आप आसानी से ऐसा कर सकता है:

memcpy(NULL, NULL, 123456789); 

यह एक SIGSEGV कारण होगा और इससे आप memcpy() बता देंगे यह कारण होता है। बेशक, यह memcpy की गलती नहीं है - यह सिर्फ वही कर रहा है जो आपने कहा था। आपका सिग्नल हैंडलर इसे कुछ अजीब के साथ बुला रहा है। कॉलर की साइट पर एक बैकट्रैक (जीडीबी या आपके पास जो भी उपकरण है) को दिखाना चाहिए कि आपने इसे क्या कहा है। उसमें विफल होने के कारण, बस उन तर्कों को प्रिंट करें जिन्हें आप memcpy में गुजर रहे हैं।

+2

पॉज़िक्स का कहना है कि सिग्नल हैंडलर से memcpy नहीं कहा जा सकता है। अभ्यास में, यह काम कर सकता है। ज्यादातर समय, कम से कम। लेकिन यह बिल्कुल गारंटी नहीं है। –

+1

@ जेम्स: यह जांचने का तरीका, मुझे लगता है कि, स्पष्ट लूप के साथ कॉल को 'memcpy' में बदलना होगा और देखें कि segfault अभी भी होता है या नहीं। यदि यह दूर चला जाता है तो 'memcpy' async-signal-safe नहीं था। यदि ऐसा नहीं होता है, तो या तो समस्या कहीं और है कि वास्तविक प्रतिलिपि, या फिर यह 'char' पहुंच के साथ सिग्नल-परमाणु नहीं होने के लिए कुछ सूक्ष्म है। –

+1

@ जेम्स यह बेहद आश्चर्यजनक है।मुझे memcpy() सिग्नल-सुरक्षित नहीं होने का संदर्भ नहीं मिल रहा है (opengroup से भी)। कुछ माइक्रोकंट्रोलर/डीएसपी आर्किटेक्चर पर यह स्थानीय चर के लिए स्थैतिक स्थान होने के कारण पुनर्वित्त नहीं है, लेकिन मैं कल्पना नहीं कर सकता कि आप इसे अन्य आर्किटेक्चर पर असुरक्षित बनाने के लिए कैसे प्रबंधित करेंगे, इसे बनाने के लिए वास्तव में कठिन प्रयास किए बिना। क्या आपके पास एक लिंक है? –

2

के विषय में (गैर) रैत्रांत कार्य करता है और संकेत संचालकों (जहाँ तक GNU सी पुस्तकालय के लिए प्रासंगिक) कुछ प्रासंगिक जानकारी http://www.gnu.org/s/libc/manual/html_node/Nonreentrancy.html#Nonreentrancy में पाया जा सकता:

    :

    इस भाग विशेष रूप से अपने प्रश्न के लिए प्रासंगिक लगती है

  • "मेमोरी ऑब्जेक्ट से केवल पढ़ने से सुरक्षित है बशर्ते कि आप ऑब्जेक्ट में किसी भी मूल्य से निपट सकें, जब सिग्नल डिलीवर किया जा सके। ध्यान रखें कि कुछ डेटा प्रकारों को असाइनमेंट की आवश्यकता होती है एक निर्देश, जिसका अर्थ है कि हैंडलर "के बीच में" चला सकता है चर के लिए ssignment अगर इसका प्रकार परमाणु नहीं है। "

  • "जब तक हैंडलर चल सकता है, किसी भी समय मूल्य में अचानक परिवर्तन के रूप में स्मृति मेमोरी में लिखना सुरक्षित है, तो कुछ भी परेशान नहीं होगा।"

0

memcpy जब तक बुरी तरह से कार्यान्वित किया जाता है, यह रैत्रांत है। यह केवल वही काम करेगा जो आप इसे देते हैं - पॉइंटर्स और लम्बाई मान। सभी पैरामीटर मान द्वारा पारित किए जाते हैं, इसलिए फ़ंक्शन सक्रिय होने के बाद, ये मान सिग्नल और/या अन्य थ्रेड के बावजूद, इसके स्टैक फ्रेम पर नहीं बदले जाएंगे।

0

मुझे लगता है कि समस्या यह है कि आप memcpy फ़ंक्शन के लिए पैरामीटर के रूप में अमान्य (या हटाए गए) पॉइंटर के रूप में उपयोग कर रहे हैं, कृपया अपना कोड सावधानी से जांचें।

सम्मान।

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