[Lldb-commits] [PATCH] D13617: Fix ref-counting of Python objects
Zachary Turner via lldb-commits
lldb-commits at lists.llvm.org
Fri Oct 9 19:41:45 PDT 2015
zturner created this revision.
zturner added a reviewer: clayborg.
zturner added a subscriber: lldb-commits.
PythonObjects were being incorrectly ref-counted. This problem was pervasive throughout the codebase, leading to an unknown number of memory leaks and potentially use-after-free.
The issue stems from the fact that Python native methods can either return "borrowed" references or "owned" references. For the former category, you *must* incref it prior to decrefing it. And for the latter category, you should not incref it before decrefing it. This is mostly an issue when a Python C API method returns a `PyObject` to you, but it can also happen with a method accepts a `PyObject`. Notably, this happens in `PyList_SetItem`, which is documented to "steal" the reference that you give it. So if you pass something to `PyList_SetItem`, you cannot hold onto it unless you incref it first. But since this is one of only two exceptions in the entire API, it's confusing and difficult to remember.
Our `PythonObject` class was indiscriminantely increfing every object it received, which means that if you passed it an owned reference, you now have a dangling reference since owned references should not be increfed. We were doing this in quite a few places.
There was also a fair amount of manual increfing and decrefing prevalent throughout the codebase, which is easy to get wrong.
This patch solves the problem by first changing the name of `PythonObject` to `PyRef` (so that it is clear from the name what this actually is), and then making any construction of a `PyRef` from a `PyObject` take a flag which indicates whether it is an owned reference or a borrowed reference. There is no way to construct a `PyRef` without this flag, and it does not offer a default value, forcing the user to make an explicit decision every time.
All manual uses of `PyObject` have been cleaned up throughout the codebase and replaced with `PyRef`.
http://reviews.llvm.org/D13617
Files:
source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h
source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h
unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D13617.37018.patch
Type: text/x-patch
Size: 70656 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/lldb-commits/attachments/20151010/7acd0ba4/attachment-0001.bin>
More information about the lldb-commits
mailing list