2011-09-11 2 views
11

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

मैं कैसे इस तरह के segfaults (कम से कम डीबगिंग के लिए) के रूप में अप्रत्याशित अपवाद के साथ ही मार संकेतों ताकि मैं किसी भी कनेक्शन को बंद करने और किसी भी धागे चलना बंद कर देते हैं, जिससे कि प्रक्रिया कुछ भी की गड़बड़ी नहीं छोड़ता यह उपयोग कर रहा है संभाल कर ?

+0

जारी रखने के लिए जारी रखें, साफ करने के लिए भी, विभाजन खंड के बाद खतरनाक हो सकता है। – icktoofay

+0

'मैन सिग्नेक्शन' –

+1

यह भी ध्यान रखें कि आप हत्या संकेतों को पकड़ नहीं सकते हैं। – Gabe

उत्तर

7

आप संकेतों को पकड़ने के लिए सिग्नल हैंडलर इंस्टॉल करते हैं - हालांकि 99% मामलों में आप बस बाहर निकलना चाहते हैं और लिनक्स ओएस को क्लीनअप का ख्याल रखना है - यह खुशी से सभी फाइलों, सॉकेट, मुफ्त मेमोरी और शटडाउन थ्रेड को बंद कर देगा ।

तो जब तक कि कुछ भी विशेष रूप से आप करना चाहते हैं, जैसे सॉकेट पर संदेश भेजना, तो आपको प्रक्रिया से बाहर निकलना चाहिए और सिग्नल को पकड़ने की कोशिश नहीं करना चाहिए।

+0

मुझे लगता है कि आप यहां हैं ... मेरे मामले में एप्लिकेशन विश्वसनीयता अधिक महत्वपूर्ण है और पागल सामान कर रही है संकेतों के साथ बुरा हो सकता है। जब एक सीगफॉल्ट होता है, अगर मुझे कॉर्डम्प्स मिलते हैं, तो क्या यह आपको बताता है कि सेगफॉल्ट कहाँ हुआ? – user623879

+0

कॉलिंग स्टैक बताता है कि आप सीजी-गलती हुई थी, मानते हुए कि कॉलिंग स्टैक दूषित नहीं हुआ - यह प्रश्न यहां: http://stackoverflow.com/questions/105659/how-can-one-grab-a- स्टैक-ट्रेस-इन-सी स्टैक ट्रेस – Soren

+0

ग्रेट सलाह कैसे प्राप्त करें इस बारे में वार्ता। इस नियम का अपवाद तब होता है जब किसी प्रोग्राम को शट डाउन करते समय हार्डवेयर को साफ या बदलने की आवश्यकता होती है (एम्बिडेड सिस्टम में)। – Havok

6

मैं कभी कभी SIGSEGV पर एक पश्व-अनुरेखन प्राप्त करना चाहते, पकड़ने हिस्सा प्रकार है:

#include <stdio.h> 
#include <stdlib.h> 
#include <signal.h> 

void sig_handler(int); 

int main() { 
    signal(SIGSEGV, sig_handler); 
    int *p = NULL; 
    return *p; 
} 

void sig_handler(int sig) { 
    switch (sig) { 
    case SIGSEGV: 
     fprintf(stderr, "give out a backtrace or something...\n"); 
     abort(); 
    default: 
     fprintf(stderr, "wasn't expecting that!\n"); 
     abort(); 
    } 
} 

आप इन बातों से निपटने में बहुत सावधान है, उदा बनना चाहते हो सुनिश्चित करें कि आप एक और सिग्नल ट्रिगर नहीं कर सकते हैं।

+1

क्या कोर डंप प्राप्त करने के लिए 'ulimit' का उपयोग करना आसान नहीं है और इस तरह से स्टैक ट्रेस प्राप्त करना आसान है? –

+0

