Python C API free() errors after using Py_SetPath() and Py_GetPath()

I'm trying to figure out why I can't simply get and set the python path through its C API. I am using Python3.6, on Ubuntu 17.10 with gcc version 7.2.0. Compiling with:

gcc pytest.c `python3-config --libs` `python3-config --includes`

#include <Python.h> int main() { Py_Initialize(); // removes error if put after Py_SetPath printf("setting path\n"); // prints Py_SetPath(L"/usr/lib/python3.6"); // Error in `./a.out': free(): invalid size: 0x00007fd5a8365030 *** printf("success\n"); // doesn't print return 0; } 

Setting the path works fine, unless I also try to get the path prior to doing so. If I get the path at all, even just to print without modifying the returned value or anything, I get a "double free or corruption" error.

Very confused. Am I doing something wrong or is this a bug? Anyone know a workaround if so?

Edit: Also errors after calling Py_Initialize();. Updated code. Now errors even if I don't call Py_GetPath() first.

13

2 Answers

[the below answer refers to this version of the question.]

From the docs:

void Py_Initialize()

Initialize the Python interpreter. In an application embedding Python, this should be called before using any other Python/C API functions; with the exception of Py_SetProgramName(), Py_SetPythonHome() and Py_SetPath().

But the code you show does call Py_GetPath() before it calls Py_Initialize();, which it per the above paragraph implicitly should not.

1

From alk it seems related to this bug:

Here is the workaround I am using. Since you can't call Py_GetPath() before Py_Initialize(), and also seemingly you can't call Py_SetPath() after Py_Initialize(), you can add to or get the path like this after calling Py_Initialize():

#include <Python.h> int main() { Py_Initialize(); // get handle to python sys.path object PyObject *sys = PyImport_ImportModule("sys"); PyObject *path = PyObject_GetAttrString(sys, "path"); // make a list of paths to add to sys.path PyObject *newPaths = PyUnicode_Split(PyUnicode_FromWideChar(L"a:b:c", -1), PyUnicode_FromWideChar(L":", 1), -1); // iterate through list and add all paths for(int i=0; i<PyList_Size(newPaths); i++) { PyList_Append(path, PyList_GetItem(newPaths, i)); } // print out sys.path after appends PyObject *newlist = PyUnicode_Join(PyUnicode_FromWideChar(L":", -1), path); printf("newlist = %ls\n", PyUnicode_AsWideCharString(newlist, NULL)); return 0; } 

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

You Might Also Like