- 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