2013-02-25 102 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

相关问题