2013-02-25 17 views
5

Ho scritto un programma molto semplice in Linux usando C++, che scarica le immagini da qualche sito web su http (fondamentalmente sviluppato una richiesta client http), usando le librerie cURL. http://curl.haxx.se/libcurl/c/allfuncs.htmlgdb/ddd Programma ricevuto segnale 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; 
} 

Ho verificato il codice e funziona correttamente. Posso vedere l'immagine è scaricata e che posso visualizzare l'immagine (senza errori o avvisi). Dal momento che ho intenzione di espandere il mio codice, ho provato a installare ddd, e usare il debugger, ma il debugger non funziona, e il mio programma si chiude con una sorta di errore Signal, quando provo a eseguire il mio programma con ddd.

Questo è l'errore:

(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 

primo momento ho pensato che non ho installato correttamente ddd, così sono tornato a gdb, ma ottengo gli stessi errori esatti, quando si esegue il programma. (E credo che sto usando l'ultima versione di gdb e ddd)

Poi ho provato a usare ddd su un altro programma semplice, che non coinvolge la libreria cURL, e ha funzionato bene !!!

Qualcuno sa perché questo è il caso, e qual è la soluzione? Devo in qualche modo puntare alle librerie cURL mentre ddd è in esecuzione? Ma, in passato, non ricordo di averlo fatto con diversi set di librerie! Forse è qualcosa in più che non piace a ddd? Ma il programma funziona bene senza il debugger! Gradirei un aiuto.

+1

solo dicendo: sono venuto qui con lo stesso errore. La mia soluzione era di ritornare a 'gdb 7.6.1' (da gdb7.7). – Sebastian

+0

Grazie, Sebastian! – Mike

+0

Possibile duplicato di [SSL \ _library \ _init causa SIGILL durante l'esecuzione in gdb] (https://stackoverflow.com/questions/25708907/ssl-library-init-cause-sigill-when-running-under-gdb) – jww

risposta

13

Immagino che possa far parte di un codice di rilevamento del set di istruzioni. Lascia che il programma continui e vedi se gestisce il segnale da solo (poiché funziona al di fuori di gdb, probabilmente lo fa). In alternativa, puoi dire a gdb di non disturbarti affatto con SIGILL prima di eseguire il programma: handle SIGILL pass nostop noprint.

È solo un problema se il programma muore, cosa non chiara dalla domanda.

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 ha dato la soluzione. Ecco la ragione per cui succede.

libcrypto.so è la libreria crittografica di OpenSSL. OpenSSL esegue sonde di funzionalità della cpu eseguendo un'istruzione per vedere se è disponibile. Se viene generato un SIGILL, la funzione è non disponibile e al suo posto viene utilizzata una funzione appropriata.

Il motivo per cui vengono visualizzati su ARM e non su IA-32 è, su Intel IA-32, l'istruzione cpuid non è un privilegio. Qualsiasi programma può eseguire cpuid per rilevare le funzioni della CPU, quindi non è necessario il programma di funzionalità basato su SIGILL.

In contrasto con IA-32, l'equivalente ARM di cpuid è un'istruzione privilegiata. Il tuo programma richiede Exception Level 1 (EL-1), ma il tuo programma gira su EL-0. Per fare un passo avanti la necessità di privilegi sui programmi ARM impostare un jmpbuf e installare un gestore SIGILL. Quindi, provano le istruzioni in questione e il gestore SIGILL indica se l'istruzione o la funzione è disponibile o meno.

OpenSSL è stato recentemente modificato in SIGILL - rilevamento di funzionalità gratuite su alcune piattaforme Apple perché Apple corrompe le cose. Vedi anche PR 3108, SIGILL-free processor capabilities detection on MacOS X. Altre biblioteche stanno facendo simili.Vedi anche How to determine ARMv8 features at runtime?

OpenSSL documenta anche il comportamento di SIGILL nelle loro FAQ. Vedere l'articolo 17 nelle Domande frequenti su OpenSSL per ulteriori dettagli: When debugging I observe SIGILL during OpenSSL initialization: why? Vedere anche SSL_library_init cause SIGILL when running under gdb su Stack Overflow.

Problemi correlati