2012-04-28 93 views
1

我無法弄清我的代碼在哪裏進行分割?簡單的libcurl應用程序 - segfault

基本上它通過SSL(HTTPS)安全連接連接到服務器,並提供一個GET,提供一個MachineID(程序將其作爲參數)。

還應該設置一些自定義標題。然後我將返回的正文和標題保存爲單獨的文本文件。 (基本上它會得到一個shell腳本來運行,所以我的遠程系統可以自動從我的服務器上獲取'訂單')

但是它的segfaults和我唯一需要開發的linux機器是我的VPS,對於這種奇怪的虛擬化,總是崩潰加載GDB ...:

誰能告訴我問題在哪裏? - 我認爲它幾乎可以肯定地在我的字符串連接中 - 我在其中構建標題並請求URL。

編輯:杜,忘了代碼!

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <curl/curl.h> 
#include <string.h> 

static size_t write_data(void *ptr, size_t size, size_t nmemb, void *stream) 
{ 
int written = fwrite(ptr, size, nmemb, (FILE *)stream); 
return written; 
} 

int main(int argc, char *argv[]) 
{ 
static const char *headerfilename = "head.out"; 
static const char *bodyfilename = "body.out"; 

char *url = "https://fakeserver.fakesite.com:8443/SystemManager/getOrders.jsp?machineID="; 
char *customHeader = "MachineID:"; 
char *machineID = NULL; 

struct curl_slist *chunk = NULL; 

CURL *curl; 
CURLcode res; 
FILE *headerfile; 
FILE *bodyfile; 

    if (argc == 2) 
{ 
    machineID = argv[1]; 
    strcat(url,machineID); 
} 
else 
{ 
printf("Usage: %s <MachineID>\n", argv[0]); 
return 1; 
} 

curl_global_init(CURL_GLOBAL_SSL); 

// init the curl session 
curl = curl_easy_init(); 

if(curl) { 
    // set URL to get 

curl_easy_setopt(curl, CURLOPT_URL, url); 

    // no progress meter please 
    curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1L); 

    // send all data to this function 
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data); 

// some servers don't like requests that are made without a user-agent field, so we provide one 
curl_easy_setopt(curl, CURLOPT_USERAGENT, "libcurl-agent/1.0"); 

// Also add a custom MachineID header 
strcat(customHeader, machineID); 
chunk = curl_slist_append(chunk, customHeader); 
res = curl_easy_setopt(curl, CURLOPT_HTTPHEADER, chunk); 

    // These tweaks must be enabled for my dodgy self-signed certificate. 

    // DONT bother verifying our certificate is signed by a trusted CA. 
    curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); 
    // DONT check the hostname on the certificate matcheds the remote system. 
    curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); 


    // open the files 
headerfile = fopen(headerfilename,"w"); 
if (headerfile == NULL) { 
curl_easy_cleanup(curl); 
return -1; 
} 
else 
{ 
// we want the headers to this file handle 
curl_easy_setopt(curl, CURLOPT_WRITEHEADER, headerfile); 
} 

bodyfile = fopen(bodyfilename,"w"); 
if (bodyfile == NULL) { 
curl_easy_cleanup(curl); 
return -1; 
} 
else 
{ 
// we want the body to this file handle 
curl_easy_setopt(curl, CURLOPT_WRITEDATA, bodyfile); 
} 
    // get it! 
res = curl_easy_perform(curl); 

    // close the files 
fclose(headerfile); 
fclose(bodyfile); 

// always cleanup curl stuff 
curl_easy_cleanup(curl); 
} 
curl_global_cleanup(); 
return 0; 
} 

回答

1

您正在使用字符串文字作爲strcat的目標。您需要分配內存的指針,然後在strcpystrcat功能

使用它們作爲目的地

字符串文字一般駐留在RO區和寫入這些地區可能會調用未定義行爲

改變的事情像

char *url 

char url[100]; 

還要考慮使用n版本strcatstrcpy和適當的緩衝區大小,以防止意外的緩衝區溢出

+0

更妙的是,聲明' url'作爲'const char *'並動態分配一個大小爲'strlen(url)+ strlen(machineID)+ 1'的新數組。或者,因爲這是用C++標記的,所以使用'std :: string'。 – 2012-04-28 10:15:12

+0

謝謝你們。我稍後再嘗試。 C字符串操作現在有點生疏,去年一直在做Java ... – 2012-04-28 10:43:51

0

你不能做一個不strcat自己分配內存。