aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Burgess <aburgess@redhat.com>2025-08-24 21:09:40 +0100
committerAndrew Burgess <aburgess@redhat.com>2025-08-26 15:52:05 +0100
commit0a507079473c5a48be7affbc790c304ecb5ada3e (patch)
tree920bcba13cb2beeeb9f92ec25d440a86dc3859a2
parentaa2b674af942a4d9defa1a1d53707684dd393095 (diff)
downloadbinutils-0a507079473c5a48be7affbc790c304ecb5ada3e.zip
binutils-0a507079473c5a48be7affbc790c304ecb5ada3e.tar.gz
binutils-0a507079473c5a48be7affbc790c304ecb5ada3e.tar.bz2
gdb/python: fix an unlikely memory leak
I noticed a possible memory leak in gdbpy_create_ptid_object, in py-infthread.c. We create a Tuple, and hold the reference in a 'PyObject*' local. If we then fail to create any of the tuple contents we perform an early exit, returning nullptr, this will leak the Tuple object. Currently, we create the Tuple as the first action in the function, but we don't really need the tuple until the end of the function. In this commit I have: 1. Moved creation of the Tuple until the end of the function, just before we need it. 2. Stored the Tuple reference in a gdbpy_ref<>. This is not strictly needed any more, but is (I think) good practice as future changes to the function will not need to worry about releasing the Tuple object. 3. Taken the opportunity to replace a NULL with nullptr in this function. 4. Inlined the local variable declarations to the point of first use. There should be no user visible changes after this commit. No tests as I have no idea how to make gdb_py_object_from_longest (and friends) fail, and so trigger the memory leak. I suspect we'd never actually see this leak in the real world, but it doesn't hurt to clean these things up. Approved-By: Simon Marchi <simon.marchi@efficios.com>
-rw-r--r--gdb/python/py-infthread.c27
1 files changed, 11 insertions, 16 deletions
diff --git a/gdb/python/py-infthread.c b/gdb/python/py-infthread.c
index 4f1f8d4..d78c3a1 100644
--- a/gdb/python/py-infthread.c
+++ b/gdb/python/py-infthread.c
@@ -366,18 +366,9 @@ thpy_repr (PyObject *self)
PyObject *
gdbpy_create_ptid_object (ptid_t ptid)
{
- int pid;
- long lwp;
- ULONGEST tid;
- PyObject *ret;
-
- ret = PyTuple_New (3);
- if (!ret)
- return NULL;
-
- pid = ptid.pid ();
- lwp = ptid.lwp ();
- tid = ptid.tid ();
+ int pid = ptid.pid ();
+ long lwp = ptid.lwp ();
+ ULONGEST tid = ptid.tid ();
gdbpy_ref<> pid_obj = gdb_py_object_from_longest (pid);
if (pid_obj == nullptr)
@@ -389,12 +380,16 @@ gdbpy_create_ptid_object (ptid_t ptid)
if (tid_obj == nullptr)
return nullptr;
+ gdbpy_ref<> ret (PyTuple_New (3));
+ if (ret == nullptr)
+ return nullptr;
+
/* Note that these steal references, hence the use of 'release'. */
- PyTuple_SET_ITEM (ret, 0, pid_obj.release ());
- PyTuple_SET_ITEM (ret, 1, lwp_obj.release ());
- PyTuple_SET_ITEM (ret, 2, tid_obj.release ());
+ PyTuple_SET_ITEM (ret.get (), 0, pid_obj.release ());
+ PyTuple_SET_ITEM (ret.get (), 1, lwp_obj.release ());
+ PyTuple_SET_ITEM (ret.get (), 2, tid_obj.release ());
- return ret;
+ return ret.release ();
}
/* Implementation of gdb.selected_thread () -> gdb.InferiorThread.