Details
-
Bug
-
Status: Closed (View Workflow)
-
High
-
Resolution: Fixed
-
6.22/00
-
None
-
lxplus7
Description
hi -
We're seeing a crash in pyroot that occurs if one has derived a class from
TTree that's in a namespace, and one tries to do a getattr() on an instance
of that class.
A standalone reproducer is in the attached tarball.
The included setup script should be appriate for lxplus7.
Run:
$ . ./setup
$ ./build.sh
$ python test.py
and it should segfault.
#0 0x00007fffef8568f8 in TClass::DynamicCast(TClass const*, void*, bool) ()
|
from /cvmfs/sft.cern.ch/lcg/releases/LCG_98python3/ROOT/v6.22.00/x86_64-centos7-gcc8-opt/lib/libCore.so
|
#1 0x00007fffd9f95c63 in GetAttr(CPyCppyy::CPPInstance*, _object*) ()
|
from /cvmfs/sft.cern.ch/lcg/releases/LCG_98python3/ROOT/v6.22.00/x86_64-centos7-gcc8-opt/lib/libROOTPythonizations3_7.so
|
#2 0x00007ffff79385c9 in _PyMethodDef_RawFastCallDict (method=0x4c3afb0,
|
self=0x7fffda56b410, args=<optimized out>, nargs=1, kwargs=<optimized out>)
|
at /workspace/build/externals/Python-3.7.6/src/Python/3.7.6/Objects/call.c:497
|
The problem is in GetTClass in PyzCppHelpers.cxx:
// Get the TClass of the C++ object proxied by pyobj
|
TClass *GetTClass(const CPyCppyy::CPPInstance *pyobj)
|
{
|
return TClass::GetClass(Cppyy::GetFinalName(pyobj->ObjectIsA()).c_str());
|
}
|
This gets called with the tree object, which in this case is of type
Foo::MyTree. But GetFinalName() returns only the final component
of the name (in this case MyTree), so the class lookup fails,
leading to a segfault in the caller. Changing the call
to GetScopedFinalName appear to fix the crash.
diff --git a/bindings/pyroot/pythonizations/src/PyzCppHelpers.cxx b/bindings/pyroot/pythonizations/src/PyzCppHelpers.cxx
|
index 672817d..baaa399 100644
|
--- a/bindings/pyroot/pythonizations/src/PyzCppHelpers.cxx
|
+++ b/bindings/pyroot/pythonizations/src/PyzCppHelpers.cxx
|
@@ -43,7 +43,7 @@ PyObject *BoolNot(PyObject *value)
|
// Get the TClass of the C++ object proxied by pyobj
|
TClass *GetTClass(const CPyCppyy::CPPInstance *pyobj)
|
{
|
- return TClass::GetClass(Cppyy::GetFinalName(pyobj->ObjectIsA()).c_str());
|
+ return TClass::GetClass(Cppyy::GetScopedFinalName(pyobj->ObjectIsA()).c_str());
|
}
|
|
////////////////////////////////////////////////////////////////////////////
|