|
|
b79911 |
From 0963646091f392aa04493f426306572bc8bfa41d Mon Sep 17 00:00:00 2001
|
|
|
b79911 |
Message-Id: <0963646091f392aa04493f426306572bc8bfa41d@dist-git>
|
|
|
b79911 |
From: Michal Privoznik <mprivozn@redhat.com>
|
|
|
b79911 |
Date: Tue, 16 Sep 2014 13:00:38 +0200
|
|
|
b79911 |
Subject: [PATCH] generator: Free strings after libvirt_charPtrWrap
|
|
|
b79911 |
|
|
|
b79911 |
https://bugzilla.redhat.com/show_bug.cgi?id=1140998
|
|
|
b79911 |
|
|
|
b79911 |
Up till bb3301ba the wrapper was freeing the passed strings for us.
|
|
|
b79911 |
However that changed after the commit. So now we don't free any
|
|
|
b79911 |
strings which results in memory leaks as reported upstream [1]:
|
|
|
b79911 |
|
|
|
b79911 |
==14265== 2,407 bytes in 1 blocks are definitely lost in loss record 1,457 of 1,550
|
|
|
b79911 |
==14265== at 0x4C2845D: malloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
|
|
|
b79911 |
==14265== by 0x5C46624: xdr_string (in /usr/lib64/libc-2.17.so)
|
|
|
b79911 |
==14265== by 0xCFD9FCD: xdr_remote_nonnull_string (remote_protocol.c:31)
|
|
|
b79911 |
==14265== by 0xCFDC2C8: xdr_remote_domain_get_xml_desc_ret (remote_protocol.c:1617)
|
|
|
b79911 |
==14265== by 0xCFF0811: virNetMessageDecodePayload (virnetmessage.c:407)
|
|
|
b79911 |
==14265== by 0xCFE68FB: virNetClientProgramCall (virnetclientprogram.c:379)
|
|
|
b79911 |
==14265== by 0xCFBE8B1: callFull.isra.2 (remote_driver.c:6578)
|
|
|
b79911 |
==14265== by 0xCFC7F04: remoteDomainGetXMLDesc (remote_driver.c:6600)
|
|
|
b79911 |
==14265== by 0xCF8167C: virDomainGetXMLDesc (libvirt.c:4380)
|
|
|
b79911 |
==14265== by 0xCC2C4DF: libvirt_virDomainGetXMLDesc (libvirt.c:1141)
|
|
|
b79911 |
==14265== by 0x4F12B93: PyEval_EvalFrameEx (in /usr/lib64/libpython2.7.so.1.0)
|
|
|
b79911 |
==14265== by 0x4F141AC: PyEval_EvalCodeEx (in /usr/lib64/libpython2.7.so.1.0)
|
|
|
b79911 |
|
|
|
b79911 |
The python documentation clearly advise us to call free() [2]. From
|
|
|
b79911 |
an example in their docs:
|
|
|
b79911 |
|
|
|
b79911 |
PyObject *res;
|
|
|
b79911 |
char *buf = (char *) malloc(BUFSIZ); /* for I/O */
|
|
|
b79911 |
|
|
|
b79911 |
if (buf == NULL)
|
|
|
b79911 |
return PyErr_NoMemory();
|
|
|
b79911 |
...Do some I/O operation involving buf...
|
|
|
b79911 |
res = PyString_FromString(buf);
|
|
|
b79911 |
free(buf); /* malloc'ed */
|
|
|
b79911 |
return res;
|
|
|
b79911 |
|
|
|
b79911 |
Moreover, instead of using VIR_FREE() (which we are not exporting),
|
|
|
b79911 |
I'll just go with bare free().
|
|
|
b79911 |
|
|
|
b79911 |
1: https://www.redhat.com/archives/libvir-list/2014-September/msg00736.html
|
|
|
b79911 |
2: https://docs.python.org/2/c-api/memory.html
|
|
|
b79911 |
|
|
|
b79911 |
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
|
|
|
b79911 |
(cherry picked from commit 4acfb169400497da2a82a849dc8aaa65f88ac6d1)
|
|
|
b79911 |
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
|
|
|
b79911 |
---
|
|
|
b79911 |
generator.py | 4 ++++
|
|
|
b79911 |
1 file changed, 4 insertions(+)
|
|
|
b79911 |
|
|
|
b79911 |
diff --git a/generator.py b/generator.py
|
|
|
b79911 |
index a798274..8ee046a 100755
|
|
|
b79911 |
--- a/generator.py
|
|
|
b79911 |
+++ b/generator.py
|
|
|
b79911 |
@@ -708,12 +708,16 @@ def print_function_wrapper(module, name, output, export, include):
|
|
|
b79911 |
else:
|
|
|
b79911 |
c_call = "\n c_retval = %s(%s);\n" % (name, c_call)
|
|
|
b79911 |
ret_convert = " py_retval = libvirt_%sWrap((%s) c_retval);\n" % (n,c)
|
|
|
b79911 |
+ if n == "charPtr":
|
|
|
b79911 |
+ ret_convert = ret_convert + " free(c_retval);\n"
|
|
|
b79911 |
ret_convert = ret_convert + " return py_retval;\n"
|
|
|
b79911 |
elif ret[0] in py_return_types:
|
|
|
b79911 |
(f, t, n, c) = py_return_types[ret[0]]
|
|
|
b79911 |
c_return = " %s c_retval;\n" % (ret[0])
|
|
|
b79911 |
c_call = "\n c_retval = %s(%s);\n" % (name, c_call)
|
|
|
b79911 |
ret_convert = " py_retval = libvirt_%sWrap((%s) c_retval);\n" % (n,c)
|
|
|
b79911 |
+ if n == "charPtr":
|
|
|
b79911 |
+ ret_convert = ret_convert + " free(c_retval);\n"
|
|
|
b79911 |
ret_convert = ret_convert + " return py_retval;\n"
|
|
|
b79911 |
else:
|
|
|
b79911 |
if ret[0] in skipped_types:
|
|
|
b79911 |
--
|
|
|
b79911 |
2.1.0
|
|
|
b79911 |
|