사용하고 난에합니다 (getinmemory.c libcurl에서 예를을 통합하려고 할 때 성공적으로libcurl에서 : WriteMemoryCallback 내가 C를 사용하여 JSON-RPC 요청을
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <curl/curl.h>
void post_rpc(CURL *curl_handle)
{
CURLcode res;
char JSONRPC_BASE_URL[] = "https://api.betfair.com/exchange/betting/json-rpc/v1";
char rpc_request[]="{\"jsonrpc\": \"2.0\", \"method\": \"SportsAPING/v1.0/listEventTypes\", \"params\": {\"filter\":{ }}, \"id\": 1}";
char session_token[]= "MY_ACTIVE_SESSION_STRING";
char session_header[100+sizeof(session_token)];
strcpy(session_header, "X-Authentication:");
strcat(session_header, session_token);
struct curl_slist * headers = NULL;
headers = curl_slist_append(headers, "X-Application: MY_API_KEY");
headers = curl_slist_append(headers, session_header);
headers = curl_slist_append(headers, "content-type : application/json");
/* init the curl session */
curl_handle = curl_easy_init();
/* HEADERS */
curl_easy_setopt(curl_handle, CURLOPT_HTTPHEADER, headers);
/* POST FIELD : Json-rpc request */
curl_easy_setopt(curl_handle, CURLOPT_POSTFIELDS, rpc_request);
curl_easy_setopt(curl_handle, CURLOPT_POSTFIELDSIZE, (long)strlen(rpc_request));
/* stdout the header sent */
curl_easy_setopt(curl_handle, CURLOPT_WRITEHEADER, stdout);
curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, stdout);
/* specify URL to get */
curl_easy_setopt(curl_handle, CURLOPT_URL, JSONRPC_BASE_URL);
/* get it! */
res = curl_easy_perform(curl_handle);
/* check for errors */
if(res != CURLE_OK) {
fprintf(stderr, "curl_easy_perform() failed: %s\n",
curl_easy_strerror(res));
}
}
int main(){
int res;
CURL *curl_handle;
curl_global_init(CURL_GLOBAL_DEFAULT);
post_rpc(curl_handle);
curl_global_cleanup();
return 0;
}
그러나 다음 코드를 사용하여 libcurl에 curl_easy_perform에 분할 오류 내가 기본적으로 위의 코드를 추가하는 내 편집)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <curl/curl.h>
struct MemoryStruct {
char *memory;
size_t size;
};
static size_t
WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp)
{
size_t realsize = size * nmemb;
struct MemoryStruct *mem = (struct MemoryStruct *)userp;
mem->memory = realloc(mem->memory, mem->size + realsize + 1);
if(mem->memory == NULL) {
/* out of memory! */
printf("not enough memory (realloc returned NULL)\n");
return 0;
}
memcpy(&(mem->memory[mem->size]), contents, realsize);
mem->size += realsize;
mem->memory[mem->size] = 0;
return realsize;
}
int main(void)
{
CURL *curl_handle;
CURLcode res;
struct MemoryStruct chunk;
chunk.memory = malloc(1); /* will be grown as needed by the realloc above */
chunk.size = 0; /* no data at this point */
curl_global_init(CURL_GLOBAL_ALL);
/* init the curl session */
curl_handle = curl_easy_init();
char JSONRPC_BASE_URL[] = "https://api.betfair.com/exchange/betting/json-rpc/v1";
char rpc_request[]="{\"jsonrpc\": \"2.0\", \"method\": \"SportsAPING/v1.0/listEventTypes\", \"params\": {\"filter\":{ }}, \"id\": 1}";
char session_token[]= "MY_ACTIVE_SESSION_STRING";
char session_header[100+sizeof(session_token)];
strcpy(session_header, "X-Authentication:");
strcat(session_header, session_token);
struct curl_slist * headers = NULL;
headers = curl_slist_append(headers, "X-Application: MY_API_KEY");
headers = curl_slist_append(headers, session_header);
headers = curl_slist_append(headers, "content-type : application/json");
/* HEADERS */
curl_easy_setopt(curl_handle, CURLOPT_HTTPHEADER, headers);
/* POST FIELD : Json-rpc request */
curl_easy_setopt(curl_handle, CURLOPT_POSTFIELDS, rpc_request);
curl_easy_setopt(curl_handle, CURLOPT_POSTFIELDSIZE, (long)strlen(rpc_request));
/* stdout the header sent */
curl_easy_setopt(curl_handle, CURLOPT_WRITEHEADER, stdout);
curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, stdout);
/* specify URL to get */
curl_easy_setopt(curl_handle, CURLOPT_URL, JSONRPC_BASE_URL);
/* send all data to this function */
curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
/* we pass our 'chunk' struct to the callback function */
curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *)&chunk);
/* some servers don't like requests that are made without a user-agent
field, so we provide one */
curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "libcurl-agent/1.0");
printf("THIS IS PRINTED\n");
fflush(stdout);
/* get it! */
res = curl_easy_perform(curl_handle); //LINE 114: SEGFAULT
printf("THIS IS NOT...\n");
fflush(stdout);
/* check for errors */
if(res != CURLE_OK) {
fprintf(stderr, "curl_easy_perform() failed: %s\n",
curl_easy_strerror(res));
}
else {
/*
* Now, our chunk.memory points to a memory block that is chunk.size
* bytes big and contains the remote file.
*
* Do something nice with it!
*/
printf("%lu bytes retrieved\n", (long)chunk.size);
printf("Chunk:%s\n", chunk.memory);
}
/* cleanup curl stuff */
curl_easy_cleanup(curl_handle);
if(chunk.memory)
free(chunk.memory);
/* we're done with libcurl, so clean it up */
curl_global_cleanup();
return 0;
}
을 들여 한 곳 대신에 표준 출력의 변수)의 출력을 얻기 위해, 따라서 (다음 코드로 올라오고3210
나는 writeMemoryCallback
내부 realloc
호출에 발생
res = curl_easy_perform(curl_handle);
에서 세그먼트 오류를 얻을.
위의 예에서 stdout에 인쇄 된 헤더는 여기에 인쇄되지 않습니다.
$ valgrind ./dafuq --tool memcheck
==7002== Memcheck, a memory error detector
==7002== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==7002== Using Valgrind-3.10.0 and LibVEX; rerun with -h for copyright info
==7002== Command: ./dafuq --tool memcheck
==7002==
THIS IS PRINTED
==7002== Invalid free()/delete/delete[]/realloc()
==7002== at 0x4C2AF2E: realloc (vg_replace_malloc.c:692)
==7002== by 0x400D27: WriteMemoryCallback (getinmemory.c:44)
==7002== by 0x4E4BD89: ??? (in /usr/lib/x86_64-linux-gnu/libcurl.so.4.3.0)
==7002== by 0x4E4A353: ??? (in /usr/lib/x86_64-linux-gnu/libcurl.so.4.3.0)
==7002== by 0x4E605AF: ??? (in /usr/lib/x86_64-linux-gnu/libcurl.so.4.3.0)
==7002== by 0x4E6ACE8: ??? (in /usr/lib/x86_64-linux-gnu/libcurl.so.4.3.0)
==7002== by 0x4E6B560: curl_multi_perform (in /usr/lib/x86_64-linux-gnu/libcurl.so.4.3.0)
==7002== by 0x4E6215A: curl_easy_perform (in /usr/lib/x86_64-linux-gnu/libcurl.so.4.3.0)
==7002== by 0x401178: main (getinmemory.c:114)
==7002== Address 0xfbad2a84 is not stack'd, malloc'd or (recently) free'd
==7002==
not enough memory (realloc returned NULL)
THIS IS NOT...
curl_easy_perform() failed: Failed writing received data to disk/application
==7002==
==7002== HEAP SUMMARY:
==7002== in use at exit: 238 bytes in 8 blocks
==7002== total heap usage: 7,171 allocs, 7,163 frees, 67,842,654 bytes allocated
==7002==
==7002== LEAK SUMMARY:
==7002== definitely lost: 16 bytes in 1 blocks
==7002== indirectly lost: 158 bytes in 5 blocks
==7002== possibly lost: 0 bytes in 0 blocks
==7002== still reachable: 64 bytes in 2 blocks
==7002== suppressed: 0 bytes in 0 blocks
==7002== Rerun with --leak-check=full to see details of leaked memory
==7002==
==7002== For counts of detected and suppressed errors, rerun with: -v
==7002== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
어떤 생각 : 인쇄되어있는 유일한 방법은
$ ./dafuq
THIS IS PRINTED
Segmentation fault
이것은 GDB는 Valgrind의 덤프는
(gdb) break 114
Breakpoint 1 at 0x40116d: file getinmemory.c, line 114.
(gdb) break 115
Breakpoint 2 at 0x40117c: file getinmemory.c, line 115.
(gdb) run
Starting program: dafuq
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
THIS IS PRINTED
Breakpoint 1, main() at getinmemory.c:114
114 res = curl_easy_perform(curl_handle);
(gdb) step
[New Thread 0x7ffff341e700 (LWP 6774)]
[Thread 0x7ffff341e700 (LWP 6774) exited]
Program received signal SIGSEGV, Segmentation fault.
__GI___libc_realloc (oldmem=0xfbad2a84, bytes=140737354092562) at malloc.c:2977
2977 malloc.c: No such file or directory.
(gdb)
덤프입니다?
추신 : 정확히 같은 행동으로 올라오고 here에서 sth의 코드와 같은 스트림을 사용해 보았습니다.
먼저 (예 : 세션을 만료) * 모든 * 함수의 값을 반환 한 다음 malloc/realloc 호출을 바꾸어보십시오. – 2501
http://curl.haxx.se/libcurl/c/postinmemory.html 예제가 원하는 것보다 훨씬 더 가까울 수도 있습니다 ... –
좋은 지적입니다. 모든 libcurl 함수는 다음을 반환합니다. ''realloc ''을 ''malloc ''으로 바꾸면 (gdb에서) 프로그램 수신 신호 SIGSEGV, 세그먼트 오류가 발생합니다. __memcpy_sse2_unaligned() ../sysdeps/x86_64/multiarch/memcpy-sse2-unaligned.S:35 ../sysdeps/x86_64/multiarch/memcpy-sse2-unaligned.S에서 : 해당 파일이나 디렉토리. – chefarov