[英]Why is libcurl segfaulting on this call to curl_easy_perform()?
在我為負載測試站點編寫的HTTP Flooder中使用libCURL時,出現了段錯誤。
這是相關的代碼: https : //gist.github.com/AppleDash/a26e0ce0b138cd9eacd2 (在此處粘貼有點大。)
這是它隔離段所在行的鏈接: https ://gist.github.com/AppleDash/a26e0ce0b138cd9eacd2#file-httpflood-improved-c-L57
這是段錯誤的回溯:
#0 0x00007ffff760d65b in fwrite () from /usr/lib/libc.so.6
#1 0x00007ffff79656d8 in ?? () from /usr/lib/libcurl.so.4
#2 0x00007ffff797a76b in ?? () from /usr/lib/libcurl.so.4
#3 0x00007ffff7984349 in ?? () from /usr/lib/libcurl.so.4
#4 0x00007ffff7984b11 in curl_multi_perform () from /usr/lib/libcurl.so.4
#5 0x00007ffff797b977 in curl_easy_perform () from /usr/lib/libcurl.so.4
#6 0x0000000000400f42 in flood (structPointer=0x7fffffffe060) at httpflood.c:57
#7 0x00007ffff7bc5124 in start_thread () from /usr/lib/libpthread.so.0
#8 0x00007ffff768b4bd in clone () from /usr/lib/libc.so.6
我不明白為什么這個電話會引起段錯誤。 有任何想法嗎?
我知道您只打算提供一小部分相關代碼,但由於我覺得這里需要上下文,因此在這里提供了全部內容。 (事實上,它是從許多線程等運行的。)
這是你的問題:
for (i = 0; i < threadnum; i++) {
struct flood_data ddosData;
memset(&ddosData, 0, sizeof(struct flood_data));
ddosData.url = url;
ddosData.proxy = getProxy();
pthread_create(&threads[i], NULL, flood, (void *)&ddosData);
}
您要在堆棧上分配單個struct flood_data
實例,並將其同時傳遞給所有新線程。 每次迭代循環時,您都會覆蓋同一實例,而從較早的迭代生成的線程可能會嘗試從中讀取同一實例。 主要的不確定行為。
正確的方法是為每個線程動態分配一個單獨的實例:
for (i = 0; i < threadnum; i++) {
struct flood_data *ddosData = calloc(1, sizeof(*ddosData));
ddosData->url = url;
ddosData->proxy = getProxy();
pthread_create(&threads[i], NULL, flood, ddosData);
}
...
void *flood(void *structPointer) {
struct flood_data *data = structPointer;
char *bootable = data->url;
char *proxy = data->proxy;
free(data);
...
}
正如評論中指出的那樣,您還需要檢查系統調用是否失敗。 您應該驗證對fopen()
所有調用都成功,因為您很可能會達到在進程中打開的文件描述符的最大數目。 而不是將文件打開到/dev/null
,為什么不使用CURLOPT_WRITEFUNCTION
選項設置無操作寫功能呢?
static size_t noop_write_callback(char *ptr, size_t size, size_t nmemb, void *userdata)
{
// Do nothing
return size * nmemb;
}
...
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &noop_write_callback);
// No need to call fopen("/dev/null") or set CURLOPT_WRITEDATA now
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.