[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