魔法 - 未定义的符号:_ZTIN5eckit9ExceptionE
MAGICS - undefined symbol: _ZTIN5eckit9ExceptionE
我遇到这样的运行时错误"undefined symbol: _ZTIN5eckit9ExceptionE"
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
构建共享库时没有错误 libMagPlus.so。该错误只是在 Python 模块加载它时在运行时引发的。
用 nm 检查,未定义的符号 '_ZTIN5eckit9ExceptionE' 来自静态库 libOdb.a,像这样
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
但是在编译时和运行时直接链接到静态库libOdb.a的可执行文件没有任何关于未定义符号'_ZTIN5eckit9ExceptionE'的投诉。除了共享库 libMagPlus.so,所有 C、Fortran 代码也可以很好地与静态库 libOdb.a 配合使用。
库 LibMagPlus.so 是这样链接的
/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 \
... ...
库libOdb.a是这样构建的
usr/bin/ar qc ../../lib/libOdb.a ... ...
/usr/bin/ranlib ../../lib/libOdb.a
搜索常见问题解答和谷歌搜索,对我的问题帮助不大。我对 C++ 知之甚少,也不知道如何解决这个问题。
[为了回应 Jorge 的意见,更新了这些]
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
我还尝试从 libOdb.a 中解压缩所有目标文件并使用选项“-fvisibility=default -rdynamic”重新链接 libMagPlus.so,就像这样
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 \
... ...
但还是得到了这些未定义的符号
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
想知道是否需要触摸Exceptions.h以及如何触摸?
有人可以帮忙吗?
感谢您的宝贵时间
此致
查看 Exceptions.h
文件。请注意所有未定义的符号如何属于 已声明但未定义的函数 。
~Exception() throw();
// [...]
virtual void print(std::ostream&) const;
eckit::Exception::~Exception()
是您的析构函数(在 Exceptions.h:108
中声明但未定义)。同样适用于 eckit::Exception::print(std::ostream&) const
.
在 typeinfo for eckit::Exception
的情况下,这里的问题是您有未声明为 纯虚拟 的虚函数(抽象 classes ), 但都没有定义,所以类型不完整。
如果我没记错的话,因为 eckit::Exception
class 对于其他派生的 class 来说是超级 class,它的析构函数应该被声明为 virtual
也是。
检查那些缺失的函数声明在哪里。它们应该在存档器的目标文件 skipped/missed 中(如果缺少的函数在 .cpp
文件中定义)或在您未包含的头文件中(如果它们在 .cpp
中定义=19=] 文件).
另请参阅:g++ undefined reference to typeinfo
我遇到这样的运行时错误"undefined symbol: _ZTIN5eckit9ExceptionE"
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
构建共享库时没有错误 libMagPlus.so。该错误只是在 Python 模块加载它时在运行时引发的。
用 nm 检查,未定义的符号 '_ZTIN5eckit9ExceptionE' 来自静态库 libOdb.a,像这样
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
但是在编译时和运行时直接链接到静态库libOdb.a的可执行文件没有任何关于未定义符号'_ZTIN5eckit9ExceptionE'的投诉。除了共享库 libMagPlus.so,所有 C、Fortran 代码也可以很好地与静态库 libOdb.a 配合使用。
库 LibMagPlus.so 是这样链接的
/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 \
... ...
库libOdb.a是这样构建的
usr/bin/ar qc ../../lib/libOdb.a ... ...
/usr/bin/ranlib ../../lib/libOdb.a
搜索常见问题解答和谷歌搜索,对我的问题帮助不大。我对 C++ 知之甚少,也不知道如何解决这个问题。
[为了回应 Jorge 的意见,更新了这些]
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
我还尝试从 libOdb.a 中解压缩所有目标文件并使用选项“-fvisibility=default -rdynamic”重新链接 libMagPlus.so,就像这样
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 \
... ...
但还是得到了这些未定义的符号
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
想知道是否需要触摸Exceptions.h以及如何触摸?
有人可以帮忙吗?
感谢您的宝贵时间
此致
查看 Exceptions.h
文件。请注意所有未定义的符号如何属于 已声明但未定义的函数 。
~Exception() throw();
// [...]
virtual void print(std::ostream&) const;
eckit::Exception::~Exception()
是您的析构函数(在 Exceptions.h:108
中声明但未定义)。同样适用于 eckit::Exception::print(std::ostream&) const
.
在 typeinfo for eckit::Exception
的情况下,这里的问题是您有未声明为 纯虚拟 的虚函数(抽象 classes ), 但都没有定义,所以类型不完整。
如果我没记错的话,因为 eckit::Exception
class 对于其他派生的 class 来说是超级 class,它的析构函数应该被声明为 virtual
也是。
检查那些缺失的函数声明在哪里。它们应该在存档器的目标文件 skipped/missed 中(如果缺少的函数在 .cpp
文件中定义)或在您未包含的头文件中(如果它们在 .cpp
中定义=19=] 文件).
另请参阅:g++ undefined reference to typeinfo