[PATCH 24/28] introduce gdb_pymodule_addobject

Tom Tromey
2013-04-19T14:42:18Z

The checker pointed out that this common idiom in gdb is wrong:

- Py_INCREF (&arch_object_type);
- return PyModule_AddObject (gdb_module, "Architecture",
- (PyObject *) &arch_object_type);

This is buggy because if PyModule_AddObject fails, then the reference
will not be stolen. So, the object will be leaked.

This isn't extremely important, as such failures probably won't
actually happen. Nevertheless it is better to be clean; and also
remove false reports from the checker.

This patch does so by introducing a wrapper function for
PyModule_AddObject that doesn't steal a reference.

* python/py-arch.c (gdbpy_initialize_arch): Use
gdb_pymodule_addobject.
* python/py-block.c (gdbpy_initialize_blocks): Use
gdb_pymodule_addobject.
* python/py-breakpoint.c (gdbpy_initialize_breakpoints): Use
gdb_pymodule_addobject.
* python/py-cmd.c (gdbpy_initialize_breakpoints): Use
gdb_pymodule_addobject.
* python/py-event.c (gdbpy_initialize_event_generic): Use
gdb_pymodule_addobject.
* python/py-evtregistry.c (gdbpy_initialize_eventregistry): Use
gdb_pymodule_addobject.
* python/py-evts.c (add_new_registry): Use
gdb_pymodule_addobject.
(gdbpy_initialize_py_events): Likewise.
* python/py-finishbreakpoint.c
(gdbpy_initialize_finishbreakpoints): Use
gdb_pymodule_addobject.
* python/py-frame.c (gdbpy_initialize_frames): Use
gdb_pymodule_addobject.
* python/py-function.c (gdbpy_initialize_functions): Use
gdb_pymodule_addobject.
* python/py-inferior.c (gdbpy_initialize_inferior): Use
gdb_pymodule_addobject.
* python/py-infthread.c (gdbpy_initialize_thread): Use
gdb_pymodule_addobject.
* python/py-objfile.c (gdbpy_initialize_objfile): Use
gdb_pymodule_addobject.
* python/py-param.c (gdbpy_initialize_parameters): Use
gdb_pymodule_addobject.
* python/py-progspace.c (gdbpy_initialize_pspace): Use
gdb_pymodule_addobject.
* python/py-symbol.c (gdbpy_initialize_symbols): Use
gdb_pymodule_addobject.
* python/py-symtab.c (gdbpy_initialize_symtabs): Use
gdb_pymodule_addobject.
* python/py-type.c (gdbpy_initialize_types): Use
gdb_pymodule_addobject.
* python/py-utils.c (gdb_pymodule_addobject): New function.
* python/py-value.c (gdbpy_initialize_values): Use
gdb_pymodule_addobject.
* python/python-internal.h (gdb_pymodule_addobject): Declare.
* python/python.c (_initialize_python): Use
gdb_pymodule_addobject.
---
gdb/python/py-arch.c | 5 ++---
gdb/python/py-block.c | 10 ++++------
gdb/python/py-breakpoint.c | 5 ++---
gdb/python/py-cmd.c | 5 ++---
gdb/python/py-event.c | 10 +---------
gdb/python/py-evtregistry.c | 5 ++---
gdb/python/py-evts.c | 23 +++++++++--------------
gdb/python/py-finishbreakpoint.c | 5 ++---
gdb/python/py-frame.c | 5 ++---
gdb/python/py-function.c | 5 ++---
gdb/python/py-inferior.c | 10 ++++------
gdb/python/py-infthread.c | 5 ++---
gdb/python/py-objfile.c | 5 ++---
gdb/python/py-param.c | 5 ++---
gdb/python/py-progspace.c | 5 ++---
gdb/python/py-symbol.c | 5 ++---
gdb/python/py-symtab.c | 10 ++++------
gdb/python/py-type.c | 15 ++++++---------
gdb/python/py-utils.c | 15 +++++++++++++++
gdb/python/py-value.c | 5 ++---
gdb/python/python-internal.h | 4 ++++
gdb/python/python.c | 11 ++++++-----
22 files changed, 79 insertions(+), 94 deletions(-)

diff --git a/gdb/python/py-arch.c b/gdb/python/py-arch.c
index 7920fbb..7098a8a 100644
--- a/gdb/python/py-arch.c
+++ b/gdb/python/py-arch.c
@@ -239,9 +239,8 @@ gdbpy_initialize_arch (void)
if (PyType_Ready (&arch_object_type) < 0)
return -1;

