Why am I losing exceptions with SWIG, C ++, python

I'll go crazy. 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 can not catch my Exceptions inside the 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

The same C ++ code that actually blocks 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

Players:

custom Exception class
SWIG 2.0.12
boost 1.41 throw_exception

Excerpt 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 is my .i file (hdrs macros are populated 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 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 caught inside my library. There should be 3 exceptions thrown by my library and then caught by my SWIG code.

This was discovered inside:

#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 had to get 2 more from setControllerClock () to:

#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
+4
1

.i %exception try , catch , , . , , , , - , Python ( ? SWIG , ). exception.i, 11.1.7 SWIG. ,

%include exception.i       

%exception {
    try {
        $action
    } catch(const danAPI::Exception& e) {
        SWIG_exception(SWIG_ValueError, "Dan API exception");
    } catch(const std::exception& e) {
        SWIG_exception(SWIG_UnknownError, "Standard exception");
    } catch(const boost::exception& e) {
        SWIG_exception(SWIG_UnknownError, "Boost exception");
    } catch(...) {
        SWIG_exception(SWIG_RuntimeError, "Unknown exception");
    }
}

, , SWIG_exception , SWIG $, , SWIG API Python Python.

:

, catch, ++ . (setControllerClock), ++ setClock, , , , . , SWIG Python. .

: a throw std::runtime_error("test") $action. catch, e.what() "test":

%exception {
    try {
        $action
        throw std::runtime_error("test");
    } catch(const danAPI::Exception& e) {
        SWIG_exception(SWIG_ValueError, "Dan API exception");
    } catch(const std::exception& e) {
        SWIG_exception(SWIG_UnknownError, "Standard exception");
+3

Source: https://habr.com/ru/post/1531059/


All Articles