I have found this leak

Алексей Ставцев <astavtsev-JGs/[email protected]> Sat, 24 Nov 2007 00:03:45 +0300
Newsgroups gmane.mail.libetpan.user
Message-ID <[email protected]>
 
 I have found this leak.
 
 I attached two little test:
 
 The first test has only one single part, and the second has 2 single parts with data. The first test works ok, but the second causes a memory leak. I used these functions in my server, and I have found that my program after some time uses too much memory.   I suppose that leak occurs in mailmime_part_write_driver function whis is situated in /src/low_level/mime/mailmime_write_generic.c .A function mailmime_part_write_driver on 779 string uses function mailmime_extract_boundry which allocates a memory for the char array "boundary" and doesn't free it. 
 
 test1.c - the 1'st test
 test2.c - the 2'nd test
 test1.debug.log - ccmalloc log for the first test
 test2.debug.log - ccmalloc log for the second test

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/

_______________________________________________
Libetpan-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/libetpan-users
test1.c (application/octet-stream, 4.2 KB)
#include <libetpan/libetpan.h>
#include <libetpan/charconv.h>
#include <string.h>
#include <time.h>
#include <stdlib.h>
#include <stdio.h>

#define DEST_CHARSET "iso-8859-1"

static struct mailmime * build_body_text(char * text)
{
  struct mailmime_fields * mime_fields;
  struct mailmime * mime_sub;
  struct mailmime_content * content;
  struct mailmime_parameter * param;
  int r;

  /* text/plain part */

  mime_fields = mailmime_fields_new_encoding(MAILMIME_MECHANISM_8BIT);
  if (mime_fields == NULL) {
    goto err;
  }

  content = mailmime_content_new_with_str("text/plain");
  if (content == NULL) {
    goto free_fields;
  }

  param = mailmime_param_new_with_data("charset", DEST_CHARSET);
  if (param == NULL) {
    goto free_content;
  }

  r = clist_append(content->ct_parameters, param);
  if (r < 0) {
    mailmime_parameter_free(param);
    goto free_content;
  }

  mime_sub = mailmime_new_empty(content, mime_fields);
  if (mime_sub == NULL) {
    goto free_content;
  }

  r = mailmime_set_body_text(mime_sub, text, strlen(text));
  if (r != MAILIMF_NO_ERROR) {
    goto free_mime;
  }

  return mime_sub;

 free_mime:
  mailmime_free(mime_sub);
  goto err;
 free_content:
  mailmime_content_free(content);
 free_fields:
  mailmime_fields_free(mime_fields);
 err:
  return NULL;
}


static struct mailmime * build_body_file(char* filetype ,char * filename)
{
	struct mailmime_fields * mime_fields;
	struct mailmime * mime_sub;
	struct mailmime_content * content;
	struct mailmime_parameter * param;

	char *temp_filename=NULL;
	
	int r;

	temp_filename = strdup(filename);
	/* text/plain part */


	mime_fields =
		mailmime_fields_new_filename(MAILMIME_DISPOSITION_TYPE_ATTACHMENT,
									 temp_filename, MAILMIME_MECHANISM_BASE64);
	if (mime_fields == NULL)
		goto err;

	content = mailmime_content_new_with_str(filetype);
	if (content == NULL) {
		goto free_fields;
	}

	param = mailmime_param_new_with_data("charset", DEST_CHARSET);
	if (param == NULL) {
		goto free_content;
	}

	r = clist_append(content->ct_parameters, param);
	if (r < 0) {
		mailmime_parameter_free(param);
		goto free_content;
	}

	mime_sub = mailmime_new_empty(content, mime_fields);
	if (mime_sub == NULL) {
		mailmime_parameter_free(param);
		goto free_content;
	}
	
	temp_filename = strdup(filename);
	
	r = mailmime_set_body_file(mime_sub, temp_filename);
	if (r != MAILIMF_NO_ERROR) {
		goto free_mime;
	}

	return mime_sub;

free_mime:
	mailmime_free(mime_sub);
free_content:
	mailmime_content_free(content);
free_fields:
	mailmime_fields_free(mime_fields);
err:
	return NULL;
}


static struct mailmime * build_message(struct mailimf_fields * fields)
{
	struct mailmime * mime;

	/* message */

	mime = mailmime_new_message_data(NULL);
	if (mime == NULL) {
		goto err;
	}

	mailmime_set_imf_fields(mime, fields);

	return mime;

err:
	return NULL;
}

