【问题标题】:gdb/ddd Program received signal SIGILLgdb/ddd 程序收到信号 SIGILL
【发布时间】:2013-02-25 16:29:07
【问题描述】:

我使用 c++ 在 Linux 中编写了一个非常简单的程序,它使用 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 运行我的程序时,调试器不起作用,并且我的程序以某种信号错误退出。

这是错误:

 (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)

然后我尝试在另一个不涉及 cURL 库的简单程序上使用 ddd,并且效果很好!!!

有谁知道为什么会这样,解决办法是什么?在 ddd 运行时,我是否需要以某种方式指向 cURL 库?但是,在过去,我不记得用不同的库做这个!也许这是 ddd 不喜欢的 cURL ?但是程序在没有调试器的情况下运行良好!我将不胜感激。

【问题讨论】:

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


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:
     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 上看到它们的原因是,在 Intel 的 IA-32 上,cpuid 指令是非特权指令。任何程序都可以执行cpuid来检测cpu特性,所以不需要基于SIGILL的特性程序。

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

    OpenSSL 最近在某些 Apple 平台上更改为 SIGILL-free 功能检测,因为 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

    【讨论】:

      【解决方案3】:

      对于 Android 开发人员,您可以在 Android Studio 中禁用 SIGILLhttps://developer.oculus.com/documentation/native/android/mobile-studio-debug/#troubleshooting

      【讨论】:

        猜你喜欢
        • 2017-08-08
        • 1970-01-01
        • 2013-08-26
        • 1970-01-01
        • 2011-05-28
        • 1970-01-01
        • 1970-01-01
        • 2013-08-09
        • 2014-12-05
        相关资源
        最近更新 更多