gdb / ddd程序收到信号SIGILL

时间:2013-02-25 16:29:08

标签: linux gdb libcurl raspberry-pi ddd-debugger

我在Linux中使用c ++编写了一个非常简单的程序,它使用cURL库从http(基本上开发了一个http客户端请求)下载某些网站的图像。 http://curl.haxx.se/libcurl/c/allfuncs.html

#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运行程序时,我的程序会出现某种Signal错误。

这是错误:

 (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的东西?但是没有调试器,程序运行良好!我将不胜感激。

2 个答案:

答案 0 :(得分:17)

我猜它可能是某些指令集检测代码的一部分。让程序继续,看看它是否自己处理信号(因为它在gdb之外运行,它可能会这样做)。或者,您可以在运行程序之前告诉gdb根本不打扰SIGILL:handle SIGILL pass nostop noprint

如果程序死了,这只是一个问题,而你的问题并不清楚。

答案 1 :(得分:5)

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

有谁知道为什么会这样,解决方案是什么?

Jester给了你解决方案。这就是它发生的原因。

libcrypto.so是OpenSSL的加密库。 OpenSSL通过执行指令来查看它是否可用来执行cpu功能探测。如果生成SIGILL,则该功能可用,而是使用相应的功能。

您在ARM而不是IA-32上看到它们的原因是,在英特尔的IA-32上,cpuid指令是非特权的。任何程序都可以执行cpuid来检测cpu功能,因此不需要基于SIGILL的功能程序。

与IA-32相比,ARM相当于cpuid是一种特权指令。您的程序需要异常级别1(EL-1),但您的程序运行在EL-0。为了支持对ARM程序的特权需求,设置jmpbuf并安装SIGILL处理程序。然后他们尝试有问题​​的指令,SIGILL处理程序指示指令或功能是否可用。

OpenSSL最近更改为SIGILL - 某些Apple平台上的免费功能检测,因为Apple腐败了。另请参阅PR 3108, SIGILL-free processor capabilities detection on MacOS X。其他图书馆做的很相似。另请参阅How to determine ARMv8 features at runtime?

OpenSSL还会在其常见问题解答中记录SIGILL行为。有关详细信息,请参阅OpenSSL常见问题解答中的第17项:When debugging I observe SIGILL during OpenSSL initialization: why?另请参阅Stack Overflow上的SSL_library_init cause SIGILL when running under gdb