PyRoot terminate execution after first C++ thrown exception

Hello,

I would like to know if the following behavior is known and if there are any other root approach that I should use:

C++ code:

void func() { try { throw "exception"; } catch (...) { std::cout << "I could catch it!" << std::endl; } }

And run it via PyRoot, the program will exit with the following message:

Is there any workaround for this?

Thanks in advance!

Hi,

what version of ROOT are you using?
In ROOT 6.04 this is ok:

void func() {
  try {
    throw "exception";
  } catch (...) {
    std::cout << "I could catch it!" << std::endl;
  }
}

Cheers,
Danilo

Hi Danilo,

I’m using 6.02/12. But I’m accessing the function through dictionaries generated with reflex on PyRoot. If you cannot reproduce this, tell me so that I’ll build a SSCCE.

Cheers,
Werner.

Bunch of ROOT6 releases don’t support mapping exceptions due to JIT limitations. Most recent is good.

-Dom

Hi werner,

As dominique correctly points out, the first release supporting exceptions in jitted code is 6.04.
The workaround suggested for 6.02 is to handle the exceptions directly in c++.

Cheers,
Danilo

Hello Danilo, Dominique,

thanks for the information. However, the catch block that I’m using is on C++, if I understood correctly, then this this work on 6.02, right? What I believe that is happening is as soon PyRoot passes through one throw C++ code, it terminates the execution, even if I have a catch block as I showed here before…

Cheers,
Werner.

Only if in C++ library compiled and linked with C++ compiler.

Compare:[code]$ root -b -q

| Welcome to ROOT 6.02/13 http://root.cern.ch |
| (c) 1995-2014, The ROOT Team |
| Built for linuxx8664gcc |
| From heads/v6-02-00-patches@v6-02-12-6-gc8c3a57, Jul 06 2015, 12:05:01 |

Try ‘.help’, ‘.demo’, ‘.license’, ‘.credits’, ‘.quit’/‘.q’

root [0]
cat toto.cxx #include <iostream> void func() { try { throw "exception"; } catch (...) { std::cout << "I could catch it!" << std::endl; } } g++ -shared -o truc.so toto.cxx -fpic
$ python

import ROOT
ROOT.gSystem.Load(‘truc.so’)
0
ROOT.gInterpreter.Declare(‘void func();’)
True
ROOT.func()
I could catch it!
[/code]
v.s.:$ python import ROOT ROOT.gROOT.LoadMacro('toto.cxx') 0 ROOT.func() terminate called after throwing an instance of 'char const*' [1] 11290 abort python
-Dom

Hi Dominique,

I’m importing the reflection library via:

import cppyy cppyy.loadDict('RingerSelectorTools_Reflex')

This should be analog to the second case, then? Should this work on 6.04 (although unfortunately I can’t change the ROOT version as it is defined by RootCore…)?

Thanks,
Werner.

[quote=“Dominique”]Only if in C++ library compiled and linked with C++ compiler.

Compare:[code]$ root -b -q

| Welcome to ROOT 6.02/13 http://root.cern.ch |
| (c) 1995-2014, The ROOT Team |
| Built for linuxx8664gcc |
| From heads/v6-02-00-patches@v6-02-12-6-gc8c3a57, Jul 06 2015, 12:05:01 |

Try ‘.help’, ‘.demo’, ‘.license’, ‘.credits’, ‘.quit’/‘.q’

root [0]
cat toto.cxx #include <iostream> void func() { try { throw "exception"; } catch (...) { std::cout << "I could catch it!" << std::endl; } } g++ -shared -o truc.so toto.cxx -fpic
$ python

import ROOT
ROOT.gSystem.Load(‘truc.so’)
0
ROOT.gInterpreter.Declare(‘void func();’)
True
ROOT.func()
I could catch it!
[/code]
v.s.:$ python import ROOT ROOT.gROOT.LoadMacro('toto.cxx') 0 ROOT.func() terminate called after throwing an instance of 'char const*' [1] 11290 abort python
-Dom[/quote]

Reflex is dead in R6, so don’t know what the above is. More likely autoloader brings in actual ‘func’. That would be first case, unless ‘func’ is defined in header (inline or template).

-Dom

Indeed, it is a template. I’ve tried using cppyy.loadDict('RingerSelectorTools') and got the same result, so in fact the “_reflex” library was unnecessary.

Hi Werner,

I am glad you converged on a solution.
On the other hand if you are only interested to interactivity in PyROOT (i.e. no I/O), you do not even need dictionaries.
It is enough to load the shared library and inject the header in the interpreter.
For example:
MyClass.h

#ifndef __MyClass__
#define __MyClass__
#include <cstdio>

class MyClass{
public:
 void Greet();
};
#endif

MyClass.cpp

#include "myclass.h"
void MyClass::Greet(){printf("Hello!\n");}

Compilation line and python:

g++ -o libMyclass.so -shared -fPIC `root-config --libs --cflags` Myclass.cpp -I ./
python
>>> import ROOT
>>> ROOT.gSystem.Load('libMyClass.so')
0
>>> ROOT.gInterpreter.ProcessLine('#include "myClass.h"')
0L
>>> a=ROOT.MyClass()
>>> a.Greet()
Hello!

Cling is a much more powerful interpreter than the ROOT5 one, CINT, and reflection for interactivity is guaranteed even without dictionaries.

Cheers,
Danilo