2013-02-25 52 views
5

我在Linux中使用C++編寫了一個非常簡單的程序,該程序使用cURL庫從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; 
} 

我驗證了代碼,它工作正常。我可以看到圖像已下載,並且可以查看圖像(沒有錯誤或警告)。由於我打算擴展我的代碼,我試圖安裝ddd,並使用調試器,但調試器不起作用,並且當我嘗試使用ddd運行我的程序時,程序退出時出現某種信號錯誤。

這是錯誤:

(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,但我得到確切同樣的錯誤,當我運行該程序。 (我相信我使用的是最新版本的gdb和ddd)

然後我嘗試在另一個簡單的程序上使用ddd,它不涉及cURL庫,它運行良好!

有誰知道爲什麼會出現這種情況,解決方案是什麼?當ddd運行時,我是否需要指向cURL庫?但是,在過去,我不記得使用不同的庫來做這件事!也許這是ddd不喜歡的cURL的東西嗎?但是程序運行良好,沒有調試器!我希望得到一些幫助。

+1

只是說:我來到這裏時發生了同樣的錯誤。我的解決方案是恢復到'gdb 7.6.1'(來自gdb7.7)。 – Sebastian 2014-02-12 11:27:51

+0

謝謝你塞巴斯蒂安! – Mike 2015-06-09 11:17:15

+0

[SSL \ _library \ _init在gdb下運行時導致SIGILL可能重複](https://stackoverflow.com/questions/25708907/ssl-library-init-cause-sigill-when-running-under-gdb) – jww 2017-08-12 17:45:37

回答

13

我猜測它可能是某些指令集檢測代碼的一部分。讓程序繼續,看看它是否自己處理信號(因爲它運行在gdb以外,它可能會)。或者,在運行該程序之前,可以告訴gdb不要使用SIGILL來打擾您:handle SIGILL pass nostop noprint

這只是一個問題,如果程序死亡,這是不明確的問題。

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是OpenSSL的加密庫。 OpenSSL通過執行指令來查看它是否可用,從而執行cpu功能探測。如果生成了SIGILL,則該功能是而不是可用,而是使用相應的功能。

您在ARM上看到它們而不是IA-32的原因是,在Intel IA-32上,cpuid指令是非特權的。任何程序都可以執行cpuid來檢測cpu功能,因此不需要基於SIGILL的功能程序。

與IA-32相比,ARM等效的cpuid是一條特權指令。你的程序需要異常等級1(EL-1),但你的程序在EL-0運行。爲了支持對ARM程序的權限設置a jmpbuf並安裝SIGILL處理程序。然後他們嘗試有問題​​的指令,並且處理程序指示指令或功能是否可用。

OpenSSL最近更改爲SIGILL - 某些Apple平臺上的免費功能檢測,因爲Apple損壞了某些東西。另見PR 3108, SIGILL-free processor capabilities detection on MacOS X。其他圖書館也在做類似的事另請參閱How to determine ARMv8 features at runtime?

OpenSSL還在其FAQ中記錄了SIGILL行爲。有關更多詳細信息,請參閱OpenSSL FAQ中的第17項:When debugging I observe SIGILL during OpenSSL initialization: why?另請參閱堆棧溢出的SSL_library_init cause SIGILL when running under gdb

相關問題