किसी प्रक्रिया को SIGABRT (सिग्नल 6) कब मिलता है?


202

ऐसे परिदृश्य क्या हैं जहां एक प्रक्रिया को C ++ में SIGABRT मिलता है? क्या यह संकेत हमेशा प्रक्रिया के भीतर से आता है या यह संकेत एक प्रक्रिया से दूसरी प्रक्रिया में भेजा जा सकता है?

क्या यह पहचानने का कोई तरीका है कि कौन सी प्रक्रिया यह संकेत भेज रही है?


3
कुछ तरीके हैं। सबसे आसान तरीका है, अगर आपने प्रोग्राम लिखा है, तो SIGABRT के लिए एक सिग्नल हैंडलर को पंजीकृत करना है जो उस जानकारी को प्रिंट करता है और लौटने से पहले इसकी धाराओं को फ्लश करता है। दूसरा सबसे आसान तरीका स्ट्रीम्स के भीतर प्रोग्राम को चलाना है। तीसरा सबसे आसान तरीका यह सुनिश्चित करना है कि प्रोग्राम क्रैश होने पर एक कोर फ़ाइल बनाता है, और कोर डंप के माध्यम से पता लगाता है।
पार्थियन शॉट

जवाबों:


195

abort()कॉलिंग प्रक्रिया को SIGABRTसिग्नल भेजता है , यह abort()मूल रूप से काम करता है।

abort()आमतौर पर लाइब्रेरी फ़ंक्शंस द्वारा बुलाया जाता है जो आंतरिक त्रुटि या कुछ गंभीर रूप से टूटी हुई बाधा का पता लगाता है। उदाहरण के लिए malloc(), abort()यदि इसकी आंतरिक संरचनाएं ढेर अतिप्रवाह से क्षतिग्रस्त हैं, तो कॉल करेगा ।


27
मेरे लिए ज्यादातर मामलों में libcfree()
SIGABRT

अगर मेरे पास कोड में कहीं है, तो कंस्ट्रक्टर के भीतर से शुद्ध वर्चुअल फंक्शन कॉल को दफन कर दिया जाए, तो क्या यह भी SIGABTT सिग्नल के साथ समाप्त हो सकता है? मैं पूछ रहा हूं क्योंकि मुझे एक त्रुटि दिखाई दे रही है कि मेरे पास एक शुद्ध वर्चुअल कॉल है, और अगली पंक्ति मुझे एक SIGABRT संदेश देती है और एप्लिकेशन या तो क्रैश हो जाता है या ऑपरेटिंग सिस्टम द्वारा बंद कर दिया जाता है। धन्यवाद।
हरविज

2
MacOS पर, हमें SIGABRT को बिना बंद किए लगभग 1000 फ़ाइल हैंडल खोलने के लिए मिला। मॉकिंग के बजाय, हमारे परीक्षणों ने फ़ाइल को अधिक सामान्य पाठक प्रकार के साथ सार कर दिया, जिसमें कोई Close()विधि नहीं है, इसलिए इसे भूल गया था। हालांकि महान कवरेज था। : रोली:
Zyl

51

SIGABRTआमतौर पर libc और अन्य पुस्तकालयों द्वारा महत्वपूर्ण त्रुटियों के मामले में कार्यक्रम को निरस्त करने के लिए उपयोग किया जाता है। उदाहरण के लिए, ग्लिबेक SIGABRTएक पता लगाए गए डबल-फ्री या अन्य ढेर भ्रष्टाचार के मामले में भेजता है ।

इसके अलावा, अधिकांश assertकार्यान्वयन SIGABRTएक असफल दावे के मामले में उपयोग करते हैं।

इसके अलावा, SIGABRTकिसी भी अन्य प्रक्रिया से किसी अन्य सिग्नल की तरह भेजा जा सकता है। बेशक, भेजने की प्रक्रिया को समान उपयोगकर्ता या रूट के रूप में चलाने की आवश्यकता है।


49

आप kill(2)इंटरफ़ेस का उपयोग करके किसी भी प्रक्रिया को कोई भी संकेत भेज सकते हैं :

kill -SIGABRT 30823

30823 एक ऐसी dashप्रक्रिया थी जिसे मैंने शुरू किया था, इसलिए मैं आसानी से उस प्रक्रिया को पा सकता था जिसे मैं मारना चाहता था।

$ /bin/dash
$ Aborted

Abortedउत्पादन जाहिरा तौर पर कैसे है dashएक SIGABRT रिपोर्ट।

यह उपयोग कर किसी भी प्रक्रिया के लिए सीधे भेजा जा सकता kill(2)है, या एक प्रक्रिया ही करने के लिए संकेत भेज सकते हैं के माध्यम से assert(3), abort(3)याraise(3)


17

यह आमतौर पर तब होता है जब मेमोरी आवंटन में कोई समस्या होती है।

यह मेरे साथ तब हुआ जब मेरा कार्यक्रम नकारात्मक आकार के साथ एक सरणी आवंटित करने का प्रयास कर रहा था।


14

C ++ के मामले में एक और सरल कारण है।