- Py_INCREF (&arch_object_type);
- return PyModule_AddObject (gdb_module, "Architecture",
- (PyObject *) &arch_object_type);
+ return gdb_pymodule_addobject (gdb_module, "Architecture",
+ (PyObject *) &arch_object_type);
}

static PyMethodDef arch_object_methods [] = {
diff --git a/gdb/python/py-block.c b/gdb/python/py-block.c
index f2d9000..c74ac2c 100644
--- a/gdb/python/py-block.c
+++ b/gdb/python/py-block.c
@@ -442,14 +442,12 @@ gdbpy_initialize_blocks (void)
blpy_objfile_data_key
= register_objfile_data_with_cleanup (NULL, del_objfile_blocks);

- Py_INCREF (&block_object_type);
- if (PyModule_AddObject (gdb_module, "Block",
- (PyObject *) &block_object_type) < 0)
+ if (gdb_pymodule_addobject (gdb_module, "Block",
+ (PyObject *) &block_object_type) < 0)
return -1;

- Py_INCREF (&block_syms_iterator_object_type);
- return PyModule_AddObject (gdb_module, "BlockIterator",
- (PyObject *) &block_syms_iterator_object_type);
+ return gdb_pymodule_addobject (gdb_module, "BlockIterator",
+ (PyObject *) &block_syms_iterator_object_type);
}

\f
diff --git a/gdb/python/py-breakpoint.c b/gdb/python/py-breakpoint.c
index b1b6e93..d958f30 100644
--- a/gdb/python/py-breakpoint.c
+++ b/gdb/python/py-breakpoint.c
@@ -868,9 +868,8 @@ gdbpy_initialize_breakpoints (void)
if (PyType_Ready (&breakpoint_object_type) < 0)
return -1;

- Py_INCREF (&breakpoint_object_type);
- if (PyModule_AddObject (gdb_module, "Breakpoint",
- (PyObject *) &breakpoint_object_type) < 0)
+ if (gdb_pymodule_addobject (gdb_module, "Breakpoint",
+ (PyObject *) &breakpoint_object_type) < 0)
return -1;

observer_attach_breakpoint_created (gdbpy_breakpoint_created);
diff --git a/gdb/python/py-cmd.c b/gdb/python/py-cmd.c
index 22eff25..8b6252e 100644
--- a/gdb/python/py-cmd.c
+++ b/gdb/python/py-cmd.c
@@ -600,9 +600,8 @@ gdbpy_initialize_commands (void)
return -1;
}

- Py_INCREF (&cmdpy_object_type);
- if (PyModule_AddObject (gdb_module, "Command",
- (PyObject *) &cmdpy_object_type) < 0)
+ if (gdb_pymodule_addobject (gdb_module, "Command",
+ (PyObject *) &cmdpy_object_type) < 0)
return -1;

invoke_cst = PyString_FromString ("invoke");
diff --git a/gdb/python/py-event.c b/gdb/python/py-event.c
index 04f33ab..9f5134d 100644
--- a/gdb/python/py-event.c
+++ b/gdb/python/py-event.c
@@ -78,15 +78,7 @@ gdbpy_initialize_event_generic (PyTypeObject *type,
if (PyType_Ready (type) < 0)
return -1;

- Py_INCREF (type);
- if (PyModule_AddObject (gdb_module, name, (PyObject *) type) < 0)
- goto fail;
-
- return 0;
-
- fail:
- Py_XDECREF (type);
- return -1;
+ return gdb_pymodule_addobject (gdb_module, name, (PyObject *) type);
}

diff --git a/gdb/python/py-evtregistry.c b/gdb/python/py-evtregistry.c
index d7cbe64..0eeb853 100644
--- a/gdb/python/py-evtregistry.c
+++ b/gdb/python/py-evtregistry.c
@@ -112,9 +112,8 @@ gdbpy_initialize_eventregistry (void)
if (PyType_Ready (&eventregistry_object_type) < 0)
return -1;

- Py_INCREF (&eventregistry_object_type);
- return PyModule_AddObject (gdb_module, "EventRegistry",
- (PyObject *) &eventregistry_object_type);
+ return gdb_pymodule_addobject (gdb_module, "EventRegistry",
+ (PyObject *) &eventregistry_object_type);
}

