【问题标题】:simple libcurl app - segfault简单的 libcurl 应用程序 - 段错误
【发布时间】:2012-04-28 10:01:40
【问题描述】:

我无法确定我的代码在哪里出现了段错误?

基本上,它通过 SSL (HTTPS) 安全连接连接到服务器并进行 GET,提供 MachineID(程序将其作为参数)。

还应设置一些自定义标题。然后我将返回的正文和标题保存为单独的文本文件。 (基本上它会运行一个 shell 脚本,所以我的远程系统可以自动从我的服务器获取“订单”)

但是它有段错误,我必须在其上开发它的唯一 linux 机器是我的 VPS,由于其奇怪的虚拟化,加载 GDB 时总是崩溃...:o

谁能告诉我问题出在哪里? - 我认为它几乎可以肯定是在我的字符串连接中 - 我在其中构建标题和请求 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;
}

【问题讨论】:

    标签: c++ c curl segmentation-fault libcurl


    【解决方案1】:

    您正在使用字符串文字作为strcat 的目标。您需要为指针分配内存,然后将它们用作strcpystrcat 函数中的目标

    字符串文字通常驻留在 RO 区域中,写入此类区域可能会调用 未定义行为

    改变类似的东西

    char *url
    

    char url[100];
    

    还可以考虑使用strcatstrcpyn 版本和适当的缓冲区大小,以防止意外缓冲区溢出

    【讨论】:

    • 更好的是,将url 声明为const char* 并动态分配大小为strlen(url)+strlen(machineID)+1 的新数组。或者,由于这是用 C++ 标记的,请使用 std::string
    • 谢谢大家。以后我会试试的。现在对 C 字符串操作有点生疏,去年一直在做 Java...
    【解决方案2】:

    如果不自己分配内存,您将无法执行strcat

    【讨论】:

      【解决方案3】:

      不管提供给参考的代码中可能存在的错误,在我过去的观点中,我发现 libssl 的使用默认情况下不是线程安全的。 如果您使用的是 libssl,请告诉我们,如果是这样,我将能够提供更多信息

      请通过第 2 个陷阱 http://horstr.blogspot.in/2008/04/on-libcurl-openssl-and-thread-safety.html 更多启示

      【讨论】:

        猜你喜欢
        • 2012-09-16
        • 1970-01-01
        • 2014-01-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-09-15
        • 1970-01-01
        相关资源
        最近更新 更多