2013-02-25 69 views
5

मैंने लिनक्स में सी ++ का उपयोग करके एक बहुत ही सरल प्रोग्राम लिखा, जो कर्ल पुस्तकालयों का उपयोग करते हुए http (मूल रूप से एक http क्लाइंट अनुरोध विकसित) पर कुछ वेबसाइटों से छवियों को डाउनलोड करता है। http://curl.haxx.se/libcurl/c/allfuncs.htmlgdb/ddd प्रोग्राम प्राप्त सिग्नल SIGILL

#define CURL_STATICLIB 
#include <stdio.h> 
#include <stdlib.h> 
#include </usr/include/curl/curl.h> 
#include </usr/include/curl/stdcheaders.h> 
#include </usr/include/curl/easy.h> 

size_t write_data(void *ptr, size_t size, size_t nmemb, FILE *stream) { 
    size_t written = fwrite(ptr, size, nmemb, stream); 
    return written; 
} 

int main(void) { 
    CURL *curl; 
    FILE *fp; 
    CURLcode res; 

    char *url = "http://www.example.com/test_img.png"; 
    char outfilename[FILENAME_MAX] = "/home/c++_proj/output/web_req_img.png"; 
    curl = curl_easy_init(); 
    if (curl) { 
     fp = fopen(outfilename,"wb"); 
     curl_easy_setopt(curl, CURLOPT_URL, url); 
     curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data); 
     curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp); 
     res = curl_easy_perform(curl); 
     /* always cleanup */ 
     curl_easy_cleanup(curl); 
     fclose(fp); 
    } 
    return 0; 
} 

मैंने कोड सत्यापित किया, और यह ठीक काम करता है। मैं देख सकता हूं कि छवि डाउनलोड की गई है और मैं छवि को देख सकता हूं (बिना किसी त्रुटि या चेतावनियों के)। चूंकि मैं अपने कोड का विस्तार करने की योजना बना रहा हूं, इसलिए मैंने डीडीडी स्थापित करने की कोशिश की, और डीबगर का उपयोग किया, लेकिन डीबगर काम नहीं करता है, और मेरा प्रोग्राम किसी प्रकार की सिग्नल त्रुटियों से निकलता है, जब मैं अपने प्रोग्राम को डीडीडी के साथ चलाने की कोशिश करता हूं।

यह त्रुटि है:

(Threadd debugging using libthread_db enabled) 
Using host libthread_db library "/lib/arm-linux-gnueadihf/libthread_db.so.1" 

Program received signal SIGILL, illegal instruction. 
0xb6a5c4C0 in ??() from /usr/lib/arm-linux-gnueadbihf/libcrypto.so.1.0.0 

सबसे पहले मैंने सोचा था कि मैं ठीक से ddd स्थापित नहीं किया है, इसलिए मैं वापस gdb के लिए गया था, लेकिन मैं ठीक उसी त्रुटियों मिलता है, जब मैं इस कार्यक्रम चलाते हैं। (और मेरा मानना ​​है कि मैं जीडीबी और डीडीडी के नवीनतम संस्करण का उपयोग कर रहा हूं)

फिर मैंने एक और सरल कार्यक्रम पर डीडीडी का उपयोग करने की कोशिश की, जिसमें कर्ल लाइब्रेरी शामिल नहीं है, और यह ठीक काम करता है !!!

क्या कोई जानता है कि यह मामला क्यों है, और समाधान क्या है? क्या मुझे किसी भी तरह से ddd चल रहा है, जबकि curl पुस्तकालयों को इंगित करने की जरूरत है? लेकिन, अतीत में, मुझे पुस्तकालयों के विभिन्न सेट के साथ ऐसा करने की याद नहीं है! हो सकता है कि यह कुछ ऐसा कर्ल है जो ddd पसंद नहीं करता है? लेकिन कार्यक्रम डीबगर के बिना खुद को ठीक चलाता है! मैं कुछ मदद की सराहना करता हूं।

