I recently wrote another hsf proxy program. Use libcurl to communicate with the backend nginx. The programming process encountered a strange problem.
Call code = curl_easy_getinfo (curl, CURLINFO_RESPONSE_CODE, & rsp_code); a segment error is reported.
The sample code is as follows:
The code is as follows: |
Copy 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; // If this parameter is set to int, a segment error occurs. If the long type is correct. 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; }
|
Problem:
Int rsp_code;
Code = curl_easy_getinfo (curl, CURLINFO_RESPONSE_CODE, & rsp_code );
When rsp_code is set to int type, a segment error occurs. If the long type is correct.
Analysis:
Download the libcurl code to find the cause.
The original curl_easy_getinfo implementation uses variable parameters. That is, the number and type of parameters are not checked during compilation. In this way, no error is reported whether the input type is int or long. Although, it requires the long type. However, when assigning values, he assigns values based on the long type. In this way, the stack is damaged. Of course, a segment error is reported.
The related code is as follows:
The code is as follows: |
Copy code |
# 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; }
|
Verification:
The sample code is compiled to verify the hypothesis. Note that this code does not report errors on 32-bit operating systems, and reports segment errors on 64-bit operating systems. Note that a segment error occurs only when the length of the int and long types is inconsistent. For example, in a 64-bit operating system.
The code is as follows: |
Copy code |
# Include <iostream> # Include <string> # Include <cstdarg> Using namespace std; Void f (char chr ,...){ Long values = 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; Int p = 0; String B; A = ""; B = "B "; F ('A', & p ); Cout <"p value" <p <endl; Cout <"a value" <a <endl; Cout <"B value" <B <endl; Output: Help
[Hailong. xhl @ v1080140 test] $./test P value 202 B value B |
Segment error
It seems that loose means more rigorous. There are no constraints, so you must be self-disciplined.