[pcp] Patch for Python's pmExtractValue Function
Tom Yearke
tyearke at buffalo.edu
Thu Mar 27 08:14:49 CDT 2014
Hi all,
In developing some scripts using the Python bindings for PCP, I
discovered the scripts were leaking memory whenever they extracted
string values from pmResult objects. As the man page for pmExtractValue
states, the user is responsible for freeing strings returned by the
function, but freeing memory was not something I expected to do in
Python beyond pmResult objects, which have an explicit function for
doing so. This was a simple enough fix to make on the script side, but
I'd like to suggest that the issue be taken care of on the API side to
prevent other developers from making the same mistake.
Part of my confusion stemmed from the fact that many Python functions
return either Python objects or C objects allocated in Python code, both
of which are subject to Python's memory management scheme. In the case
of pmExtractValue, while the returned pmAtomValue objects are allocated
in the Python function, any strings returned inside those objects are
allocated in the C function. This means that the former are deallocated
automatically when there are no more Python references to them, while
the latter will stay in memory until manually freed.
I've attached a patch based on 3.9.1 for one possible approach to the
problem, which involves performing an additional step in the Python
pmExtractValue function after the C function returns. A string returned
by the C function will be copied into Python memory and freed from C
memory before the Python function returns. This will allow both the
returned pmAtomValue object and its string to be automatically freed
when there are no more Python references.
Thanks for your consideration! Hope this helps!
Tom Yearke
-------------- next part --------------
From 9d14cc4234e100ba14606d30975508934f069255 Mon Sep 17 00:00:00 2001
From: Tom Yearke <tyearke at buffalo.edu>
Date: Wed, 26 Mar 2014 15:44:26 -0400
Subject: [PATCH] python/pmapi - simplify memory management for users in
pmExtractValue
---
src/python/pcp/pmapi.py | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/src/python/pcp/pmapi.py b/src/python/pcp/pmapi.py
index fd67a9e..18d136e 100644
--- a/src/python/pcp/pmapi.py
+++ b/src/python/pcp/pmapi.py
@@ -1333,6 +1333,12 @@ class pmContext(object):
byref(outAtom), outtype)
if status < 0:
raise pmErr, status
+ # If value was allocated in C memory, copy to Python memory and free C.
+ if outtype == c_api.PM_TYPE_STRING:
+ c_char_pointer_address = outAtom.vp
+ python_char_array = create_string_buffer(outAtom.cp)
+ outAtom.cp = cast(python_char_array, c_char_p)
+ LIBC.free(c_char_pointer_address)
return outAtom
@staticmethod
--
1.8.4.2
More information about the pcp
mailing list