/* Retern the number of listeners currently connected to this
diff --git a/gdb/python/py-evts.c b/gdb/python/py-evts.c
index 4828bda..971c520 100644
--- a/gdb/python/py-evts.c
+++ b/gdb/python/py-evts.c
@@ -40,21 +40,16 @@ static struct PyModuleDef EventModuleDef =
static int CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION
add_new_registry (eventregistry_object **registryp, char *name)
{
+ int result;
+
*registryp = create_eventregistry_object ();

if (*registryp == NULL)
- goto fail;
-
- if (PyModule_AddObject (gdb_py_events.module,
- name,
- (PyObject *)(*registryp)) < 0)
- goto fail;
-
- return 0;
+ return -1;

- fail:
- Py_XDECREF (*registryp);
- return -1;
+ return gdb_pymodule_addobject (gdb_py_events.module,
+ name,
+ (PyObject *)(*registryp));
}

int
@@ -81,9 +76,9 @@ gdbpy_initialize_py_events (void)
if (add_new_registry (&gdb_py_events.new_objfile, "new_objfile") < 0)
return -1;

- if (PyModule_AddObject (gdb_module,
- "events",
- (PyObject *) gdb_py_events.module) < 0)
+ if (gdb_pymodule_addobject (gdb_module,
+ "events",
+ (PyObject *) gdb_py_events.module) < 0)
return -1;

return 0;
diff --git a/gdb/python/py-finishbreakpoint.c b/gdb/python/py-finishbreakpoint.c
index 5fd1f4b..ca20439 100644
--- a/gdb/python/py-finishbreakpoint.c
+++ b/gdb/python/py-finishbreakpoint.c
@@ -413,9 +413,8 @@ gdbpy_initialize_finishbreakpoints (void)
if (PyType_Ready (&finish_breakpoint_object_type) < 0)
return -1;

- Py_INCREF (&finish_breakpoint_object_type);
- if (PyModule_AddObject (gdb_module, "FinishBreakpoint",
- (PyObject *) &finish_breakpoint_object_type) < 0)
+ if (gdb_pymodule_addobject (gdb_module, "FinishBreakpoint",
+ (PyObject *) &finish_breakpoint_object_type) < 0)
return -1;

observer_attach_normal_stop (bpfinishpy_handle_stop);
diff --git a/gdb/python/py-frame.c b/gdb/python/py-frame.c
index 75e84ac..435eb50 100644
--- a/gdb/python/py-frame.c
+++ b/gdb/python/py-frame.c
@@ -642,9 +642,8 @@ gdbpy_initialize_frames (void)
#undef SET
#undef FIRST_ERROR

- Py_INCREF (&frame_object_type);
- return PyModule_AddObject (gdb_module, "Frame",
- (PyObject *) &frame_object_type);
+ return gdb_pymodule_addobject (gdb_module, "Frame",
+ (PyObject *) &frame_object_type);
}

\f
diff --git a/gdb/python/py-function.c b/gdb/python/py-function.c
index 57cdfae..fc0d4dd 100644
--- a/gdb/python/py-function.c
+++ b/gdb/python/py-function.c
@@ -207,9 +207,8 @@ gdbpy_initialize_functions (void)
if (PyType_Ready (&fnpy_object_type) < 0)
return -1;

- Py_INCREF (&fnpy_object_type);
- return PyModule_AddObject (gdb_module, "Function",
- (PyObject *) &fnpy_object_type);
+ return gdb_pymodule_addobject (gdb_module, "Function",
+ (PyObject *) &fnpy_object_type);
}

\f
diff --git a/gdb/python/py-inferior.c b/gdb/python/py-inferior.c
index 1ab58e6..a603f19 100644
--- a/gdb/python/py-inferior.c
+++ b/gdb/python/py-inferior.c
@@ -789,9 +789,8 @@ gdbpy_initialize_inferior (void)
if (PyType_Ready (&inferior_object_type) < 0)
return -1;

- Py_INCREF (&inferior_object_type);
- if (PyModule_AddObject (gdb_module, "Inferior",
- (PyObject *) &inferior_object_type) < 0)
+ if (gdb_pymodule_addobject (gdb_module, "Inferior",
+ (PyObject *) &inferior_object_type) < 0)
return -1;

infpy_inf_data_key =
@@ -808,9 +807,8 @@ gdbpy_initialize_inferior (void)
if (PyType_Ready (&membuf_object_type) < 0)
return -1;

- Py_INCREF (&membuf_object_type);
- return PyModule_AddObject (gdb_module, "Membuf", (PyObject *)
- &membuf_object_type);
+ return gdb_pymodule_addobject (gdb_module, "Membuf", (PyObject *)
+ &membuf_object_type);
}

static PyGetSetDef inferior_object_getset[] =
diff --git a/gdb/python/py-infthread.c b/gdb/python/py-infthread.c
index 7a5f262..d46f573 100644
--- a/gdb/python/py-infthread.c
+++ b/gdb/python/py-infthread.c
@@ -261,9 +261,8 @@ gdbpy_initialize_thread (void)
if (PyType_Ready (&thread_object_type) < 0)
return -1;

- Py_INCREF (&thread_object_type);
- return PyModule_AddObject (gdb_module, "InferiorThread",
- (PyObject *) &thread_object_type);
+ return gdb_pymodule_addobject (gdb_module, "InferiorThread",
+ (PyObject *) &thread_object_type);
}

diff --git a/gdb/python/py-objfile.c b/gdb/python/py-objfile.c
index 53f8829..7a257ca 100644
--- a/gdb/python/py-objfile.c
+++ b/gdb/python/py-objfile.c
@@ -249,9 +249,8 @@ gdbpy_initialize_objfile (void)
if (PyType_Ready (&objfile_object_type) < 0)
return -1;

- Py_INCREF (&objfile_object_type);
- return PyModule_AddObject (gdb_module, "Objfile",
- (PyObject *) &objfile_object_type);
+ return gdb_pymodule_addobject (gdb_module, "Objfile",
+ (PyObject *) &objfile_object_type);
}

\f
diff --git a/gdb/python/py-param.c b/gdb/python/py-param.c
index a81ab66..9f56c3a 100644
--- a/gdb/python/py-param.c
+++ b/gdb/python/py-param.c
@@ -774,9 +774,8 @@ gdbpy_initialize_parameters (void)
return -1;
}

- Py_INCREF (&parmpy_object_type);
- return PyModule_AddObject (gdb_module, "Parameter",
- (PyObject *) &parmpy_object_type);
+ return gdb_pymodule_addobject (gdb_module, "Parameter",
+ (PyObject *) &parmpy_object_type);
}

\f
diff --git a/gdb/python/py-progspace.c b/gdb/python/py-progspace.c
index f964fe0..68fe217 100644
--- a/gdb/python/py-progspace.c
+++ b/gdb/python/py-progspace.c
@@ -245,9 +245,8 @@ gdbpy_initialize_pspace (void)
if (PyType_Ready (&pspace_object_type) < 0)
return -1;

- Py_INCREF (&pspace_object_type);
- return PyModule_AddObject (gdb_module, "Progspace",
- (PyObject *) &pspace_object_type);
+ return gdb_pymodule_addobject (gdb_module, "Progspace",
+ (PyObject *) &pspace_object_type);
}

\f
diff --git a/gdb/python/py-symbol.c b/gdb/python/py-symbol.c
index 7629f70..8afe52d 100644
--- a/gdb/python/py-symbol.c
+++ b/gdb/python/py-symbol.c
@@ -531,9 +531,8 @@ gdbpy_initialize_symbols (void)
TYPES_DOMAIN) < 0)
return -1;

- Py_INCREF (&symbol_object_type);
- return PyModule_AddObject (gdb_module, "Symbol",
- (PyObject *) &symbol_object_type);
+ return gdb_pymodule_addobject (gdb_module, "Symbol",
+ (PyObject *) &symbol_object_type);
}

\f
diff --git a/gdb/python/py-symtab.c b/gdb/python/py-symtab.c
index fe26b4c..006946c 100644
--- a/gdb/python/py-symtab.c
+++ b/gdb/python/py-symtab.c
@@ -501,14 +501,12 @@ gdbpy_initialize_symtabs (void)
salpy_objfile_data_key
= register_objfile_data_with_cleanup (NULL, del_objfile_sal);

- Py_INCREF (&symtab_object_type);
- if (PyModule_AddObject (gdb_module, "Symtab",
- (PyObject *) &symtab_object_type) < 0)
+ if (gdb_pymodule_addobject (gdb_module, "Symtab",
+ (PyObject *) &symtab_object_type) < 0)
return -1;

- Py_INCREF (&sal_object_type);
- return PyModule_AddObject (gdb_module, "Symtab_and_line",
- (PyObject *) &sal_object_type);
+ return gdb_pymodule_addobject (gdb_module, "Symtab_and_line",
+ (PyObject *) &sal_object_type);
}

\f
diff --git a/gdb/python/py-type.c b/gdb/python/py-type.c
index dd3a751..63629fe 100644
--- a/gdb/python/py-type.c
+++ b/gdb/python/py-type.c
@@ -1548,19 +1548,16 @@ gdbpy_initialize_types (void)
return -1;
}

- Py_INCREF (&type_object_type);
- if (PyModule_AddObject (gdb_module, "Type",
- (PyObject *) &type_object_type) < 0)
+ if (gdb_pymodule_addobject (gdb_module, "Type",
+ (PyObject *) &type_object_type) < 0)
return -1;

- Py_INCREF (&type_iterator_object_type);
- if (PyModule_AddObject (gdb_module, "TypeIterator",
- (PyObject *) &type_iterator_object_type) < 0)
+ if (gdb_pymodule_addobject (gdb_module, "TypeIterator",
+ (PyObject *) &type_iterator_object_type) < 0)
return -1;

- Py_INCREF (&field_object_type);
- return PyModule_AddObject (gdb_module, "Field",
- (PyObject *) &field_object_type);
+ return gdb_pymodule_addobject (gdb_module, "Field",
+ (PyObject *) &field_object_type);
}

\f
diff --git a/gdb/python/py-utils.c b/gdb/python/py-utils.c
index 6a7e9e4..cf82734 100644
--- a/gdb/python/py-utils.c
+++ b/gdb/python/py-utils.c
@@ -409,3 +409,18 @@ gdb_py_generic_dict (PyObject *self, void *closure)
Py_INCREF (result);
return result;
}
+
+/* Like PyModule_AddObject, but does not steal a reference to
+ OBJECT. */
+
+int
+gdb_pymodule_addobject (PyObject *module, const char *name, PyObject *object)
+{
+ int result;
+
+ Py_INCREF (object);
+ result = PyModule_AddObject (module, name, object);
+ if (result < 0)
+ Py_DECREF (object);
+ return result;
+}
diff --git a/gdb/python/py-value.c b/gdb/python/py-value.c
index d8d90c7..e4f4263 100644
--- a/gdb/python/py-value.c
+++ b/gdb/python/py-value.c
@@ -1391,9 +1391,8 @@ gdbpy_initialize_values (void)
if (PyType_Ready (&value_object_type) < 0)
return -1;

