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

Denis Rivière denis.riviere at cea.fr
Wed Mar 31 22:02:49 BST 2010


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. 

Denis


More information about the PyQt mailing list