我在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(
然后我尝试在另一个不涉及cURL库的简单程序上使用ddd,它运行得很好!!!
有人知道为什么会这样吗?解决方案是什么?ddd运行时,我是否需要以某种方式指向cURL库?但是,在过去,我不记得用不同的库做过这件事!也许是cURL上的某些内容让ddd不喜欢?但是程序在没有调试器的情况下运行良好!我很感激你的帮助。
我猜它可能是某些指令集检测代码的一部分。只需让程序继续,看看它是否自己处理信号(因为它在gdb
之外运行,所以它可能会处理(。或者,在运行程序handle SIGILL pass nostop noprint
之前,您可以告诉gdb
不要用SIGILL来打扰您。
这只是一个问题,如果程序死了,这从你的问题中是不清楚的。
Program received signal SIGILL, illegal instruction. 0xb6a5c4C0 in ?? () from /usr/lib/arm-linux-gnueadbihf/libcrypto.so.1.0.0
有人知道为什么会这样吗?解决方案是什么?
杰斯特给了你解决方案。以下是发生这种情况的原因。
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
免费功能检测,因为苹果会破坏东西。另请参阅PR 3108,MacOS X上的SIGILL免费处理器功能检测。其他库也在做类似的工作。另请参阅如何在运行时确定ARMv8功能?
OpenSSL还在其常见问题解答中记录了SIGILL
的行为。有关更多详细信息,请参阅OpenSSL常见问题解答中的第17项:调试时,我在OpenSSL初始化期间观察到SIGILL:为什么?另请参阅SSL_library_init在堆栈溢出上的gdb下运行时导致SIGILL。
对于Android开发人员,您可以在Android Studio中禁用SIGILL
:https://developer.oculus.com/documentation/native/android/mobile-studio-debug/#troubleshooting