Boost logo

Boost :

From: Norman Shelley (rrdn60) (rrdn60_at_[hidden])
Date: 2001-05-18 14:34:31


>> We had problems like this with gcc before. In general, the gcc exception handling
>> seems to be unreliable. Have you tried your code on a different platform?
>> Ralf
Nope. This code only has to run on HPUX systems. There is no desire to
try other platforms.
Norman

Norman Shelley wrote:

> Throwing an error within a class init causes a segment fault.
>
> Boost1.21.1
>
> [524] % uname -a
> HP-UX wvenus B.10.20 A 9000/782 2009382447 two-user license
> [525] % gcc --version
> 2.95.3
> [526] % gmake abc_sl.sl
> g++ - -I/usr/local/include/python2.1 -ftemplate-depth-21 -fpic -g -c
> abc_sl.cpp
> g++ -o abc_sl.sl abc_sl.o -shared -fpic -lboost_python -ldld -lm
>
> % python2.1
> Python 2.1 (#2, Apr 24 2001, 11:33:06)
> [GCC 2.95.3 20010315 (release)] on hp-uxB
> Type "copyright", "credits" or "license" for more information.
> >>> from mot_ddl_wssg import abc_sl
> >>> abc_sl.command("test")
> command: raise_error: 'Command problem!!'
> >>>Command problem!!<<<
> Traceback (most recent call last):
> File "<stdin>", line 1, in ?
> abc.error: Command problem!!
> >>> abc_sl.Listing(2)
> Listing creation NULL: raise_error: 'A problem!!'
> >>>A problem!!<<<
> Segmentation fault
>
> #include <cstddef>
> #include <string>
> #include <cstring>
> #include <iostream>
> #include <sstream>
> #include <typeinfo>
> #include <exception>
> #include <boost/python/reference.hpp>
> #include <boost/python/module_builder.hpp>
> #include <boost/python/class_builder.hpp>
>
> #include <assert.h>
>
> // Needed for Py_None
> #include <python2.1/object.h>
> // Needed for PyFile_AsFile
> #include <python2.1/fileobject.h>
>
> #define BPC BOOST_PYTHON_CONVERSION
>
> namespace python = boost::python;
>
> namespace { // Avoid cluttering the global namespace.
> PyObject *abcError; // Initialized in BOOST_PYTHON_MODULE_INIT(abc_sl)
>
> void raise_error(const string& errstr) {
> cerr << "raise_error: '" << errstr << "'\n";
> PyErr_SetString(abcError, errstr.c_str());
> fprintf(stderr, ">>>%s<<<\n", errstr.c_str());
> throw python::error_already_set();
> }
>
> void command(const std::string& cmd) {
> cerr << "command: ";
> raise_error("Command problem!!");
> }
>
> class Listing {
> //CAVEAT: Internal FILE* is held and closed only on instance deletion
> public:
> Listing(int type) {
> cerr << "Listing creation NULL: ";
> raise_error("A problem!!");
> __fp = tmpfile();
> cerr << "fp " << __fp << "\n";
> listing(type);
> }
> Listing(int type, const std::string& filename) {
> cerr << "Listing creation " << filename << ": ";
> __fp = fopen(filename.c_str(), "w+");
> cerr << "fp " << __fp << "\n";
> listing(type);
> }
>
> ~Listing() {
> //fprintf(stderr, "Listing destruction: fp %x\n", __fp);
> fclose(__fp);
> }
>
> int fileno() {
> if (__fp == NULL) {
> raise_error("NULL file pointer");
> }
> //The std:: prefix is necessary for it to compile
> return std::fileno(__fp);
> }
> private:
> FILE *__fp;
>
> void listing(int type) {
> if (0) {
> fclose(__fp);
> __fp = NULL;
> }
> }
> };
>
> }
>
> // Python requires an exported function called init<module-name> in
> every
> // extension module. This is where we build the module contents.
> BOOST_PYTHON_MODULE_INIT(abc_sl)
> {
> try
> {
> // Create an object representing this extension module
> python::module_builder abc_sl_module("abc_sl");
>
> // Create a Python abc exception type/class
> abcError = PyErr_NewException("abc.error", NULL, NULL);
> if (abcError == NULL) {
> throw python::error_already_set();
> }
> //PyObject *d = PyModule_GetDict(abc_sl_module.module());
> //PyDict_SetItemString(d, "error", abcError);
>
> // Place abcError in the abc_sl_module namespace as "error"
> abc_sl_module.add(python::make_ref(abcError), "error");
>
> abc_sl_module.def(command, "command");
>
> python::class_builder<Listing> ListingClass(abc_sl_module,
> "Listing");
> // Add in __init__ functions (constructors)
> ListingClass.def(python::constructor<int>());
> ListingClass.def(python::constructor<int,const std::string>());
> // Add in regular member functions
> ListingClass.def(&Listing::fileno, "fileno");
> }
> catch(...)
> {
> python::handle_exception(); // Deal with the exception for Python
> }
> }
>
> ------------------------------------------------------------------------
> #include <cstddef>
> #include <string>
> #include <cstring>
> #include <iostream>
> #include <sstream>
> #include <typeinfo>
> #include <exception>
> #include <boost/python/reference.hpp>
> #include <boost/python/module_builder.hpp>
> #include <boost/python/class_builder.hpp>
>
> #include <assert.h>
>
> // Needed for Py_None
> #include <python2.1/object.h>
> // Needed for PyFile_AsFile
> #include <python2.1/fileobject.h>
>
> #define BPC BOOST_PYTHON_CONVERSION
>
> namespace python = boost::python;
>
> namespace { // Avoid cluttering the global namespace.
> PyObject *abcError; // Initialized in BOOST_PYTHON_MODULE_INIT(abc_sl)
>
> void raise_error(const string& errstr) {
> cerr << "raise_error: '" << errstr << "'\n";
> PyErr_SetString(abcError, errstr.c_str());
> fprintf(stderr, ">>>%s<<<\n", errstr.c_str());
> throw python::error_already_set();
> }
>
> void command(const std::string& cmd) {
> cerr << "command: ";
> raise_error("Command problem!!");
> }
>
> class Listing {
> //CAVEAT: Internal FILE* is held and closed only on instance deletion
> public:
> Listing(int type) {
> cerr << "Listing creation NULL: ";
> raise_error("A problem!!");
> __fp = tmpfile();
> cerr << "fp " << __fp << "\n";
> listing(type);
> }
> Listing(int type, const std::string& filename) {
> cerr << "Listing creation " << filename << ": ";
> __fp = fopen(filename.c_str(), "w+");
> cerr << "fp " << __fp << "\n";
> listing(type);
> }
>
>
> ~Listing() {
> //fprintf(stderr, "Listing destruction: fp %x\n", __fp);
> fclose(__fp);
> }
>
> int fileno() {
> if (__fp == NULL) {
> raise_error("NULL file pointer");
> }
> //The std:: prefix is necessary for it to compile
> return std::fileno(__fp);
> }
> private:
> FILE *__fp;
>
> void listing(int type) {
> if (0) {
> fclose(__fp);
> __fp = NULL;
> }
> }
> };
>
>
> }
>
> // Python requires an exported function called init<module-name> in every
> // extension module. This is where we build the module contents.
> BOOST_PYTHON_MODULE_INIT(abc_sl)
> {
> try
> {
> // Create an object representing this extension module
> python::module_builder abc_sl_module("abc_sl");
>
> // Create a Python abc exception type/class
> abcError = PyErr_NewException("abc.error", NULL, NULL);
> if (abcError == NULL) {
> throw python::error_already_set();
> }
> //PyObject *d = PyModule_GetDict(abc_sl_module.module());
> //PyDict_SetItemString(d, "error", abcError);
>
> // Place abcError in the abc_sl_module namespace as "error"
> abc_sl_module.add(python::make_ref(abcError), "error");
>
> abc_sl_module.def(command, "command");
>
> python::class_builder<Listing> ListingClass(abc_sl_module,
> "Listing");
> // Add in __init__ functions (constructors)
> ListingClass.def(python::constructor<int>());
> ListingClass.def(python::constructor<int,const std::string>());
> // Add in regular member functions
> ListingClass.def(&Listing::fileno, "fileno");
> }
> catch(...)
> {
> python::handle_exception(); // Deal with the exception for Python
> }
> }


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk