curl-library
Re: cURL bug -- Segmentation Fault when timeout is 1 second
Date: Mon, 9 Feb 2009 20:08:36 +0100
>>>>> What do you mean with the SSL-Part? What has to be other if a
>>>>> HTTPS-page is
>>>> called? Will the thread-safeness disappear then or whatß
>>>
>>> As described in the manual: yes.
>>>
>>> http://curl.haxx.se/libcurl/c/libcurl-tutorial.html#Multi-threading
>>
>> There is written something with SSL/TLS handlers. But what has this to
>> do with multithreading? I don't use own TLS-handlers or something in
>> that direction. So, what do I have to change for SSL?
>
> Read it again. Yes, most of that section discusses SSL, but there is some
> other relevant information there.
I did read and understand, but the OpenSSL part is not relevant to me
because I don't use this crypto locks provided there. I also followed those
2 links. I am not stupid, as you might think.
>
>>>>> Can you post a full stand-alone example here that crashes for you and
>>>>> that
>>>
>>>> I actually did post a full, stand-alone code that can be directly
>>>> compiled
>>>> and runned, look at my post.
>>>
>>> You didn't post it here and I didn't chase around for one.
>>
>> If you cannot follow a link, I doubt your readiness to help. I cannot
>> post 300 lines code unformated in this newsgroup. The link contains
>> exactly the code and is well formated and highlighted.
>
> If you cannot follow a link, I doubt your readiness to learn.
Smarty-pants, I don't need destructive backtalk.
>
> - Toby
Ah yes, your desired code because you cannot follow links:
#include <stdlib.h> // free, malloc, atoi, exit, EXIT_SUCCESS, EXIT_FAILURE,
setenv#include <pthread.h> // pthread_attr_init, PTHREAD_CREATE_DETACHED,
pthread_attr_setdetachstate, pthread_create, pthread_attr_destroy#include
<signal.h>#include <curl/curl.h>#include <string.h>#ifdef
__cplusplus#include <unistd.h> // sleep()#endif#ifndef __cplusplus#include
<stdbool.h> // Typ "bool"#endifstruct meinserver { uint id; char*
url; int downtime;};static void async_function_call( void*
(*start_routine)(void*), void* arg ) { pthread_t mythread; // Zu
Testzwecken nicht Detached int rc = pthread_create(&mythread, NULL,
start_routine, arg); if (rc != 0) { printf("pthread_create:
'%d'\n", rc); }
return;}//********************************************************************************************////
OFFIZIELLER CODE VON CURL, hier kann kein Fehler drinnen sein#include
<curl/types.h>#include <curl/easy.h>struct MemoryStruct { char *memory;
size_t size;};static void *myrealloc(void *ptr, size_t size){ /* There
might be a realloc() out there that doesn't like reallocing NULL
pointers, so we take care of it here */ if(ptr) return
realloc(ptr, size); else return malloc(size);}static size_t
WriteMemoryCallback(void *ptr, size_t size, size_t nmemb, void *data){
size_t realsize = size * nmemb; struct MemoryStruct *mem = (struct
MemoryStruct *)data; #ifndef __cplusplus mem->memory =
myrealloc(mem->memory, mem->size + realsize + 1); #else mem->memory =
(char*) myrealloc(mem->memory, mem->size + realsize + 1); #endif if
(mem->memory) { memcpy(&(mem->memory[mem->size]), ptr, realsize);
mem->size += realsize; mem->memory[mem->size] = 0; } return
realsize;}// *** ENDE CURL CODE ***// Code von einem offiziellen Example
abgeleitet, Fehler unwahrscheinlichstatic bool http_call (const char* url)
{ printf("Calling URL: '%s'\n", url); CURL *curl; curl =
curl_easy_init(); if (curl) { // URL übergeben
curl_easy_setopt(curl, CURLOPT_URL, url); // Pufferoptionen
char errorBuffer[CURL_ERROR_SIZE]; curl_easy_setopt(curl,
CURLOPT_ERRORBUFFER, errorBuffer); struct MemoryStruct chunk;
chunk.memory = NULL; chunk.size = 0; curl_easy_setopt(curl,
CURLOPT_WRITEFUNCTION, WriteMemoryCallback); curl_easy_setopt(curl,
CURLOPT_WRITEDATA, (void *)&chunk); // Der Cast ist für'n ***** //
Benutzerdefinierter User-Agent-Name curl_easy_setopt(curl,
CURLOPT_USERAGENT, "Hello World Browser"); // Einen Timeout setzen
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 1); // Einen
HTTP-Fehler-Statuscode beachten curl_easy_setopt(curl,
CURLOPT_FAILONERROR, true); curl_easy_setopt(curl, CURLOPT_NOSIGNAL,
true); curl_easy_setopt(curl, CURLOPT_DNS_USE_GLOBAL_CACHE, false);
// Abfrage ausführen und Resultat speichern CURLcode res; res
= curl_easy_perform(curl); // !! Wäre diese Zeile weg, käme der Fehler
nicht. Aber: http_call() funktioniert alleine korrekt. char *buffer =
chunk.memory; // Alias printf(buffer); printf("\n");
fflush(stdout); // Clean up curl_easy_cleanup(curl); //
Alles OK? if (res == CURLE_OK) { printf("URL
successfully entered.\n"); if (buffer != "\0") {
printf("There was an output (see next line).\n");
printf(buffer); // Bei snprintf würde der Puffer sonst platzen
printf("\n"); } else { printf("There was no
output.\n"); } return true; } else
{ printf("Error while calling URL '%s': [%d] - '%s'\n", url, res,
errorBuffer); return false; } } else { return
false; }}static char* strcombine(const char* str1, const char* str2)
{ #ifndef __cplusplus char *newstr =
malloc(strlen(str1)+strlen(str2)+1); #else char *newstr =
(char*)malloc(strlen(str1)+strlen(str2)+1); #endif if (newstr == NULL)
{ printf("Malloc-Error at strcombine()!\n"); return NULL; }
memcpy(newstr, str1, strlen(str1)+1); strcat(newstr, str2); return
newstr;}const char* CHECKING_APPENDIX = "startchecking.php";static
void* pwb_checking(void* data) { // Lese die übergebene Struktur aus
struct meinserver *k = (struct meinserver*)data; printf("Start checking
of system #%d\n", k->id); char* completeurl = strcombine(k->url,
CHECKING_APPENDIX); if (completeurl == NULL) { return NULL; }
printf(completeurl); printf("\n"); fflush(stdout); if
(http_call(completeurl)) { printf("HTTP CALL OK\n"); } else
{ printf("HTTP CALL BAD\n"); } free(completeurl); // malloc()
von strcombine() wieder freigeben free(k->url); // malloc() von
strclone() wieder freigeben printf("Stop checking of system #%d\n",
k->id); free(k); // malloc() von pwb_neuer_durchlauf() wieder freigeben
return NULL;}static char* strclone(const char* str) { char *newstr =
malloc(strlen(str)+1); if (newstr == NULL) { printf("Malloc-Error
at strclone()!\n"); return NULL; } memcpy(newstr, str,
strlen(str)+1); return newstr;}static void* pwb_neuer_durchlauf(void*
data) { // Zu Demonstrationszwecken stark abstrahiert, Fehlererhaltend
// Die Werte "Fake-Test" und "2000" kommen eigentlich aus einer DB, sind
also lokale Variablen in Form von MYSQL_ROW row[...], werden aber korrekt in
die Struktur k kopiert, nicht referenziert. int i; for (i = 0; i<10;
i++) { struct meinserver *k = malloc(sizeof *k); if (k ==
NULL) { printf("Malloc-Error at pwb_neuer_durchlauf()!\n");
return NULL; } k->id = i; k->url =
strclone("http://www.example.com/"); // String einzigartig machen, damit der
Pointer nicht ungültig wird, wenn die Funktion zuende ist if (k->url
== NULL) { return NULL; } k->downtime =
atoi("2000"); async_function_call(pwb_checking, k); // !! Wäre hier
ein serieller statt asynchroner Aufruf, dann wäre kein Fehler... wieso? }
// In diesem Beispiel kein Join der Threads pwb_checking() return
NULL;}int main(void) { while (true) {
printf("-----------------------\n");
async_function_call(pwb_neuer_durchlauf, NULL); sleep(5); }
return EXIT_SUCCESS;}
Do you know what? Forget it...
Received on 2009-02-09