- Py_INCREF (&value_object_type);
- return PyModule_AddObject (gdb_module, "Value",
- (PyObject *) &value_object_type);
+ return gdb_pymodule_addobject (gdb_module, "Value",
+ (PyObject *) &value_object_type);
}

\f
diff --git a/gdb/python/python-internal.h b/gdb/python/python-internal.h
index 4a9405f..a2a5079 100644
--- a/gdb/python/python-internal.h
+++ b/gdb/python/python-internal.h
@@ -464,4 +464,8 @@ int gdb_py_int_as_long (PyObject *, long *);

PyObject *gdb_py_generic_dict (PyObject *self, void *closure);

+int gdb_pymodule_addobject (PyObject *module, const char *name,
+ PyObject *object)
+ CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION;
+
#endif /* GDB_PYTHON_INTERNAL_H */
diff --git a/gdb/python/python.c b/gdb/python/python.c
index ab84bad..4f69c32 100644
--- a/gdb/python/python.c
+++ b/gdb/python/python.c
@@ -1630,19 +1630,20 @@ message == an error message without a stack will be printed."),

gdbpy_gdb_error = PyErr_NewException ("gdb.error", PyExc_RuntimeError, NULL);
if (gdbpy_gdb_error == NULL
- || PyModule_AddObject (gdb_module, "error", gdbpy_gdb_error) < 0)
+ || gdb_pymodule_addobject (gdb_module, "error", gdbpy_gdb_error) < 0)
goto fail;

gdbpy_gdb_memory_error = PyErr_NewException ("gdb.MemoryError",
gdbpy_gdb_error, NULL);
if (gdbpy_gdb_memory_error == NULL
- || PyModule_AddObject (gdb_module, "MemoryError",
- gdbpy_gdb_memory_error) < 0)
+ || gdb_pymodule_addobject (gdb_module, "MemoryError",
+ gdbpy_gdb_memory_error) < 0)
goto fail;

gdbpy_gdberror_exc = PyErr_NewException ("gdb.GdbError", NULL, NULL);
if (gdbpy_gdberror_exc == NULL
- || PyModule_AddObject (gdb_module, "GdbError", gdbpy_gdberror_exc) < 0)
+ || gdb_pymodule_addobject (gdb_module, "GdbError",
+ gdbpy_gdberror_exc) < 0)
goto fail;

gdbpy_initialize_gdb_readline ();
@@ -1789,7 +1790,7 @@ finish_python_initialization (void)
return;
}

- if (PyModule_AddObject (m, "gdb", gdb_python_module))
+ if (gdb_pymodule_addobject (m, "gdb", gdb_python_module) < 0)
goto fail;

/* Keep the reference to gdb_python_module since it is in a global
--
1.8.1.4