+1

बस कह रहा है: मैं यहां एक ही त्रुटि के साथ आया था। मेरा समाधान 'gdb 7.6.1' (gdb7.7 से) पर वापस जाना था। – Sebastian

+0

धन्यवाद सेबेस्टियन! – Mike

+0

जीएसबी के तहत चलते समय [एसएसएल \ _library \ _init कारण सिगिल का संभावित डुप्लिकेट] (https://stackoverflow.com/questions/25708907/ssl-library-init-cause-sigill-when-running-under-gdb) – jww

उत्तर

13

मुझे लगता है कि यह कुछ निर्देश सेट पहचान कोड का हिस्सा हो सकता है। बस कार्यक्रम जारी रखें और देखें कि क्या यह सिग्नल स्वयं ही संभालता है (क्योंकि यह gdb के बाहर चलाता है, यह शायद करता है)। वैकल्पिक रूप से, आप प्रोग्राम चलाने से पहले पर सिगिल के साथ परेशान न करने के लिए gdb बता सकते हैं।

यह केवल एक समस्या है यदि प्रोग्राम मर जाता है, जो आपके प्रश्न से स्पष्ट नहीं था।

1
Program received signal SIGILL, illegal instruction. 
0xb6a5c4C0 in ??() from /usr/lib/arm-linux-gnueadbihf/libcrypto.so.1.0.0 

Does anyone know why this is the case, and what is the solution?

जेस्टर ने आपको समाधान दिया। यही कारण है कि ऐसा क्यों होता है।

libcrypto.so ओपनएसएसएल की क्रिप्टो लाइब्रेरी है। ओपनएसएसएल यह देखने के लिए कि क्या यह उपलब्ध है, एक निर्देश निष्पादित करके सीपीयू फीचर जांच करता है। यदि SIGILL उत्पन्न होता है, तो सुविधा उपलब्ध नहीं है और इसके बजाय उचित फ़ंक्शन का उपयोग किया जाता है।

कारण आप उन्हें एआरएम पर देखते हैं और आईए -32 नहीं, इंटेल के आईए -32 पर cpuid निर्देश गैर-विशेषाधिकार प्राप्त है। कोई भी प्रोग्राम cpu सुविधाओं का पता लगाने के लिए cpuid निष्पादित कर सकता है, इसलिए SIGILL-आधारित सुविधा प्रोग्राम की आवश्यकता नहीं है।

आईए -32 के विपरीत, एआरएम cpuid के बराबर एक विशेषाधिकार प्राप्त निर्देश है। आपके कार्यक्रम को अपवाद स्तर 1 (ईएल -1) की आवश्यकता है, लेकिन आपका प्रोग्राम ईएल -0 पर चलता है। एआरएम कार्यक्रमों पर विशेषाधिकारों की आवश्यकता को आगे बढ़ाने के लिए jmpbuf सेट करें और SIGILL हैंडलर स्थापित करें। फिर वे प्रश्न में निर्देश का प्रयास करते हैं और SIGILL हैंडलर इंगित करता है कि निर्देश या सुविधा उपलब्ध है या नहीं।

ओपनएसएसएल हाल ही में SIGILL में बदल गया - कुछ ऐप्पल प्लेटफार्मों पर मुफ्त फीचर डिटेक्शन क्योंकि ऐप्पल चीजों को दूषित करता है। PR 3108, SIGILL-free processor capabilities detection on MacOS X भी देखें। अन्य पुस्तकालय समान कर रहे हैं।How to determine ARMv8 features at runtime?

ओपनएसएसएल अपने एफएक्यू में SIGILL व्यवहार भी दस्तावेज करता है। अधिक जानकारी के लिए ओपनएसएसएल एफएक्यू में आइटम 17 देखें: When debugging I observe SIGILL during OpenSSL initialization: why? स्टैक ओवरफ़्लो पर SSL_library_init cause SIGILL when running under gdb भी देखें।