My project uses GLib's GObject and recently I thought of adding support for
executing python scripts by embedding the interpreter within the code.
However there is this need to pass a GOB struct as one of the parameters to
a function in the python script. How exactly do I pass non-PyObject types
with the API?
I tried (to be clever) casting my GOB structure to PyObject and passing it
in the args field of PyObject_CallObject. This of course turned out to be an
EPIC FAIL with
a nasty segfault. (I also tried Py_BuildValue with 'O&' signature)
It would be wonderful if some points me to some code which does this. From
what I gather, do I need to create some sort of a Type Object which the
Python API can understand? If it matters, I am using the 2.5 API.
Thanks and regards
Blog : http://www.sudharsh.wordpress.com
IRC : Sup3rkiddo @ Freenode, Gimpnet
On Tue, Oct 21, 2008 at 10:54 PM, Campbell Barton <ideasman42(a)gmail.com> wrote:
> On Wed, Oct 22, 2008 at 3:03 PM, Adam Olsen <rhamph(a)gmail.com> wrote:
>> On Tue, Oct 21, 2008 at 9:34 PM, Campbell Barton <ideasman42(a)gmail.com> wrote:
>>> Hi, just spent a couple of hours looking into a bug that others might also have.
>>> If your app embeds python, and allows scripts to throw exceptions
>>> while the application keeps running you may also have this problem.
>>> sys.last_traceback will store the last exception along with the
>>> namespace dictionary of the script that just ran (with all its
>>> functions etc, variables etc).
>>> In our case this caused crashes because you could load in new data,
>>> making many of the PyObjects referenced from sys.last_traceback, point
>>> to invalid data. Once sys.last_traceback was set again it would free
>>> the existing data sometimes touching pointers with invalid addresses
>>> causing a segfault.
>>> Simple solution is to run this after PyErr_Print();
>>> PySys_SetObject( "last_traceback", Py_None);
>>> This can also free memory, if large datasets are references from the
>>> traceback. maybe some of your would fine this useful.
>> Do you mean you have a PyObject with a pointer to malloc'd memory, and
>> after the exception is handled (but not cleared) you free the malloc'd
>> memory, but leave the PyObject with a pointer to it? If so you should
>> be keeping track of any PyObjects and clearing them instead (or let
>> them take care of freeing the malloc'd memory).
> Yeah, this is the case and you're right, we should be aware of the
> PyObjects existence and invalidate them when the memory is freed, or
> let python do the freeing.
> But our application does not center around python, the PyAPI has its
> own directory and PyObjects are not supposed to be used outside that.
> Id be interested in knowing what other apps do - is this even a common problem?
Common in the sense that other apps probably do it right, yes. ;)
How are you calling into python? If you call a single python function
(which in turn calls many others), and this is what raises the
exception, this is the obvious point to trigger the clearing.
Adam Olsen, aka Rhamphoryncus
Hi, just spent a couple of hours looking into a bug that others might also have.
If your app embeds python, and allows scripts to throw exceptions
while the application keeps running you may also have this problem.
sys.last_traceback will store the last exception along with the
namespace dictionary of the script that just ran (with all its
functions etc, variables etc).
In our case this caused crashes because you could load in new data,
making many of the PyObjects referenced from sys.last_traceback, point
to invalid data. Once sys.last_traceback was set again it would free
the existing data sometimes touching pointers with invalid addresses
causing a segfault.
Simple solution is to run this after PyErr_Print();
PySys_SetObject( "last_traceback", Py_None);
This can also free memory, if large datasets are references from the
traceback. maybe some of your would fine this useful.
Here is a screenshot and the call stack:
user32.dll!_NtUserWaitMessage@0() + 0xc bytes
user32.dll!_InternalDialogBox@24() + 0xb6 bytes
user32.dll!_SoftModalMessageBox@4() + 0x677 bytes
user32.dll!_MessageBoxWorker@4() + 0x175 bytes
user32.dll!_MessageBoxTimeoutW@24() + 0x7a bytes
user32.dll!_MessageBoxTimeoutA@24() + 0x9c bytes
user32.dll!_MessageBoxExA@20() + 0x1b bytes
user32.dll!_MessageBoxA@16() + 0x45 bytes
[Frames below may be incorrect and/or missing, no symbols loaded for python25.dll]
kernel32.dll!_CreateFileA@28() + 0x2b bytes
msvcr90.dll!_sopen_helper(const char * path=0x0fd0dc68, int oflag=32768, int shflag=64, int pmode=384, int * pfh=0x0fd0d7c8, int bSecure=1) Line 190 + 0x5 bytes
msvcr90.dll!_sopen_s(int * pfh=0x0fd0d7c8, const char * path=0x0fd0dc68, int oflag=32768, int shflag=64, int pmode=384) Line 907 + 0x16 bytes
msvcr90.dll!_openfile(const char * filename=0x1e1a53b2, const char * mode=0x1e0097c7, int shflag=265345024, _iobuf * str=0x00000025) Line 272 + 0x17 bytes
msvcr90.dll!__lock_fhandle(int fh=89305032) Line 468 + 0x5 bytes
NMMediaServer.dll!initMediaHomeWebInterface() Line 32 + 0x30 bytes C++
ntdll.dll!_RtlGetFullPathName_Ustr@24() + 0x2f7 bytes
ntdll.dll!_RtlAllocateHeapSlowly@12() + 0x3da bytes
msvcr90.dll!malloc(unsigned int size=408) Line 163 + 0x5f bytes
msvcr90.dll!__lock_fhandle(int fh=3) Line 467
msvcr90.dll!_close(int fh=503378203) Line 62 + 0x8 bytes
msvcr90.dll!_close(int fh=503378203) Line 66 + 0x5 bytes
NMMediaServer.dll!std::_Iterator_base::~_Iterator_base() Line 151 + 0x28 bytes C++
NMUPnPServices.dll!CILibWebRequestHeader::CILibWebRequestHeader(packetheader * pHeader=0x00000000) Line 90 + 0x19 bytes C++
The problem is msvcr90.dll? Why this dll for Visual Studio 2008? I thought it should be 2005. :-?
>Here are some facts:
>Winodws XP SP3 with newest updates
>Visual Studio 2005
>Microsoft Visual C++ 2005 Redistributable I downloaded Python 2.6 installer for Windows from >python.org I use Python with boost 1.36 for Python (could this be a problem?)
>I want to use Python 2.6 because it was (i think so) built with VS2005.
>So I haven't to use msvcr71.dll.
>On monday I can send a stack trace and a screenshot of this crash a with E-Mail.
>Jack Jansen wrote:
>> This could be one of thousands of things. If it works with 2.5 and no
>> more with 2.6 some possible candidates are (1) a bug in Python, (2) a
>> difference in memory layout which caused buggy code to work correct in
>> 2.5 nonetheless or (3) a timing difference, with the same effect.
>> Oh yes, if you're on Windows and using the prebuilt dll it could also
>> be caused by runtime library differences, I think 2.5 was built with
>> VS2003 and 2.6 with VS2005.
>> You'll need to provide a bit more detail if you want more help (OS and
>> version, how you built Python and your app, is your code in an
>> extension module or embedding Python, how does it crash, did you get a
>> stack trace, etc)
>> Jack Jansen, <Jack.Jansen(a)cwi.nl>, http://www.cwi.nl/~jack
>> If I can't dance I don't want to be part of your revolution -- Emma
I've use Python 2.5 and want to use Python 2.6.
But I have a problem with PyImport_ImportModule.
PyObject* pModule = PyImport_ImportModule(pBuffer);
pBuffer is for example theme.simple.index
and my script looks like:
def StartWebInterface(cppObjectWeb, cppObjectSettings):
page = u''
page = u'''<html>
servername = cppObjectSettings.GetSettingsFromMethod(DeviceFriendlyName)
page += servername
page += u'''</title>
page += servername
page += u'''</h1>
<a href="?f=browse">Browse Directory</a><br />
page = BuildErrorPage()
page = u'''<html>
page += sys.exc_info()
page += u'</body></html>'
But the PyImport_ImportModule crashed my c++ program.
The index.py was compiled because a new index.pyc was created.
Thanks for help.
Psssst! Schon vom neuen GMX MultiMessenger gehört? Der kann`s mit allen: http://www.gmx.net/de/go/multimessenger
I stumbled about a curious problem: Including <Python.h> changes the size of fpos_t.
m01% cat fpos_python.cc
#endif /* HAVE_PYTHON_H */
int main(int argc, char** argv)
printf("sizeof(fpos_t) = %d\n",sizeof(fpos_t));
m01% g++ -DHAVE_PYTHON_H -I/usr/include/python2.5 fpos_python.cc -lpython2.5 && ./a.out
sizeof(fpos_t) = 16
m01% g++ -I/usr/include/python2.5 fpos_python.cc -lpython2.5 && ./a.out
sizeof(fpos_t) = 12
This breaks my code if I do not include <Python.h> in ALL of my compilation modules (which is not pratical in my opinion).
Is this a known problem? I personally would call this definitely a bug. What is the rational behind changing fpos_t?
"50 erste Dates" mit Adam Sandler u. Drew Barrymore kostenlos anschauen!
Exklusiv für alle WEB.DE Nutzer. http://www.blockbuster.web.de
was trying to hunt down why modules would not import in Blender3D with
python 2.6, and found its caused by an extra argument to import that
was making our own internal replacement for __builtin__.__import__
Added an #ifdef to work around this, for anyone else replacing the
builtin import, this could save you some time.
static PyObject *blender_import( PyObject * self, PyObject * args )
PyObject *exception, *err, *tb;
PyObject *globals = NULL, *locals = NULL, *fromlist = NULL;
//PyObject_Print(args, stderr, 0);
#if (PY_VERSION_HEX >= 0x02060000)
int dummy_val; /* what does this do?*/
if( !PyArg_ParseTuple( args, "s|OOOi:bimport",
&name, &globals, &locals, &fromlist, &dummy_val) )
if( !PyArg_ParseTuple( args, "s|OOO:bimport",
&name, &globals, &locals, &fromlist ) )
m = PyImport_ImportModuleEx( name, globals, locals, fromlist );
if( m )
PyErr_Fetch( &exception, &err, &tb ); /*restore for probable later use */