You are viewing a plain text version of this content. The canonical link for it is here.
Posted to apreq-dev@httpd.apache.org by Franky Braem <f....@skynet.be> on 2006/03/04 22:28:59 UTC

upload file crashes when using apr_pool_cleanup_register

The following code crashes when I remove the comment before the 
apr_pool_cleanup_register (and put apr_file_close into comment 
ofcourse). When I use apr_file_close it works.

----------------- start code
apreq_param_t *param = apreq_body_get(p, elementName.c_str());
if (    param != NULL
	 && param->upload != NULL )
{
	apr_bucket_brigade *bb;
	apr_bucket *e;

	apr_file_t *file = NULL;
	apr_int32_t flags = APR_WRITE | APR_CREATE;
	if ( overrideFile )
		flags |= APR_TRUNCATE;

	apr_status_t fileStat;
	if ( (fileStat = apr_file_open(&file, fileName.c_str(), flags, 
APR_OS_DEFAULT, p->pool)) != APR_SUCCESS )
	{
		char fileError[1024];
		apr_strerror(fileStat, fileError, sizeof(fileError));
		JS_ReportError(cx, fileError);
		*rval = JSVAL_FALSE;
		return JS_TRUE;
	}
	//apr_pool_cleanup_register(p->pool, file, (apr_status_t (__cdecl 
*)(void *)) apr_file_close, apr_pool_cleanup_null);
	long totalLength = 0;

	bb = apr_brigade_create(p->pool, r->connection->bucket_alloc);
	apreq_brigade_copy(bb, param->upload);
	while( (e = APR_BRIGADE_FIRST(bb)) != APR_BRIGADE_SENTINEL(bb) )
	{
		apr_size_t dlen;
		const char *data;
		apr_status_t s;

		s = apr_bucket_read(e, &data, &dlen, APR_BLOCK_READ);
		if ( s != APR_SUCCESS )
		{
			JS_ReportError(cx, "Error occurred while reading uploaded file content");
			return JS_FALSE;
		}

		totalLength += dlen;
		if (    maxLength != -1
			 && maxLength < totalLength )
		{
			apr_bucket_delete(e);

			*rval = JSVAL_FALSE;
			return JS_TRUE;
		}
		apr_file_write(file, data, &dlen);

		apr_bucket_delete(e);
	}
	apr_file_flush(file);
	apr_file_close(file);
}

----------------- end code

The crash is:

Unhandled exception at 0x0096b338 in Apache.exe: 0xC0000005: Access 
violation writing location 0x26470016.

The stack trace:

  	0096b338()	
 >	libhttpd.dll!ap_process_http_connection(conn_rec * c=0x0096b338) 
Line 262	C
  	libhttpd.dll!ap_run_process_connection(conn_rec * c=0x0096b338)  Line 
43 + 0x25 bytes	C
  	libhttpd.dll!ap_process_connection(conn_rec * c=0x0096b338, void * 
csd=0x0096b268)  Line 176 + 0x6 bytes	C
  	libhttpd.dll!worker_main(void * thread_num_val=0x0096b330)  Line 733	C
  	msvcr80.dll!_endthreadex()  + 0x3b bytes	
  	[Frames below may be incorrect and/or missing, no symbols loaded 
for msvcr80.dll]	
  	msvcr80.dll!_endthreadex()  + 0xc7 bytes	


Re: upload file crashes when using apr_pool_cleanup_register

Posted by Franky Braem <f....@skynet.be>.
Joe Schaefer wrote:
> Franky Braem <f....@skynet.be> writes:
> 
> 
>>The following code crashes when I remove the comment before the
>>apr_pool_cleanup_register (and put apr_file_close into comment
>>ofcourse).
> 
> 
> I *think* it's because apr_file_open registers a pool cleanup automatically.
> So you don't need to register the cleanup, you wind up closing the file
> twice when you do that.
> 

Yep, you're right. Saw this in open.c:

if (!(flag & APR_FILE_NOCLEANUP))
{
   apr_pool_cleanup_register((*new)->pool, (void *)(*new), file_cleanup,
                             apr_pool_cleanup_null);
}




Re: upload file crashes when using apr_pool_cleanup_register

Posted by Joe Schaefer <jo...@sunstarsys.com>.
Franky Braem <f....@skynet.be> writes:

> The following code crashes when I remove the comment before the
> apr_pool_cleanup_register (and put apr_file_close into comment
> ofcourse).

I *think* it's because apr_file_open registers a pool cleanup automatically.
So you don't need to register the cleanup, you wind up closing the file
twice when you do that.

-- 
Joe Schaefer