I'm going out of my mind here. I expect to catch exceptions in C++ so that I can map them to a custom exception class in python. All I get now are python Exceptions. I cannot catch my Exceptions inside generated code???
program:
#!/usr/bin/python
import os
import sys
import hpsphal_python
prog = os.path.basename(__file__) + ": "
try:
hal = hpsphal_python.System_getSystem()
scs = hal.getStorageClusters()
if len(scs) == 0:
print >>sys.stderr, prog + "No storage clusters found."
os._exit(-1)
for sc in scs:
print "sc: ", sc.getUUID()
conts = sc.getControllers()
for c in conts:
try:
c.setClock()
except hpsphal_python.Exception as e:
print "he: ", e.what()
except RuntimeError as e:
print "rt: ", e, e[0]
except Exception as e:
print "e: ", e, e[0]
os._exit(0)
except Exception, e:
print "E: ", e
os._exit(-1)
output:
sc: 222367ad-0005-1000-95ab-415a34303736
e: setControllerClock setControllerClock
e: setControllerClock setControllerClock
sc: MXQ04205MV_Con_0_Cluster
e: setControllerClock setControllerClock
Same code in C++ that does in fact catch the Exceptions:
#include "time.h"
#include <iostream>
#include <map>
#include <set>
#include <string>
#include <exception>
#include <boost/foreach.hpp>
#include <boost/regex.hpp>
#include <boost/thread/thread.hpp>
#include "Exception.hpp"
#include "StorageCluster.hpp"
#include "Controller.hpp"
#include "System.hpp"
using namespace std;
int main (int argc, char *argv[])
{
danAPI::SystemPtr danSystem;
try {
danSystem = danAPI::System::getSystem();
}
catch(danAPI::Exception& e) {
cerr << "Unable to initialize danAPI" << e.what() << endl;
return -1;
}
try {
danAPI::StorageClusterPtrList danStorageClusters = danSystem->getStorageClusters();
BOOST_FOREACH(danAPI::StorageClusterPtr sc, danStorageClusters)
{
danAPI::ControllerPtrList danStorageControllers = sc->getControllers();
BOOST_FOREACH(danAPI::ControllerPtr c, danStorageControllers)
{
try {
c->setClock();
}
catch(danAPI::Exception& e) {
cerr << "HAL Exception: " << e.what() << endl;
}
catch(exception& e) {
cerr << "Standard Exception: " << e.what() << endl;
}
}
}
}
catch(exception& e) {
cerr << "Unable to get storage clusters: " << e.what() << endl;
}
return 0;
}
output:
HAL Exception: setControllerClock: SetClock exception: function failed (1)
/jenkins/workspace/ts1.4-hpsphal/storage-lib/src/Raptor.cpp: 1100
/jenkins/workspace/ts1.4-hpsphal/storage-lib/src/Raptor.cpp: 791
(1)
/jenkins/workspace/ts1.4-hpsphal/storage-lib/src/StorageCluster_Rcim.cpp: 2158
HAL Exception: setControllerClock: SetClock exception: function failed (1)
/jenkins/workspace/ts1.4-hpsphal/storage-lib/src/Raptor.cpp: 1100
/jenkins/workspace/ts1.4-hpsphal/storage-lib/src/Raptor.cpp: 791
(1)
/jenkins/workspace/ts1.4-hpsphal/storage-lib/src/StorageCluster_Rcim.cpp: 2158
The players:
custom Exception class
SWIG 2.0.12
boost 1.41 throw_exception
A snippet from my generated code:
{
try {
(arg1)->setClock();
} catch(danAPI::Exception& e) {
std::cerr << "++++++" << std::endl;
} catch(std::exception& e) {
std::cerr << "++++++" << std::endl;
} catch(boost::exception& e) {
std::cerr << "++++++" << std::endl;
} catch(...) {
std::cerr << "++++++" << std::endl;
}
}
resultobj = SWIG_Py_Void();
return resultobj;
fail:
return NULL;
Here's my .i file (hdrs macros are filled in with my header files)
%include "stdint.i"
%include "stl.i"
%include "std_string.i"
%include "std_vector.i"
%include "std_string.i"
%include "std_pair.i"
%include "std_set.i"
%include "typemaps.i"
%apply unsigned long long &OUTPUT { unsigned long long &firstCharInBuffer };
%apply unsigned long long &OUTPUT { unsigned long long &nextChar };
%exceptionclass danAPI::Exception;
%exception {
try {
$action
}
catch(danAPI::Exception &e)
{
SWIG_Python_Raise(SWIG_NewPointerObj(
(new danAPI::Exception(static_cast<const danAPI::Exception&>(e))),
SWIGTYPE_p_danAPI__Exception,SWIG_POINTER_OWN),
"Exception", SWIGTYPE_p_danAPI__Exception);
SWIG_fail;
}
}
// need to define the templates for shared_ptr<T> before we define the
// various T's below; put in a common place so the various SWIG interfaces
// stay in sync
%include "hpsphal_ptrs.i"
%{
${hash_public_headers}
using namespace danAPI;
%}
${percent_public_headers}
// need to define the vector types after we've defined the types
// themselves; moved to a common place to keep the various SWIG interfaces
// in sync
%include "hpsphal_vectors.i"
I ran my code in gdb, "catch throw". I saw a few exceptions that I catch internal to my library. There should have been 3 exceptions thrown by my library, then caught by my SWIG code.
This was caught internally:
#0 0x000000337c8bccb0 in __cxa_throw () from /usr/lib64/libstdc++.so.6
#1 0x00007ffff122a1ac in boost::throw_exception<danAPI::Exception> (e=...) at /usr/include/boost/throw_exception.hpp:64
#2 0x00007fffef398841 in danAPI::StorageClusterFactory::getStorageControllerType (this=0x7fffffffd6d0, path="/dev/sg4")
at /home/chchr/src/hpsphal/storage-lib/src/StorageClusterFactory.cpp:247
#3 0x00007fffef398aa8 in danAPI::StorageClusterFactory::createStorageCluster (this=0x7fffffffd6d0, path="/dev/sg4",
storclustpList=std::vector of length 1, capacity 1 = {...}, cluster=std::tr1::shared_ptr (empty) 0x0, err=...)
at /home/chchr/src/hpsphal/storage-lib/src/StorageClusterFactory.cpp:308
#4 0x00007fffef3a262c in boost::_mfi::cmf4<void, danAPI::StorageClusterFactory, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, danAPI::ConstStorageClusterPtrList const&, danAPI::ConstStorageClusterPtr&, boost::exception_ptr&>::call<danAPI::StorageClusterFactory const* const, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::vector<std::tr1::shared_ptr<danAPI::StorageCluster const>, std::allocator<std::tr1::shared_ptr<danAPI::StorageCluster const> > > const, std::tr1::shared_ptr<danAPI::StorageCluster const>, boost::exception_ptr> (this=0x896740, u=@0x896750, b1=
"/dev/sg4", b2=std::vector of length 1, capacity 1 = {...}, b3=std::tr1::shared_ptr (empty) 0x0, b4=...)
at /usr/include/boost/bind/mem_fn_template.hpp:547
#5 0x00007fffef3a2466 in boost::_mfi::cmf4<void, danAPI::StorageClusterFactory, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, danAPI::ConstStorageClusterPtrList const&, danAPI::ConstStorageClusterPtr&, boost::exception_ptr&>::operator()<danAPI::StorageClusterFactory const*> (
this=0x896740, u=@0x896750, a1="/dev/sg4", a2=std::vector of length 1, capacity 1 = {...}, a3=std::tr1::shared_ptr (empty) 0x0, a4=...)
at /usr/include/boost/bind/mem_fn_template.hpp:556
#6 0x00007fffef3a21d4 in boost::_bi::list5<boost::_bi::value<danAPI::StorageClusterFactory const*>, boost::_bi::value<char*>, boost::reference_wrapper<std::vector<std::tr1::shared_ptr<danAPI::StorageCluster const>, std::allocator<std::tr1::shared_ptr<danAPI::StorageCluster const> > > >, boost::reference_wrapper<std::tr1::shared_ptr<danAPI::StorageCluster const> >, boost::reference_wrapper<boost::exception_ptr> >::operator()<boost::_mfi::cmf4<void, danAPI::StorageClusterFactory, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, danAPI::ConstStorageClusterPtrList const&, danAPI::ConstStorageClusterPtr&, boost::exception_ptr&>, boost::_bi::list0> (this=0x896750, f=..., a=...) at /usr/include/boost/bind/bind.hpp:518
#7 0x00007fffef3a1e0d in boost::_bi::bind_t<void, boost::_mfi::cmf4<void, danAPI::StorageClusterFactory, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, danAPI::ConstStorageClusterPtrList const&, danAPI::ConstStorageClusterPtr&, boost::exception_ptr&>, boost::_bi::list5<boost::_bi::value<danAPI::StorageClusterFactory const*>, boost::_bi::value<char*>, boost::reference_wrapper<std::vector<std::tr1::shared_ptr<danAPI::StorageCluster const>, std::allocator<std::tr1::shared_ptr<danAPI::StorageCluster const> > > >, boost::reference_wrapper<std::tr1::shared_ptr<danAPI::StorageCluster const> >, boost::reference_wrapper<boost::exception_ptr> > >::operator() (this=0x896740) at /usr/include/boost/bind/bind_template.hpp:20
#8 0x00007fffef3a19cc in boost::detail::thread_data<boost::_bi::bind_t<void, boost::_mfi::cmf4<void, danAPI::StorageClusterFactory, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, danAPI::ConstStorageClusterPtrList const&, danAPI::ConstStorageClusterPtr&, boost::exception_ptr&>, boost::_bi::list5<boost::_bi::value<danAPI::StorageClusterFactory const*>, boost::_bi::value<char*>, boost::reference_wrapper<std::vector<std::tr1::shared_ptr<danAPI::StorageCluster const>, std::allocator<std::tr1::shared_ptr<danAPI::StorageCluster const> > > >, boost::reference_wrapper<std::tr1::shared_ptr<danAPI::StorageCluster const> >, boost::reference_wrapper<boost::exception_ptr> > > >::run (this=0x896610) at /usr/include/boost/thread/detail/thread.hpp:56
#9 0x00007fffed8c2d97 in thread_proxy () from /usr/lib64/libboost_thread-mt.so.5
#10 0x000000337a007851 in start_thread () from /lib64/libpthread.so.0
#11 0x00000033794e811d in clone () from /lib64/libc.so.6
Then I should have gotten 2 more from setControllerClock() before:
#0 0x000000337c8bccb0 in __cxa_throw () from /usr/lib64/libstdc++.so.6
#1 0x00007ffff143fc4c in swig::SwigPyIteratorClosed_T<__gnu_cxx::__normal_iterator<std::tr1::shared_ptr<danAPI::Controller>*, std::vector<std::tr1::shared_ptr<danAPI::Controller>, std::allocator<std::tr1::shared_ptr<danAPI::Controller> > > >, std::tr1::shared_ptr<danAPI::Controller>, swig::from_oper<std::tr1::shared_ptr<danAPI::Controller> > >::value (this=0x87bf50) at /home/chchr/src/hpsphal/build/python/hpsphalPYTHON_wrap.cxx:4894
#2 0x00007ffff101ddb7 in swig::SwigPyIterator::next (this=0x87bf50) at /home/chchr/src/hpsphal/build/python/hpsphalPYTHON_wrap.cxx:3472
#3 0x00007ffff07a083c in _wrap_SwigPyIterator_next (args=0x7ffff7f69850) at /home/chchr/src/hpsphal/build/python/hpsphalPYTHON_wrap.cxx:14301
#4 0x000000337b8deb24 in PyEval_EvalFrameEx () from /usr/lib64/libpython2.6.so.1.0
#5 0x000000337b8e0797 in PyEval_EvalCodeEx () from /usr/lib64/libpython2.6.so.1.0
#6 0x000000337b86edb0 in ?? () from /usr/lib64/libpython2.6.so.1.0
#7 0x000000337b844303 in PyObject_Call () from /usr/lib64/libpython2.6.so.1.0
#8 0x000000337b85970f in ?? () from /usr/lib64/libpython2.6.so.1.0
#9 0x000000337b844303 in PyObject_Call () from /usr/lib64/libpython2.6.so.1.0
#10 0x000000337b89d5eb in ?? () from /usr/lib64/libpython2.6.so.1.0
#11 0x000000337b8da458 in PyEval_EvalFrameEx () from /usr/lib64/libpython2.6.so.1.0
#12 0x000000337b8e0797 in PyEval_EvalCodeEx () from /usr/lib64/libpython2.6.so.1.0
#13 0x000000337b8e0872 in PyEval_EvalCode () from /usr/lib64/libpython2.6.so.1.0
#14 0x000000337b8fbbbc in ?? () from /usr/lib64/libpython2.6.so.1.0
#15 0x000000337b8fbc90 in PyRun_FileExFlags () from /usr/lib64/libpython2.6.so.1.0
#16 0x000000337b8fd17c in PyRun_SimpleFileExFlags () from /usr/lib64/libpython2.6.so.1.0
#17 0x000000337b909c32 in Py_Main () from /usr/lib64/libpython2.6.so.1.0
#18 0x000000337941ecdd in __libc_start_main () from /lib64/libc.so.6
#19 0x0000000000400649 in _start ()
catch throw from c++ program:
Catchpoint 1 (exception thrown), 0x000000337c8bccb0 in __cxa_throw () from /usr/lib64/libstdc++.so.6
(gdb) bt
#0 0x000000337c8bccb0 in __cxa_throw () from /usr/lib64/libstdc++.so.6
#1 0x00007ffff6e9610c in boost::throw_exception<danAPI::Exception> (e=...) at /usr/include/boost/throw_exception.hpp:64
#2 0x00007ffff72a065f in danAPI::Controller_Rcim::setClock (this=0x641430) at /home/chchr/src/hpsphal/storage-lib/src/Controller_Rcim.cpp:2128
#3 0x00000000004072ac in main (argc=1, argv=0x7fffffffe728) at /home/chchr/src/hpsphal/python/foo.cpp:39