std::thread::~thread{
    if((joinable ())
        std::terminate ();
}

यानी थ्रेड का दायरा समाप्त हो गया लेकिन आप कॉल करना भूल गए

thread::join();

या

thread::detach();

7

GNU libc /dev/ttyकॉल करने से पहले कुछ घातक स्थितियों के बारे में जानकारी प्रिंट करेगा abort()(जो तब ट्रिगर करता हैSIGABRT ), लेकिन यदि आप अपने प्रोग्राम को सेवा के रूप में चला रहे हैं या अन्यथा एक वास्तविक टर्मिनल विंडो में नहीं हैं, तो ये संदेश खो सकते हैं, क्योंकि कोई भी नहीं है संदेशों को प्रदर्शित करने के लिए tty।

/ Dev / tty के बजाय stderr पर लिखने के लिए libc को पुनर्निर्देशित करने की मेरी पोस्ट देखें:

Libc त्रुटि संदेशों को पकड़ना, / dev / tty से पुनर्निर्देशित करना


4

एक मामला जब प्रक्रिया स्वयं से SIGABRT प्राप्त करती है: ह्रूवोज़ ने एक दफन शुद्ध आभासी के बारे में उल्लेख किया, जिसे ctor से गर्भपात उत्पन्न करने के लिए कहा जाता है, मैंने इसके लिए एक उदाहरण पुनः बनाया। यहाँ जब d का निर्माण किया जाना है, तो यह पहले अपने बेस क्लास A Ctor को कॉल करता है, और पॉइंटर के अंदर ही पास होता है। A ctor शुद्ध वर्चुअल विधि को टेबल से पहले वैध पॉइंटर से भरता है, क्योंकि d का निर्माण अभी तक नहीं हुआ है।

#include<iostream>
using namespace std;
class A {
public:
 A(A *pa){pa->f();}
 virtual void f()=0;
};
class D : public A {
public:
 D():A(this){}
 virtual void f() {cout<<"D::f\n";}
};
int main(){
 D d;
 A *pa = &d;
 pa->f();
 return 0;
}

संकलन: g ++ -o aa aa.cpp

ulimit -सी असीमित

run ://aa

pure virtual method called
terminate called without an active exception
Aborted (core dumped)

अब कोर फाइल को जल्दी से देखने देता है, और सत्यापित करता है कि SIGABRT वास्तव में कहा गया था:

gdb aa core

देखें:

i r
rdx            0x6      6
rsi            0x69a    1690
rdi            0x69a    1690
rip            0x7feae3170c37

चेक कोड:

disas 0x7feae3170c37

mov    $0xea,%eax  = 234  <- this is the kill syscall, sends signal to process
syscall   <-----

http://blog.rchapman.org/posts/Linux_System_Call_Table_for_x86_64/

234 sys_tgkill pid_t tgid pid_t pid int sig = 6 = SABABTT

:)


2

मेरे मामले में, यह सरणी की लंबाई के बराबर एक सूचकांक में एक इनपुट के कारण था।

string x[5];

for(int i=1; i<=5; i++){

    cin>>x[i];

}

x [5] को एक्सेस किया जा रहा है जो मौजूद नहीं है।


1

जैसा कि "@ सर्नॉल्ड" है, उपयुक्त रूप से कहा गया है, कोई भी प्रक्रिया किसी अन्य प्रक्रिया को संकेत भेज सकती है, इसलिए, एक प्रक्रिया अन्य प्रक्रिया को SIGABORT भेज सकती है और उस स्थिति में प्राप्त करने वाली प्रक्रिया यह भेद करने में असमर्थ है कि क्या इसकी वजह से इसकी स्वयं की जांच हो रही है स्मृति आदि, या किसी और के पास "एकतरफा" है, इसे भेजें।

मैंने जिन प्रणालियों में काम किया उनमें से एक में एक डेडलॉक डिटेक्टर है जो वास्तव में पता लगाता है कि क्या प्रक्रिया किसी कार्य से दिल की धड़कन देकर बाहर आ रही है या नहीं। यदि नहीं, तो यह घोषणा करता है कि प्रक्रिया गतिरोध की स्थिति में है और इसे SIGABORT भेजता है।

मैं सिर्फ इस संभावित सवाल के संदर्भ में साझा करना चाहता था।


0

मैं एक प्रतियोगी प्रोग्रामिंग (cp) से अपना उत्तर दूंगा परिप्रेक्ष्य , लेकिन यह अन्य डोमेन पर भी लागू होता है।

कई बार cp करते समय, अड़चनें काफी होती हैं।

उदाहरण के लिए : मेरे पास एक प्रश्न था, N, M, Qजैसे कि एक चर1 ≤ N, M, Q < 10^5

मैं जो गलती कर रहा था, मुझे उसके आकार 10000 x 10000में 2 डी पूर्णांक सरणी घोषित किया गया C++और उसके साथ संघर्ष किया गयाSIGABRT लगभग 2 दिनों के लिए Codechef में त्रुटि।

अब, यदि हम गणना करते हैं:

पूर्णांक का विशिष्ट आकार: 4 बाइट्स

हमारे सरणी में कोशिकाओं की संख्या: 10000 x 10000

कुल आकार (बाइट्स में): 400000000 बाइट्स = 4 * 10 ^ 8 tes 400 एमबी

ऐसे प्रश्नों के लिए आपके समाधान आपके पीसी पर काम करेंगे (हमेशा नहीं) क्योंकि यह इस आकार को वहन कर सकता है।

लेकिन कोडिंग साइट्स (ऑनलाइन जज) पर संसाधन कुछ केबी तक सीमित हैं।

इसलिए SIGABRT त्रुटि और ऐसी अन्य त्रुटियां।

निष्कर्ष:

इस तरह के सवालों में, हमें किसी सरणी या वेक्टर या इस आकार के किसी अन्य डीएस की घोषणा नहीं करनी चाहिए, लेकिन हमारा कार्य हमारे एल्गोरिथ्म को इतना कुशल बनाना है कि यह उनके (डीएस) या कम मेमोरी के साथ काम करता है।

पुनश्च : इस त्रुटि के अन्य कारण हो सकते हैं; ऊपर उनमें से एक था।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.