[PyQt] crash in sip module when a C++ exception is thrown from a class constructor

Phil Thompson phil at riverbankcomputing.com
Thu Apr 1 11:16:34 BST 2010


On Wed, 31 Mar 2010 23:02:49 +0200, Denis Rivière <denis.riviere at cea.fr>
wrote:
> Hi,
> Using sip 4.10 or sip 4.10.1, I have crashes when a C++ exception is
thrown
> 
> from a C++ class constructor. It happens either if the exception is
> declared 
> in the sip binding or not.
> I experienced it on a Linux system (Fedora 12).
> 
> A small example:
> 
> # C++ header:
> #ifndef WORD_H
> #define WORD_H
> 
> class Word {
> public:
>     char *the_word;
> 
>     Word(const char *w);
>     virtual ~Word();
> 
> };
> #endif
> #--
> 
> # C++ implementation:
> #include "word.h"
> #include <string>
> #include <stdexcept>
> #include <string.h>
> #include <stdlib.h>
> 
> using namespace std;
> 
> Word::Word(const char *w) : the_word( strdup( w ) )
> {
>   if( string( w ) == "exception" )
>     throw runtime_error( "exception in constructor" );
> }
> 
> Word::~Word()
> {
>   free( the_word );
> }
> #--
> 
> # sip code:
> %Module word 0
> 
> %Exception std::exception(SIP_Exception) /PyName=StdException/
> {
> %TypeHeaderCode
> #include <exception>
> %End
> %RaiseCode
>         const char *detail = sipExceptionRef.what();
> 
>         SIP_BLOCK_THREADS
>         PyErr_SetString(sipException_StdException, detail);
>         SIP_UNBLOCK_THREADS
> %End
> };
> 
> 
> %Exception std::runtime_error(std::exception) /PyName=RuntimeError/
> {
> %TypeHeaderCode
> #include <stdexcept>
> %End
> %RaiseCode
>         const char *detail = sipExceptionRef.what();
> std::cout << "throw/raise runtime_error: " << detail << std::endl;
> 
>         SIP_BLOCK_THREADS
>         PyErr_SetString(sipException_std_runtime_error, detail);
>         SIP_UNBLOCK_THREADS
> %End
> };
> 
> class Word {
> 
> %TypeHeaderCode
> #include <word.h>
> #include <stdexcept>
> %End
> 
> public:
>     Word(const char *) /* throw( std::runtime_error ) */;
>     virtual ~Word();
> 
> };
> #--
> 
> # test case:
> import word
> w = word.Word( 'toto' ) # doesn't crash
> x = word.Word( 'exception' ) # crashes
> # --
> 
> If I un-comment the throw() on the constructor in the .sip file, it still

> crashes.
> It did not crash using older versions of sip (4.7.x at least).
> It seems to happen after the sip binding code is executed (after 
> init_Word(...) in the sip-generated source), when back in the sip.so
> module. 

Fixed in Hg.

Thanks for the test case.

Phil


More information about the PyQt mailing list