Hi all, yesterday I built my first own version of cURL using a somewhat recent 7.44.0 using projects for the IDE Embarcadero C++ Builder 10 Seattle targeting 32 Bit Windows applications. I've created two projects, one for libcurl, one for curl.exe and my libcurl setup is to create a static lib. In the end both built fine, so I ested a bit using curl.exe and recognized an access violation in certain situations.
The problem only occurs if I call curl.exe in a mode in which it prints progress output on STDERR, like in the following calls on the shell: > curl.exe http://www.example.org > test.html > curl.exe -o test.html http://www.example.org If no output redirection is used and curl prints HTML on STDOUT, everything works and the application doesn't crash. The interesting part is that even WITH output redirection and if progress is printed on STDERR, curl successfully retrieves all of the data to download and only crashes sometimes afterwards. My IDE provides a debugging helper called CodeGuard which can be enabled to replace some memory related functions with itself and check for access violations. After activation, rebuilding and running curl.exe, it provided me the following line as the source of the problem: > static int dprintf_formatf( [...] > case FORMAT_STRING: [...] > else > len = strlen(str); When the access violation occurs, the pointer str ALWAYS points to address 0x64, no exceptions so far, and is invalid, especially it is not NULL of course, but its value is not 0 to be an empty string as well. What I find interesting is that 0x64 is 100 decimal, which seems to be the value of the current progress and would fit to the fact, that the HTML is saved successfully and completely before the access violation occurs and some progress is output as well. After applying the following little patch and checking for the problematic state the access violation is gone: > Index: mprintf.c > =================================================================== > --- mprintf.c (Revision 4088) > +++ mprintf.c (Arbeitskopie) > @@ -791,7 +791,12 @@ > size_t len; > > str = (char *) p->data.str; > - if(str == NULL) { > + if ((p->data.num.as_unsigned == 100) && > + (str == > 100)) > + { > + str = NULL; > + } > + if(str == NULL) { > /* Write null[] if there's space. */ > if(prec == -1 || prec >= (long) sizeof(null) - 1) { > str = null; Obviously this is a only a workaround and the real problem is the wrong pointer for str, but I don't understand enough about how the caller works and such and I really doubt that I'm the first one recognizing such a problem, which is reproducible to me. So, do you have any idea on what might cause that problem? Thanks! The following is the stack trace: > :0cd16b09 ; C:\Program Files (x86)\Embarcadero\Studio\17.0\bin\CG32.DLL > :0cd16dae ; C:\Program Files (x86)\Embarcadero\Studio\17.0\bin\CG32.DLL > :0cd16604 ; C:\Program Files (x86)\Embarcadero\Studio\17.0\bin\CG32.DLL > :0cd180e9 ; C:\Program Files (x86)\Embarcadero\Studio\17.0\bin\CG32.DLL > :0cd142b4 ; C:\Program Files (x86)\Embarcadero\Studio\17.0\bin\CG32.DLL > :0cd142f6 CG32._CG_VALIDATESTRING + 0x2a > :0cd0474f CG32.__cg_strlen + 0x43 > :0047d799 strlen(const signed char *) + 0xD > :004BC58A dprintf_formatf(data=:006DB768, stream=:0047DB88, format=:00686087, > ap_save=:0018F814) > :004BCCF5 curl_mfprintf(whereto=:006DB768, format=:00686087, > ap_save=:0018F814) > :004C74B9 Curl_pgrsUpdate(conn=:022A20D0) > :004C6724 Curl_pgrsDone(conn=:022A20D0) > :004E2204 Curl_done(connp=:022DF138, status=0 /* CURLE_OK */, premature=0 /* > bool_false */) > :004BF9CA multi_runsingle(multi=:022C9890, now={ 306284, 890000 }, > data=:022DF130) > :004BFC93 curl_multi_perform(multi_handle=:022C9890, > running_handles=:0018FAA0) > :0049E720 easy_transfer(multi=:022C9890) > :0049E86E easy_perform(data=:022DF130, events=0 /* bool_false */) > :0049E894 curl_easy_perform(easy=:022DF130) > :004558D6 operate_do(global=:0018FEFC, config=:02333D60) > :00456740 operate(config=:0018FEFC, argc=4, argv=:0235A680) > :00447036 main(argc=4, argv=:0235A680) > :0064a9ca ; __startup Memory of "p" where str comes from, which is the same as "vto[3]": > Name Wert > p :0018EBD0 > type 1 /* FORMAT_STRING */ > flags 0 (0x00000000) > width 0L (0x00000000) > precision 0L (0x00000000) > data { "", :00000064, { 100, 100 }, > 4.94065645841247E-322 } > str :00000064 "" > [0] ???? > ptr :00000064 > num { 100, 100 } > as_signed 100L (0x00000064) > as_unsigned 100UL (0x00000064) > dnum 4.94065645841247E-322 Memory of Curl_pgrsUpdate higher in the stack, which shows 100% progress: > Name Wert > now { 306284, 890000 } > result 214968049 (0x0CD026F1) > max5 { "13970\0\n\0\0\0", " 0\0Dû\x18\0", "13970\0\0\0Øø", > "21295\0¼ø\x18\0", " 0\0\0\0’6", "74705\0€\x02\n\0"} > dlpercen 100 (0x64) > ulpercen 0 (0x0) > total_percen 100 (0x64) > total_transfer 13970 (0x3692) > total_expected_transfer 13970 (0x3692) > timespent 0 (0x0) > data :022DF130 > nowindex 1 (0x00000001) > checkindex 0 (0x00000000) > countindex 1 (0x00000001) > time_left "--:--:--\0\x1D" > time_total "--:--:--\0Ý" > time_spent "--:--:--\0\0" > ulestimate 0 (0x0) > dlestimate 0 (0x0) > total_estimate 0 (0x0) > shownow 1 /* bool_true */ > conn :022A20D0 Mit freundlichen Grüßen, Thorsten Schöning -- Thorsten Schöning E-Mail: [email protected] AM-SoFT IT-Systeme http://www.AM-SoFT.de/ Telefon...........05151- 9468- 55 Fax...............05151- 9468- 88 Mobil..............0178-8 9468- 04 AM-SoFT GmbH IT-Systeme, Brandenburger Str. 7c, 31789 Hameln AG Hannover HRB 207 694 - Geschäftsführer: Andreas Muchow ------------------------------------------------------------------- List admin: http://cool.haxx.se/list/listinfo/curl-library Etiquette: http://curl.haxx.se/mail/etiquette.html
