• <li id="00i08"><input id="00i08"></input></li>
  • <sup id="00i08"><tbody id="00i08"></tbody></sup>
    <abbr id="00i08"></abbr>
  • 博客專欄

    EEPW首頁 > 博客 > libcurl中使用curl_easy_getinfo 產(chǎn)生段錯誤分析

    libcurl中使用curl_easy_getinfo 產(chǎn)生段錯誤分析

    發(fā)布人:電子禪石 時間:2025-03-20 來源:工程師 發(fā)布文章

    踩棧的典型案例:

    最近再寫一個hsf的代理程序。需要使用libcurl與后端的nginx通信。程序編寫過程中遇到一個蹊蹺的問題。
    調(diào)用 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; //此處設(shè)置為int類型 會有段錯誤。如果long類型沒問題。
        char str_rsp_code[5] = {'\0'};
        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);
    當(dāng)rsp_code設(shè)置為int類型 會有段錯誤。如果long類型沒問題。

    分析:
    下載了libcurl的代碼,查找原因。
    原來curl_easy_getinfo的實現(xiàn)使用了可變參數(shù)。即,在編譯時不進行參數(shù)個數(shù)和參數(shù)類型檢測。這樣,在使用這個函數(shù)時,無論你傳入的類型是int還是long,都不會報錯。雖然,它要求的是long類型。不過,在賦值的時候,他可是按long類型賦值的。這樣就導(dǎo)致棧被破壞了。當(dāng)然就報段錯誤了。
    相關(guān)代碼如下:

    #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;
    }

    驗證:
    編寫了示例代碼,驗證了假設(shè)。注意此代碼在32位操作系統(tǒng)上不會報錯,在64位操作系統(tǒng)上會報段錯誤。注意只有在int和long類型長度不一致時才會出現(xiàn)段錯誤。如在64位操作系統(tǒng)。.

    #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]$ ./testp value 202b value b段錯誤


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



    *博客內(nèi)容為網(wǎng)友個人發(fā)布,僅代表博主個人觀點,如有侵權(quán)請聯(lián)系工作人員刪除。



    關(guān)鍵詞: curl

    技術(shù)專區(qū)

    關(guān)閉
    主站蜘蛛池模板: 牟定县| 嘉义县| 邻水| 西丰县| 贺兰县| 越西县| 桂阳县| 建水县| 潼关县| 宝坻区| 本溪| 黑龙江省| 大新县| 锡林郭勒盟| 阜宁县| 东至县| 九龙城区| 白沙| 句容市| 白水县| 鄯善县| 东平县| 鄯善县| 台安县| 娄底市| 饶平县| 定陶县| 大竹县| 电白县| 封丘县| 沽源县| 苏尼特右旗| 凌海市| 吴堡县| 漠河县| 安龙县| 玉林市| 泽普县| 黄龙县| 香港| 香河县|