I'm stuck on a runtime error "undefined symbol: _ZTIN5eckit9ExceptionE" like this
Start 2: basic_python
2: Test command: /usr/local/Python/2.7.10/bin/python "coast.py"
2: Environment variables:
2: PYTHONPATH=/opt/src/ecmwf/Magics-2.29.4-Source/build/python
2: LD_LIBRARY_PATH=/opt/src/ecmwf/Magics-2.29.4-Source/build/lib
2: MAGPLUS_HOME=/opt/src/ecmwf/Magics-2.29.4-Source/test/..
2: OMP_NUM_THREADS=1
2: Test timeout computed to be: 1500
2: Traceback (most recent call last):
2: File "coast.py", line 11, in <module>
2: from Magics.macro import *
2: File "/opt/src/ecmwf/Magics-2.29.4-Source/build/python/Magics/__init__.py", line 32, in <module>
2: _Magics = swig_import_helper()
2: File "/opt/src/ecmwf/Magics-2.29.4-Source/build/python/Magics/__init__.py", line 28, in swig_import_helper
2: _mod = imp.load_module('_Magics', fp, pathname, description)
2: ImportError: /usr/local/Magics/2.29.4/gnu/4.4.7/lib/libMagPlus.so: undefined symbol: _ZTIN5eckit9ExceptionE
There was no error while building shared libaray libMagPlus.so. The error just was raised at runtime when Python module loading it.
Checked with nm, the undefined symbol '_ZTIN5eckit9ExceptionE' is from a static library libOdb.a, like this
nm libOdb.a | grep _ZTIN5eckit9ExceptionE
U _ZTIN5eckit9ExceptionE
U _ZTIN5eckit9ExceptionE
U _ZTIN5eckit9ExceptionE
U _ZTIN5eckit9ExceptionE
U _ZTIN5eckit9ExceptionE
U _ZTIN5eckit9ExceptionE
0000000000000000 V DW.ref._ZTIN5eckit9ExceptionE
U _ZTIN5eckit9ExceptionE
U _ZTIN5eckit9ExceptionE
U _ZTIN5eckit9ExceptionE
U _ZTIN5eckit9ExceptionE
U _ZTIN5eckit9ExceptionE
U _ZTIN5eckit9ExceptionE
But there was no any complaint about undefined symbol '_ZTIN5eckit9ExceptionE' for the excutables which linked against the static library libOdb.a directly at the both of complation time and runtime time. All C, Fortran codes also worked well with the static library libOdb.a, except the shared library libMagPlus.so.
The library LibMagPlus.so was linked like this
/usr/bin/g++ -fPIC -pipe -O2 -g \
-Wl,--disable-new-dtags -shared \
-Wl,-soname,libMagPlus.so -o ../lib/libMagPlus.so \
... ... \
-Wl,-Bstatic -L$ODB_API/lib -lOdb \
... ...
The library libOdb.a was built like this
usr/bin/ar qc ../../lib/libOdb.a ... ...
/usr/bin/ranlib ../../lib/libOdb.a
Searched the FAQ and Googled, little help with my problem. I knew little about C++, and have no idea how to get this fixed.
[ In response to Jorge's inputs, updated these ]
Exceptions.h
#ifndef eckit_Exceptions_h
#define eckit_Exceptions_h
#include <errno.h>
#include "eckit/eckit.h"
#include "eckit/eckit_version.h"
#include "eckit/log/CodeLocation.h"
#include "eckit/log/Log.h"
#include "eckit/log/SavedStatus.h"
#include "eckit/compat/StrStream.h"
namespace eckit {
//-----------------------------------------------------------------------------
void handle_panic(const char*);
void handle_panic(const char*, const CodeLocation&);
/// @brief General purpose exception
/// Derive other exceptions from this class and implement then in the class that throws them.
class Exception : public std::exception {
public: // methods
/// Constructor with message
Exception(const std::string& what, const CodeLocation& location = CodeLocation() );
/// Destructor
/// @throws nothing
~Exception() throw();
virtual const char *what() const throw() { return what_.c_str(); }
virtual bool retryOnServer() const { return false; }
virtual bool retryOnClient() const { return false; }
virtual bool terminateApplication() const { return false; }
static bool throwing();
static void exceptionStack(std::ostream&,bool callStack = false);
const std::string& callStack() const { return callStack_; }
protected: // methods
void reason(const std::string&);
Exception();
virtual void print(std::ostream&) const;
private: // members
std::string what_; ///< description
std::string callStack_; ///< call stack
SavedStatus save_; ///< saved monitor status to recover after destruction
Exception* next_;
CodeLocation location_; ///< where exception was first thrown
friend std::ostream& operator<<(std::ostream& s,const Exception& p)
{
p.print(s);
return s;
}
};
nm -Cl $ODB_API/lib/libOdb.a | grep -i "eckit::Exception"
U eckit::Exception::Exception(std::string const&, eckit::CodeLocation const&) /opt/src/OdbAPI-0.10.2-Source/eckit/src/eckit/exception/Exceptions.h:84
U eckit::Exception::~Exception() /opt/src/OdbAPI-0.10.2-Source/eckit/src/eckit/exception/Exceptions.h:108
0000000000000000 W eckit::Exception::retryOnClient() const /opt/src/OdbAPI-0.10.2-Source/eckit/src/eckit/exception/Exceptions.h:48
0000000000000000 W eckit::Exception::retryOnServer() const /opt/src/OdbAPI-0.10.2-Source/eckit/src/eckit/exception/Exceptions.h:47
0000000000000000 W eckit::Exception::terminateApplication() const /opt/src/OdbAPI-0.10.2-Source/eckit/src/eckit/exception/Exceptions.h:49
0000000000000000 W eckit::Exception::what() const /opt/src/OdbAPI-0.10.2-Source/eckit/src/eckit/exception/Exceptions.h:46
U eckit::Exception::print(std::ostream&) const
U typeinfo for eckit::Exception
I also tried to unpack all object files from libOdb.a and relink libMagPlus.so with all of them with option '-fvisibility=default -rdynamic', like this
ar x libOdb.a ( ./Odb )
/usr/bin/g++ -fvisibility=default -rdynamic -fPIC -pipe -O2 -g \
-Wl,--disable-new-dtags -shared \
-Wl,-soname,libMagPlus.so -o ../lib/libMagPlus.so \
... ... \
./Odb/*.o \
... ...
But still got these undefined symbols
U eckit::Exception::~Exception() /opt/src/OdbAPI-0.10.2-Source/eckit/src/eckit/exception/Exceptions.h:108
U eckit::Exception::print(std::ostream&) const
U typeinfo for eckit::Exception
Wondering if needs to touch Exceptions.h and how to touch it ?
Anybody can help ?
Appreciating your time
Regards