int main()
{

	int i;
	int r;

	struct mailimf_mailbox_list * from;
	struct mailimf_address_list * to;
	char * subject;
	struct mailmime *message;
	struct mailmime *text_part;
	struct mailmime *file_part;
	

	struct mailimf_fields * new_fields;
	
	FILE *f;

	int col;
	
	subject = strdup("test subject");
	if (subject == NULL) {
		goto err;
	}

	from = mailimf_mailbox_list_new_empty();
	if (from == NULL) {
		goto free_subject;
	}

	r = mailimf_mailbox_list_add_parse(from,
									   "DINH Viet Hoa <[email protected]>");
	if (r != MAILIMF_NO_ERROR) {
		goto free_from;
	}

	/* to field */

	to = mailimf_address_list_new_empty();
	if (to == NULL) {
		goto free_from;
	}

	r = mailimf_address_list_add_parse(to,
									   "Paul <[email protected]>");
	if (r != MAILIMF_NO_ERROR) {
		goto free_to;
	}

	new_fields = mailimf_fields_new_with_data(from /* from */,
				 NULL /* sender */, NULL /* reply-to */,
				 to, NULL /* cc */, NULL /* bcc */, NULL /* in-reply-to */,
				 NULL /* references */,
				 subject);

	message = build_message(new_fields);
	

	 
	file_part = 	build_body_file("text/plain", "test1.c");
	r=mailmime_smart_add_part(message, file_part);

	
	f = fopen(/*fname*/"for_test","w+");
	col = 0;
	mailmime_write(f, &col, message);
	fclose(f);

	mailmime_free(message);

	return 0;

free_to:
	mailimf_address_list_free(to);
free_from:
	mailimf_mailbox_list_free(from);
free_subject:
	free(subject);
err:

	return 0;
}
test1.debug.log (application/octet-stream, 3.1 KB)
.--------------------------------------------------------------------------.
|================ ccmalloc-0.4.0 (C) 1997-2003 Armin Biere ================|
+--------------------------------------------------------------------------+
| executable       = /home/new/test_mod5/src/main                          |
| startup file     = ~/.ccmalloc                                           |
| log file         = /root/debug.log.20073                                 |
| start time       = Tue Nov 20 11:54:17 2007                              |
| operating system = Linux 2.4.32-vniins42smp i686 on TATOOINE_2_core      |
+--------------------------------------------------------------------------+
| only-count        = 0            keep-deallocated-data = 1               |
| check-interval    = 0            check-free-space      = 0               |
| check-start       = 0            file-info             = 1               |
| chain-length      = 0            additional-line       = 1               |
| check-underwrites = 1            print-addresses       = 1               |
| check-overwrites  = 1            print-on-one-line     = 0               |
| sort-by-wasted    = 1            sort-by-size          = 1               |
| # only-log-chain  = 0            continue              = 1               |
| # dont-log-chain  = 0            statistics            = 1               |
| debug             = 1            library-chains        = 0               |
| load-dynlibs      = 1            align-8-byte          = 0               |
| only-wasting-alloc= 1                                                    |
`--------------------------------------------------------------------------'

.---------------.
|ccmalloc report|
=======================================================
| total # of|   allocated | deallocated |     garbage |
+-----------+-------------+-------------+-------------+
|      bytes|        1109 |        1109 |           0 |
+-----------+-------------+-------------+-------------+
|allocations|          85 |          85 |           0 |
+-----------------------------------------------------+
| number of checks: 1                                 |
| number of counts: 170                               |
| retrieving function names for addresses ... done.   |
| reading file info from gdb ... done.                |
| sorting by number of not reclaimed bytes ... done.  |
| number of call chains: 81                           |
| number of ignored call chains: 0                    |
| number of reported call chains: 81                  |
| number of internal call chains: 81                  |
| number of library call chains: 2                    |
=======================================================
|
`------------------------------------------------------
[symtab: elements=162 size=251 resizes=1 collisions=36 maxchain=4]
[chaintab: elements=1528 size=2039 resizes=4 collisions=446 maxchain=4]
[addrs: elements=159 size=251 resizes=1 collisions=38 maxchain=4]
[strings: elements=238 size=509 resizes=2 collisions=59 maxchain=4]
[internal: 4471 allocations, 4459 deallocations, 84836 bytes allocated]
test2.c (application/octet-stream, 4.3 KB)
#include <libetpan/libetpan.h>
#include <libetpan/charconv.h>
#include <string.h>
#include <time.h>
#include <stdlib.h>
#include <stdio.h>

