Blame SOURCES/libvirt-python-generator-Free-strings-after-libvirt_charPtrWrap.patch

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