2013-02-25 13 views
5

私は、cURLライブラリを使用して、http(基本的にhttpクライアント要求を開発した)を介していくつかのウェブサイトから画像をダウンロードする、C++を使用してLinuxで非常に簡単なプログラムを書いた。 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 

まず私は、プログラムを実行するときに、私は戻ってGDBに行ってきましたが、私は正確に同じエラーを取得し、私は適切にDDDをインストールしていないと思いました。 (そして私はgdbとdddの最新バージョンを使用していると信じています)

次に、別の簡単なプログラムでdddを使用しようとしましたが、cURLライブラリは関係ありません。

誰にこのような理由が分かっていて、解決策は何ですか? dddの実行中に何とかcURLライブラリを指す必要がありますか?しかし、これまではさまざまなライブラリを使ってこのことを思い出していません。たぶん、dddが好きではないcURLを何かabuotしているのでしょうか?しかし、プログラムはデバッガなしでは正常に動作します!私はいくつかの助けに感謝します。

+1

私はここに同じエラーで来ました。私の解決策は 'gdb 7.6.1'(gdb7.7から)に戻すことでした。 – Sebastian

+0

セバスチャンありがとう! – Mike

+0

可能性のある重複した[SSL \ _library \ _init原因SIGILL GDBの下で実行](https://stackoverflow.com/questions/25708907/ssl-library-init-cause-sigill-when-running-under-gdb) – jww

答えて

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?

Jesterさんに解決策を教えてください。それが起こる理由はここにあります。

libcrypto.soは、OpenSSLの暗号ライブラリです。 OpenSSLは、使用可能かどうかを調べる命令を実行することによって、CPU機能プローブを実行します。 SIGILLが生成された場合、その機能はではなく、であり、代わりに適切な関数が使用されます。

IntelのIA-32では、ARMで表示される理由は、cpuid命令は特権がありません。どんなプログラムでもcpuidを実行してCPU機能を検出できるので、SIGILLベースの機能プログラムは必要ありません。

IA-32とは対照的に、cpuidのARMは、特権命令です。プログラムに例外レベル1(EL-1)が必要ですが、プログラムはEL-0で実行されます。サイドステップを実行するには、ARMプログラムの特権が必要です。jmpbufをセットアップし、SIGILLハンドラをインストールします。次に、問題の命令を試し、SIGILLハンドラは、命令または機能が使用可能かどうかを示します。

OpenSSLはAppleが一部のAppleプラットフォームでフリーの機能を検出したため、最近ではSIGILLに変更されました。また、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も参照してください。

関連する問題