#define DEST_CHARSET "iso-8859-1"

static struct mailmime * build_body_text(char * text)
{
  struct mailmime_fields * mime_fields;
  struct mailmime * mime_sub;
  struct mailmime_content * content;
  struct mailmime_parameter * param;
  int r;

  /* text/plain part */

  mime_fields = mailmime_fields_new_encoding(MAILMIME_MECHANISM_8BIT);
  if (mime_fields == NULL) {
    goto err;
  }

  content = mailmime_content_new_with_str("text/plain");
  if (content == NULL) {
    goto free_fields;
  }

  param = mailmime_param_new_with_data("charset", DEST_CHARSET);
  if (param == NULL) {
    goto free_content;
  }

  r = clist_append(content->ct_parameters, param);
  if (r < 0) {
    mailmime_parameter_free(param);
    goto free_content;
  }

  mime_sub = mailmime_new_empty(content, mime_fields);
  if (mime_sub == NULL) {
    goto free_content;
  }

  r = mailmime_set_body_text(mime_sub, text, strlen(text));
  if (r != MAILIMF_NO_ERROR) {
    goto free_mime;
  }

  return mime_sub;

 free_mime:
  mailmime_free(mime_sub);
  goto err;
 free_content:
  mailmime_content_free(content);
 free_fields:
  mailmime_fields_free(mime_fields);
 err:
  return NULL;
}


static struct mailmime * build_body_file(char* filetype ,char * filename)
{
	struct mailmime_fields * mime_fields;
	struct mailmime * mime_sub;
	struct mailmime_content * content;
	struct mailmime_parameter * param;

	char *temp_filename=NULL;
	
	int r;

	temp_filename = strdup(filename);
	/* text/plain part */


	mime_fields =
		mailmime_fields_new_filename(MAILMIME_DISPOSITION_TYPE_ATTACHMENT,
									 temp_filename, MAILMIME_MECHANISM_BASE64);
	if (mime_fields == NULL)
		goto err;

	content = mailmime_content_new_with_str(filetype);
	if (content == NULL) {
		goto free_fields;
	}

	param = mailmime_param_new_with_data("charset", DEST_CHARSET);
	if (param == NULL) {
		goto free_content;
	}

	r = clist_append(content->ct_parameters, param);
	if (r < 0) {
		mailmime_parameter_free(param);
		goto free_content;
	}

	mime_sub = mailmime_new_empty(content, mime_fields);
	if (mime_sub == NULL) {
		mailmime_parameter_free(param);
		goto free_content;
	}
	
	temp_filename = strdup(filename);
	
	r = mailmime_set_body_file(mime_sub, temp_filename);
	if (r != MAILIMF_NO_ERROR) {
		goto free_mime;
	}

	return mime_sub;

free_mime:
	mailmime_free(mime_sub);
free_content:
	mailmime_content_free(content);
free_fields:
	mailmime_fields_free(mime_fields);
err:
	return NULL;
}


static struct mailmime * build_message(struct mailimf_fields * fields)
{
	struct mailmime * mime;

	/* message */

	mime = mailmime_new_message_data(NULL);
	if (mime == NULL) {
		goto err;
	}

	mailmime_set_imf_fields(mime, fields);

	return mime;

err:
	return NULL;
}

int main()
{

	int i;
	int r;

	struct mailimf_mailbox_list * from;
	struct mailimf_address_list * to;
	char * subject;
	struct mailmime *message;
	struct mailmime *text_part;
	struct mailmime *file_part;
	

	struct mailimf_fields * new_fields;
	
	FILE *f;

	int col;
	
	subject = strdup("test subject");
	if (subject == NULL) {
		goto err;
	}

	from = mailimf_mailbox_list_new_empty();
	if (from == NULL) {
		goto free_subject;
	}

	r = mailimf_mailbox_list_add_parse(from,
									   "DINH Viet Hoa <[email protected]>");
	if (r != MAILIMF_NO_ERROR) {
		goto free_from;
	}

	/* to field */

	to = mailimf_address_list_new_empty();
	if (to == NULL) {
		goto free_from;
	}

	r = mailimf_address_list_add_parse(to,
									   "Paul <[email protected]>");
	if (r != MAILIMF_NO_ERROR) {
		goto free_to;
	}

	new_fields = mailimf_fields_new_with_data(from /* from */,
				 NULL /* sender */, NULL /* reply-to */,
				 to, NULL /* cc */, NULL /* bcc */, NULL /* in-reply-to */,
				 NULL /* references */,
				 subject);

	message = build_message(new_fields);
	

	 
	file_part = 	build_body_file("text/plain", "test1.c");
	r=mailmime_smart_add_part(message, file_part);
	file_part = 	build_body_file("text/plain", "test2.c");
	r=mailmime_smart_add_part(message, file_part);
	
	f = fopen(/*fname*/"for_test","w+");
	col = 0;
	mailmime_write(f, &col, message);
	fclose(f);

	mailmime_free(message);

	return 0;

free_to:
	mailimf_address_list_free(to);
free_from:
	mailimf_mailbox_list_free(from);
free_subject:
	free(subject);
err:

	return 0;
}
test2.debug.log (application/octet-stream, 4.1 KB)
.--------------------------------------------------------------------------.
|================ ccmalloc-0.4.0 (C) 1997-2003 Armin Biere ================|
+--------------------------------------------------------------------------+
| executable       = /home/new/test_mod5/src/test1                         |
| startup file     = ~/.ccmalloc                                           |
| log file         = /root/debug.log.21452                                 |
| start time       = Tue Nov 20 12:01:21 2007                              |
| operating system = Linux 2.4.32-vniins42smp i686 on TATOOINE_2_core      |
+--------------------------------------------------------------------------+
| only-count        = 0            keep-deallocated-data = 1               |
| check-interval    = 0            check-free-space      = 0               |
| check-start       = 0            file-info             = 1               |
| chain-length      = 0            additional-line       = 1               |
| check-underwrites = 1            print-addresses       = 1               |
| check-overwrites  = 1            print-on-one-line     = 0               |
| sort-by-wasted    = 1            sort-by-size          = 1               |
| # only-log-chain  = 0            continue              = 1               |
| # dont-log-chain  = 0            statistics            = 1               |
| debug             = 1            library-chains        = 0               |
| load-dynlibs      = 1            align-8-byte          = 0               |
| only-wasting-alloc= 1                                                    |
`--------------------------------------------------------------------------'

.---------------.
|ccmalloc report|
=======================================================
| total # of|   allocated | deallocated |     garbage |
+-----------+-------------+-------------+-------------+
|      bytes|        1637 |        1614 |          23 |
+-----------+-------------+-------------+-------------+
|allocations|         129 |         128 |           1 |
+-----------------------------------------------------+
| number of checks: 1                                 |
| number of counts: 257                               |
| retrieving function names for addresses ... done.   |
| reading file info from gdb ... done.                |
| sorting by number of not reclaimed bytes ... done.  |
| number of call chains: 122                          |
| number of ignored call chains: 0                    |
| number of reported call chains: 122                 |
| number of internal call chains: 122                 |
| number of library call chains: 2                    |
=======================================================
|
*100.0% = 23 Bytes of garbage allocated in 1 allocation
|       | 1 allocated (23 Bytes = 1.4% of total allocated)
|       |
|       @ [ 
|       |   +0x0809e30c
|       | ]
|       |
|       |       0x???????? in <???>
|       |
|       |       0x3d59454b in <???>
|       |
|       |       0xbffff9c7 in <???>
|       |
|       |       0x0809f000 in <???>
|       |
|       |       0x400f9f69 in <__libc_start_main>
|       |
|       |       0x0804aa39 in <main>
|       |
|       |       0x40080317 in <mailmime_write>
|       |
|       |       0x4008012d in <mailmime_write_file>
|       |
|       |       0x40083e85 in <mailmime_write_driver>
|       |
|       |       0x40083d11 in <mailmime_part_write_driver>
|       |
|       |       0x40083e19 in <mailmime_sub_write_driver>
|       |
|       |       0x40083872 in <mailmime_part_write_driver>
|       |
|       |       0x4007cfc9 in <mailmime_extract_boundary>
|       |
|       `-----> 0x08058063 in <malloc>
|                          at src/wrapper.c:322
|        
`------------------------------------------------------
[symtab: elements=307 size=509 resizes=2 collisions=68 maxchain=3]
[chaintab: elements=2033 size=4093 resizes=5 collisions=436 maxchain=5]
[addrs: elements=188 size=251 resizes=1 collisions=54 maxchain=4]
[strings: elements=388 size=509 resizes=2 collisions=113 maxchain=4]
[internal: 6259 allocations, 6248 deallocations, 129528 bytes allocated]