Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix exception propagation from module init and memory leak #175

Open
wants to merge 4 commits into
base: develop
Choose a base branch
from

Commits on Oct 24, 2017

  1. Fix memory leaks in enum.cpp

    Unfortunately due to optimised build of Python3 libraries and executable I got only partial stack from [http://clang.llvm.org/docs/AddressSanitizer.html], however digging into and reducing my code I tracked it down to be issue with `boost/libs/python/src/object/enum.cpp`.
    
    It has to bits that leak (and comment mentioning there is one):
    
        PyObject *mod = PyObject_GetAttrString( self_, "__module__");
    
    Leaks reference, as it never decreases it.
    It also stores a new string object under object's `name` that ref count never gets decremented.
    
    That commit fixes both issues.
    elmopl authored Oct 24, 2017
    Configuration menu
    Copy the full SHA
    d7f94e0 View commit details
    Browse the repository at this point in the history

Commits on Nov 7, 2017

  1. Fix error propagation in from module init.

    When exception gets set we need to return NULL in Python3 as module pointer.
    Code in `Python/importdl.c` explicitly checks for this and suppresses exception (so you lose any knowledge of what went wrong):
    
        PyObject *
        _PyImport_LoadDynamicModuleWithSpec(PyObject *spec, FILE *fp)
        {
            [...]
    
            m = p0();
            _Py_PackageContext = oldcontext;
    
            if (m == NULL) {
                if (!PyErr_Occurred()) {
                    PyErr_Format(
                        PyExc_SystemError,
                        "initialization of %s failed without raising an exception",
                        name_buf);
                }
                goto error;
            } else if (PyErr_Occurred()) {
                PyErr_Clear();
                PyErr_Format(
                    PyExc_SystemError,
                    "initialization of %s raised unreported exception",
                    name_buf);
                m = NULL;
                goto error;
            }
    
    In above the first case propagates actually raised exception, but only if we returned NULL.
    Otherwise it overrides it with very unhelpful message of "unreported exception".
    
    Fix is to simply return NULL if we got exception raised inside `init_function`.
    
    Handling of that case follows what I could find in `Modules/symtablemodule.c` bundled with Python:
    
        PyMODINIT_FUNC
        PyInit__symtable(void)
        {
            PyObject *m;
    
            [...]
    
            if (PyErr_Occurred()) {
                Py_DECREF(m);
                m = 0;
            }
            return m;
        }
    
    So it checks if exception was raised, and if so it frees module and returns NULL.
    elmopl authored Nov 7, 2017
    Configuration menu
    Copy the full SHA
    7c3240d View commit details
    Browse the repository at this point in the history
  2. Fix memory leak in gcc_demangle

    `__cxa_demangle` returns a new pointer that needs to be freed.
    As much as this is only a minor leak (tenths of bytes per each unique symbol that got resolved) it makes automated memory leak checking tools quite upset.
    This simply adds a helper that frees memory for names we've kept.
    
    Also, removed a lot of trailing whitespace.
    elmopl authored Nov 7, 2017
    Configuration menu
    Copy the full SHA
    1d19e6f View commit details
    Browse the repository at this point in the history
  3. Merge pull request #1 from boostorg/develop

    Rebase.
    elmopl authored Nov 7, 2017
    Configuration menu
    Copy the full SHA
    449fb2a View commit details
    Browse the repository at this point in the history