Skip to contentSkip to conversation

libedac memory leak

DISCUSSION Ira W. Snyder 2 participants 2 messages Feb 10, 2010 EDAC-core

lore
Share & tools
lore
#0 lore raw

Hello all,

I've tried to use libedac in a project of mine, to read ECC errors present on a board. I have found that it leaks memory, because the edac_handle_destroy() function does not free the edac_handle that was malloc()ed.

A test program is inlined which will leak memory as long as it runs. I've added a hack to the code to show others how to work around the problem, but it isn't very nice that the library leaks memory.

----------------- cut here -----------------

/*
* libedac test program showing memory leaks
*
* Compile with: gcc -o test test.c -ledac
*
* Copyright (c) 2010 Ira W. Snyder <[email protected]>
*
* This file is licensed under the terms of the GNU General Public License
* version 2. This program is licensed "as is" without any warranty of any
* kind, whether express or implied.
*/

#include <stdio.h>
#include <stdlib.h>
#include <edac.h>

struct MonitorCarmaCommon {
	int eccErrors;
};

static int get_edac_ecc_errors(struct MonitorCarmaCommon *common)

{
	struct edac_totals totals;
	edac_handle *edac;
	int ret;

	edac = edac_handle_create();
	if (edac == NULL) {
		printf("unable to create edac handle\n");
		return -1;
	}

	ret = edac_handle_init(edac);
	if (ret < 0) {
		printf("unable to init edac handle\n");
		return -1;
	}

	ret = edac_error_totals(edac, &totals);
	if (ret < 0) {
		printf("unable to get edac totals\n");
		return -1;
	}

	common->eccErrors = 0;
	common->eccErrors += totals.ce_total;
	common->eccErrors += totals.ue_total;
	common->eccErrors += totals.pci_parity_total;

	edac_handle_destroy(edac);

#if 0
/*
* This is a quick workaround for the broken libedac library.
* Despite its claims, the edac_handle_destroy() function fails
* to free the memory for the opaque edac_handle structure, and
* therefore leaks memory. :(
*/

free(edac);

#endif
	return 0;
}

int main (int argc, char *argv[])

{
	struct MonitorCarmaCommon common;
	unsigned int count = 0;
	int ret;

	while (1) {
		ret = get_edac_ecc_errors(&common);
		if (ret < 0) {
			printf("iteration %d failed\n", count);
			return -1;
		}

		printf("iteration %d errors %d\n", count, common.eccErrors);
		count++;
	}

	return 0;
}

/* vim: set ts=8 sts=8 sw=8 noet tw=92: */

------------------------------------------------------------------------------
SOLARIS 10 is the OS for Data Centers - provides features such as DTrace, Predictive Self Healing and Award Winning ZFS. Get Solaris 10 NOW
http://p.sf.net/sfu/solaris-dev2dev

#1 lore raw

Hey Ira:

Sorry about this. Not sure how that slipped through all this time!

As you noted it is a one line fix, and will be in the next release of edac-utils.

(The edac-utils list is hosted off sf.net, btw
[email protected])

Thanks for reporting this!
mark

Quoted 100 lines

Hello all,

I've tried to use libedac in a project of mine, to read ECC errors present on a board. I have found that it leaks memory, because the edac_handle_destroy() function does not free the edac_handle that was malloc()ed.

A test program is inlined which will leak memory as long as it runs. I've added a hack to the code to show others how to work around the problem, but it isn't very nice that the library leaks memory.

----------------- cut here -----------------

/*
* libedac test program showing memory leaks
*
* Compile with: gcc -o test test.c -ledac
*
* Copyright (c) 2010 Ira W. Snyder <[email protected]>
*
* This file is licensed under the terms of the GNU General Public License
* version 2. This program is licensed "as is" without any warranty of any
* kind, whether express or implied.
*/

#include <stdio.h>
#include <stdlib.h>
#include <edac.h>

struct MonitorCarmaCommon {
	int eccErrors;
};

static int get_edac_ecc_errors(struct MonitorCarmaCommon *common)

{
	struct edac_totals totals;
	edac_handle *edac;
	int ret;

	edac = edac_handle_create();
	if (edac == NULL) {
		printf("unable to create edac handle\n");
		return -1;
	}

	ret = edac_handle_init(edac);
	if (ret < 0) {
		printf("unable to init edac handle\n");
		return -1;
	}

	ret = edac_error_totals(edac, &totals);
	if (ret < 0) {
		printf("unable to get edac totals\n");
		return -1;
	}

	common->eccErrors = 0;
	common->eccErrors += totals.ce_total;
	common->eccErrors += totals.ue_total;
	common->eccErrors += totals.pci_parity_total;

	edac_handle_destroy(edac);

#if 0
/*
* This is a quick workaround for the broken libedac library.
* Despite its claims, the edac_handle_destroy() function fails
* to free the memory for the opaque edac_handle structure, and
* therefore leaks memory. :(
*/

free(edac);

#endif
	return 0;
}

int main (int argc, char *argv[])

{
	struct MonitorCarmaCommon common;
	unsigned int count = 0;
	int ret;

	while (1) {
		ret = get_edac_ecc_errors(&common);
		if (ret < 0) {
			printf("iteration %d failed\n", count);
			return -1;
		}

		printf("iteration %d errors %d\n", count, common.eccErrors);
		count++;
	}

	return 0;
}

/* vim: set ts=8 sts=8 sw=8 noet tw=92: */

Quoted 10 lines

-----------------------------------------------------------------------------
-
SOLARIS 10 is the OS for Data Centers - provides features such as DTrace, Predictive Self Healing and Award Winning ZFS. Get Solaris 10 NOW
http://*p.sf.net/sfu/solaris-dev2dev
_______________________________________________
bluesmoke-devel mailing list [email protected]
https://*lists.sourceforge.net/lists/listinfo/bluesmoke-devel

------------------------------------------------------------------------------
SOLARIS 10 is the OS for Data Centers - provides features such as DTrace, Predictive Self Healing and Award Winning ZFS. Get Solaris 10 NOW
http://p.sf.net/sfu/solaris-dev2dev