Boost logo

Boost :

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


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