From: Michael Tremer Date: Tue, 21 Sep 2021 16:14:25 +0000 (+0000) Subject: python: Prevent early deallocation of logging callback X-Git-Tag: 0.9.28~946 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a02be46b92eb66a54f9a692a5571a523e859c7a2;p=pakfire.git python: Prevent early deallocation of logging callback Signed-off-by: Michael Tremer --- diff --git a/src/_pakfire/pakfire.c b/src/_pakfire/pakfire.c index f6784db9e..9c4401d3e 100644 --- a/src/_pakfire/pakfire.c +++ b/src/_pakfire/pakfire.c @@ -108,6 +108,7 @@ static int Pakfire_init(PakfireObject* self, PyObject* args, PyObject* kwds) { "enable_ccache", "enable_snapshot", NULL }; const char* path = NULL; const char* arch = NULL; + PyObject* logger = NULL; const char* conf = NULL; int offline = 0; int build = 0; @@ -115,12 +116,12 @@ static int Pakfire_init(PakfireObject* self, PyObject* args, PyObject* kwds) { int enable_snapshot = 1; if (!PyArg_ParseTupleAndKeywords(args, kwds, "|zzOpzppp", kwlist, - &path, &arch, &self->logger, &offline, &conf, &build, + &path, &arch, &logger, &offline, &conf, &build, &enable_ccache, &enable_snapshot)) return -1; // Check if logger is callable - if (self->logger && !PyCallable_Check(self->logger)) { + if (logger && !PyCallable_Check(logger)) { PyErr_SetString(PyExc_TypeError, "logger must be callable\n"); return -1; } @@ -144,7 +145,7 @@ static int Pakfire_init(PakfireObject* self, PyObject* args, PyObject* kwds) { // Create a new Pakfire instance int r = pakfire_create(&self->pakfire, path, arch, conf, flags, - (self->logger) ? Pakfire_logging_callback : NULL, self->logger); + (logger) ? Pakfire_logging_callback : NULL, logger); if (r) { switch (errno) { // Invalid architecture or path @@ -160,7 +161,11 @@ static int Pakfire_init(PakfireObject* self, PyObject* args, PyObject* kwds) { return -1; } - Py_XINCREF(self->logger); + // Store a reference to the logger + if (logger) { + self->logger = logger; + Py_INCREF(self->logger); + } return 0; } @@ -169,8 +174,18 @@ static void Pakfire_dealloc(PakfireObject* self) { if (self->pakfire) pakfire_unref(self->pakfire); +#if 0 + /* + It might happen, that the Pakfire python object is deallocated but the + actual struct pakfire object isn't yet. However, it might still happen + that the logging function is called which will try to call the logging + callback which has already been deallocated. + + TODO This has to move into struct pakfire or something similar. + */ if (self->logger) Py_DECREF(self->logger); +#endif Py_TYPE(self)->tp_free((PyObject *)self); }