- From: by way of Henrik Frystyk Nielsen <whicken@parasoft.com>
- Date: Sun, 30 May 1999 14:27:09 -0400
- To: www-lib@w3.org
Henrik, Here's more info on the bug I'm hitting. I tried to send this to the mailing list, but got an "Out of Office AutoReply", so I decided to send you a copy directly as well. Sorry if it comes off as spam. The test program is also considerably smaller. Wendell >Date: Fri, 21 May 1999 17:01:28 -0700 >To: www-lib@w3.org >From: Wendell Hicken <whicken@parasoft.com> >Subject: libwww bug with "HTTP 1.0 keep-alive" > >Greetings. I think I found a bug in libwww which I do not know how to >solve cleanly (code attached). I apologize for the references to statefarm's >website, but that's where I can reproduce this bug. What >happens is that the first URL loads fine, then on the 2nd URL in >_dispatchParsers, libwww ends up calling the following code from >HTMIME_connection: > > if (HTHost_version(host) < HTTP_11) { > HTNet_setPersistent(net, YES, HT_TP_SINGLE); > HTTRACE(STREAM_TRACE, "MIMEParser.. HTTP/1.0 Keep >Alive\n"); > } else > >The call the HTNet_setPersistent ends up calling HTHost_clearChannel which >deletes the HTStream object being used in _dispatchParsers. Hence, when >libwww comes back from the call the HTMIME_connection, it's using pointers >to free'd data. From there it all goes wrong until the application crashes. > >The bug only reproduces if the first URL has been loaded first. This seems >to be because HTHost_setMode has a check: > > if (mode == HT_TP_SINGLE && host->mode > mode) { > >If the 2nd URL is loaded first, or the cached HTHost object table is cleared, >then the code does not enter this if, triggering the deletion. > >Here's the stack trace of the malignant free, in case it's of use to anyone: > >HTMemory_free() c:\libwww\w3c-libwww-5.2.8\library\src\htmemory.c, 132 >HTChunk_delete() c:\libwww\w3c-libwww-5.2.8\library\src\htchunk.c, 62 >HTMIME_free() c:\libwww\w3c-libwww-5.2.8\library\src\htmime.c, 484 >HTTPStatus_free() c:\libwww\w3c-libwww-5.2.8\library\src\http.c, 874 >HTReader_free() c:\libwww\w3c-libwww-5.2.8\library\src\htreader.c, 46 >HTChannel_delete() c:\libwww\w3c-libwww-5.2.8\library\src\htchannl.c, 237 >HTHost_free() c:\libwww\w3c-libwww-5.2.8\library\src\hthost.c, 1102 >HTHost_deleteNet() c:\libwww\w3c-libwww-5.2.8\library\src\hthost.c, 1133 >HTNet_delete() c:\libwww\w3c-libwww-5.2.8\library\src\htnet.c, 910 >HTTPCleanup() c:\libwww\w3c-libwww-5.2.8\library\src\http.c, 168 >HTTPEvent() c:\libwww\w3c-libwww-5.2.8\library\src\http.c, 1249 >HTNet_execute() c:\libwww\w3c-libwww-5.2.8\library\src\htnet.c, 582 >HTHost_launchPending() c:\libwww\w3c-libwww-5.2.8\library\src\hthost.c, 1227 >HTHost_clearChannel() c:\libwww\w3c-libwww-5.2.8\library\src\hthost.c, 797 >HTHost_setMode() c:\libwww\w3c-libwww-5.2.8\library\src\hthost.c, 900 >HTHost_setPersistent() c:\libwww\w3c-libwww-5.2.8\library\src\hthost.c, 705 >HTNet_setPersistent() c:\libwww\w3c-libwww-5.2.8\library\src\htnet.c, 1071 >HTMIME_connection() c:\libwww\w3c-libwww-5.2.8\library\src\htmimimp.c, 142 >HTMIMEParseSet_dispatch() c:\libwww\w3c-libwww-5.2.8\library\src\htmimprs.c, >179 >_dispatchParsers() c:\libwww\w3c-libwww-5.2.8\library\src\htmime.c, 270 >HTMIME_put_block() c:\libwww\w3c-libwww-5.2.8\library\src\htmime.c, 341 >HTTPStatus_put_block() c:\libwww\w3c-libwww-5.2.8\library\src\http.c, 851 >HTReader_read() c:\libwww\w3c-libwww-5.2.8\library\src\htreader.c, 201 >HTHost_read() c:\libwww\w3c-libwww-5.2.8\library\src\hthost.c, 1598 >HTTPEvent() c:\libwww\w3c-libwww-5.2.8\library\src\http.c, 1228 >HTLoadHTTP() c:\libwww\w3c-libwww-5.2.8\library\src\http.c, 962 >HTNet_newClient() c:\libwww\w3c-libwww-5.2.8\library\src\htnet.c, 807 >HTLoad() c:\libwww\w3c-libwww-5.2.8\library\src\htreqman.c, 1643 >launch_request() c:\libwww\w3c-libwww-5.2.8\library\src\htaccess.c, 77 >HTLoadAbsolute() c:\libwww\w3c-libwww-5.2.8\library\src\htaccess.c, 90 >HTLoadToStream() c:\libwww\w3c-libwww-5.2.8\library\src\htaccess.c, 130 >load() c:\libwww\w3c-libwww-5.2.8\library\examples\chunk.cpp, 184 >main() c:\libwww\w3c-libwww-5.2.8\library\examples\chunk.cpp, 212 > >Another interesting note is that the HTNet_setPersistent call from inside >HTMIME_connection gets invoked recursively - the delete seems to happen >after the inner HTNet_setPersistent has completed successfully. I don't know >if this is correct behaviour or not, but is seems odd. > >Wendell > >----------- >#include "WWWLib.h" >#include "WWWApp.h" >#include "WWWInit.h" > >char *data[] = { > "http://www.statefarm.com/sponsors/natgeo.htm", > "http://www.statefarm.com/sponsors/images/natgeo.gif" >}; > >int printer(const char * fmt, va_list pArgs) { > return vfprintf(stderr, fmt, pArgs); >} > >int tracer(const char * fmt, va_list pArgs) { > return vfprintf(stderr, fmt, pArgs); >} > >int main() { > HTProfile_newNoCacheClient("Test", "1.0"); > HTPrint_setCallback(printer); > HTTrace_setCallback(tracer); > HTSetTraceMessageMask("sop"); > > for (int i = 0; i < sizeof(data)/sizeof(data[0]); ++i) { > HTRequest *req = HTRequest_new(); > HTRequest_setPreemptive(req, YES); > HTRequest_setMethod(req, METHOD_GET); > HTRequest_setOutputFormat(req, WWW_SOURCE); > HTRequest_addConnection(req, "close", ""); > > HTLoadToChunk(data[i], req); > HTRequest_delete(req); > // Adding "HTHost_deleteAll();" here causes the bug not to > // occur, but that's not a good solution. > } > HTProfile_delete(); > return 0; >}
Received on Monday, 31 May 1999 13:13:06 UTC