C++ libcurl中使用curl_easy_getinfo 產生段錯誤分析

來源:互聯網
上載者:User

最近再寫一個hsf的代理程式。需要使用libcurl與後端的nginx通訊。程式編寫過程中遇到一個蹊蹺的問題。
調用 code = curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &rsp_code); 後會報段錯誤。
範例程式碼如下:

 代碼如下 複製代碼
static int http_proxy(std::string domain, std::string path, std::string params, std::string &rsp_cont, std::string host = ""){
    string url;
    int rsp_code; //此處設定為int類型 會有段錯誤。如果long類型沒問題。
    char str_rsp_code[5] = {''};
    CURLcode code;
    CURL* curl;
    curl_slist *headers = NULL;
    curl = curl_easy_init();
 
    curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
    curl_easy_setopt(curl, CURLOPT_USERAGENT, "hsfproxy");
    curl_easy_setopt(curl, CURLOPT_READFUNCTION, NULL);
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, on_write);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&rsp_cont);
    curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
    curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 5);
    curl_easy_setopt(curl, CURLOPT_TIMEOUT, 5);
    code = curl_easy_perform(curl);
    code = curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &rsp_code);
    curl_easy_cleanup(curl);
    sprintf(str_rsp_code,"%d",rsp_code);
    log("curl: http code["+ (std::string)str_rsp_code +"] url[" + (std::string)url + "] domain["+ domain +"]", __FILE__, __LINE__, __FUNCTION__, LOG_VERBOSE);
    return 1;
}

問題:
int rsp_code;
code = curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &rsp_code);
當rsp_code設定為int類型 會有段錯誤。如果long類型沒問題。
分析:
下載了libcurl的代碼,尋找原因。
原來curl_easy_getinfo的實現使用了可變參數。即,在編譯時間不進行參數個數和參數類型檢測。這樣,在使用這個函數時,無論你傳入的類型是int還是long,都不會報錯。雖然,它要求的是long類型。不過,在賦值的時候,他可是按long類型賦值的。這樣就導致棧被破壞了。當然就報段錯誤了。
相關代碼如下:

 代碼如下 複製代碼
#undef curl_easy_getinfo
CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, ...)
{
  va_list arg;
  void *paramp;
  CURLcode ret;
  struct SessionHandle *data = (struct SessionHandle *)curl;
 
  va_start(arg, info);
  paramp = va_arg(arg, void *);
 
  ret = Curl_getinfo(data, info, paramp);
 
  va_end(arg);
  return ret;
}

驗證:
編寫了範例程式碼,驗證了假設。注意此代碼在32位作業系統上不會報錯,在64位作業系統上會報段錯誤。注意只有在int和long類型長度不一致時才會出現段錯誤。如在64位作業系統。

 代碼如下 複製代碼


#include <iostream>
#include <string>
#include <cstdarg>
 
using namespace std;
 
void f(char chr, ...){
        long value = 202;
        long *paramp;
        va_list arg_ptr;
        va_start(arg_ptr, chr);
        paramp = va_arg(arg_ptr, long *);
        va_end(arg_ptr);
        *paramp = value;
}
int main(){
        string a;
        int p=0;
        string b;
        a = "a";
        b = "b";
        f('a',&p);
        cout << "p value " << p << endl;
        cout << "a value " << a << endl;
        cout << "b value " << b << endl;
輸出:
協助

[hailong.xhl@v101080140 test]$ ./test
p value 202
b value b

段錯誤
看來,寬鬆意為著需要更加嚴謹。沒有條條框框的約束,得做好自我約束。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.