उस दृष्टिकोण से परिचित नहीं है, क्या आप विस्तृत कर सकते हैं? मैं केवल डीटीगिंग बीटीडब्ल्यू के लिए इस सामान का उपयोग करता हूं, यानी मैं एक त्रुटि करता हूं और देखना चाहता हूं कि सिग्नल सीधे कहाँ से आया था। – daniel

+2

आपको वास्तव में 'सिग्नल' का उपयोग नहीं करना चाहिए। सालों से ऐसा करने की सिफारिश की गई है कि ऐसा न करें और इसके बजाय 'सिग्नेक्शन' का उपयोग करें। 'मैन सिग्नल' से: * सिग्नल() का व्यवहार यूनिक्स संस्करणों में भिन्न होता है, और यह भी लिनक्स के विभिन्न संस्करणों में ऐतिहासिक रूप से भिन्न होता है। इसके उपयोग से बचें: इसके बजाय सिग्नेक्शन (2) का उपयोग करें। *। मैं नीचे नहीं आ रहा हूं ... लेकिन यह करीब है। आपको इसे इस्तेमाल करने के लिए किसी को भी सिफारिश नहीं करनी चाहिए। –

10

पकड़ने के संकेत कठिन हैं। आपको ध्यान रखना होगा। वांछित सिग्नल के लिए सिग्नल हैंडलर स्थापित करने के लिए आपका पहला चरण sigaction का उपयोग करना है।

  • संकेतों के एक सेट चुनें का जवाब और क्या वे अपनी प्रक्रिया के लिए मतलब है। उदाहरण के लिए, SIGTERM इस्तीफा, SIGHUP पुनरारंभ, SIGUSR1 पुनः लोड विन्यास, आदि के लिए

  • सभी संकेतों का जवाब की कोशिश मत करो और "साफ" करने के लिए संकेत है कि अपने कार्यक्रम में एक त्रुटि दर्शाता है के बाद की कोशिश नहीं करते। SIGKILL पकड़ा नहीं जा सकता है। SIGSEGV, SIGBUS, और उनके जैसे अन्य लोगों को तब तक पकड़ा नहीं जाना चाहिए जब तक आपके पास बहुत अच्छा कारण न हो। यदि आप डीबग करना चाहते हैं, तो कोर डंप के लिए उलिमिट बढ़ाएं - कोर छवि में डीबगर संलग्न करना किसी भी चीज से कहीं अधिक प्रभावी है या मैं कभी भी कोड अप कर सकता हूं। (यदि आप एक SIGSEGV या ऐसा ही कुछ करने के बाद साफ करने के लिए कोशिश करते हैं, तो पता चलता है कि सफाई कोड के कारण हो सकता है एक अतिरिक्त SIGSEGV और चीजों को जल्दी से बुरा हो सकता है। बस पूरे गंदगी से बचने और SIGSEGV अपने कार्यक्रम को समाप्त करते हैं।)

  • आप सिग्नल को कैसे संभालें मुश्किल है। यदि आपके एप्लिकेशन में मुख्य लूप है (उदा।, select या poll) तो सिग्नल हैंडलर मुख्य लूप को छोड़ने के लिए सिग्नल करने के लिए केवल एक ध्वज सेट कर सकता है या एक विशेष पाइप पर बाइट लिख सकता है। सिग्नल हैंडलर से बाहर निकलने के लिए आप siglongjmp का भी उपयोग कर सकते हैं, लेकिन यह सही है और आमतौर पर जो भी आप चाहते हैं उसे प्राप्त करना बहुत मुश्किल है।

यह जानने के बिना कुछ सुझाव देना मुश्किल है कि आपका एप्लिकेशन किस प्रकार संरचित है और यह क्या करता है।

यह भी याद रखें कि सिग्नल हैंडलर को लगभग कुछ भी नहीं करना चाहिए। सिग्नल हैंडलर से कॉल करने के लिए कई फ़ंक्शन सुरक्षित नहीं हैं।