Troubleshooting: undefined reference to `non-virtual thunk to ...`

I am trying to figure out how to fix this problem further. I would also like to know how I can install a newer version of ld, if that makes sense. All involved package managers tell me that I am in the know.

The code compiles and connects and runs with g ++ (4.7.2) on ubuntu 12.04 and 12.10, but does not compile on FC17 with this error.

ArchiveServiceLib/debug-posix/libArchiveLib.a(NamedIflTiffCache.o):(.rodata._ZTV26UnlockingGenericFileHandle[_ZTV26UnlockingGenericFileHandle]+0x58): undefined reference to `IHawk::EncryptedHandle::OnNewSecretKey(IHawk::IHPGP::SecretKey&)' ArchiveServiceLib/debug-posix/libArchiveLib.a(NamedIflTiffCache.o):(.rodata._ZTV26UnlockingGenericFileHandle[_ZTV26UnlockingGenericFileHandle]+0x8c): undefined reference to `non-virtual thunk to IHawk::EncryptedHandle::OnNewSecretKey(IHawk::IHPGP::SecretKey&)' 

Ld versions:

 12.04 only reports 2.22 (no indication other than 2.22) 12.10 reports 2.22.90.20120924 fedora17 reports 2.22.52.0.1-10.fc17 20120131 

G ++ versions:

 Ubuntu 12.04 (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3 Ubuntu 12.10 (Ubuntu/Linaro 4.7.2-2ubuntu1) 4.7.2 FC 17 (GCC) 4.7.2 20120921 (Red Hat 4.7.2-2) 

The declarations for all classes that contain this method say:

 ../Include/IHawkLib/IHPGP.h: virtual bool OnNewSecretKey( SecretKey &skey ) = 0; ../Include/IHawkLib/PgpPkidParser.h: virtual bool OnNewSecretKey( SecretKey &skey ) {return true;} ../Include/IHawkLib/EncryptedFileHandle.h: virtual bool OnNewSecretKey( SecretKey &skey ); 

But it looks like g ++ forgets to pass the virtual part to ld so that it can resolve it in link / ld time. This seems to have happened in 2002 and 2009, and possibly several times, but in this case, apparently, the problem has been fixed. This time it seems platform-specific, which makes no sense, given the code that it is upset about.

Usage in which a build error occurs:

  std::auto_ptr<IHawk::EncryptedFileHandle> apTmgHandle (GetFileHandle(filename, true, false, pKeyServer)); if (apTmgHandle.get()){ 

The class conclusions are as follows:

 class EncryptedFileHandle : public EncryptedHandle { .... // Does not mention OnNewSecretKey .... } class EncryptedHandle : public IHawk::GenericHandle, protected IHawk::IHPGP { .... virtual bool OnNewSecretKey( SecretKey &skey ); // Has a concrete implementation .... } class IHPGP { .... virtual bool OnNewSecretKey( SecretKey &skey ) = 0; .... } class GenericHandle { .... // Has no clue about OnNewSecretKey .... } 

The linker team looks like this on all platforms, we use scons and until that moment could be an agnostic platform .... (sorry for the long line, I just did not want to risk confusing it with a typo:

 g++ -o debug-posix/ArchiveService -g debug-posix/StdAfx.o debug-posix/ArchiveService_PosixMain.o debug-posix/WebCommands.o -L/usr/local/lib -L/usr/lib/mysql -L/home/mjones/C++/ifl/src/IHDB/debug-posix -L/home/mjones/C++/ifl/src/IHDB -L/home/mjones/C++/ifl/src/XMLib/debug-posix -L/home/mjones/C++/ifl/src/XMLib -L/home/mjones/C++/ifl/src/IHawkLib/debug-posix -L/home/mjones/C++/ifl/src/IHawkLib -L/home/mjones/C++/ifl/src/ImageCore/debug-posix -L/home/mjones/C++/ifl/src/ImageCore -L/home/mjones/C++/ifl/libraries/z39.50/ZExtensions/debug-posix -L/home/mjones/C++/ifl/libraries/z39.50/ZExtensions -L/home/mjones/C++/ifl/src/ServerGuts/debug-posix -L/home/mjones/C++/ifl/src/ServerGuts -L/home/mjones/C++/ifl/libraries/CRUSHER/debug-posix -L/home/mjones/C++/ifl/libraries/CRUSHER -L/home/mjones/C++/ifl/libraries/jsoncpp/debug-posix -L/home/mjones/C++/ifl/libraries/jsoncpp ArchiveServiceLib/debug-posix/libArchiveLib.a -lIHDB -lXMLib -lIHawk -lImageCore -lZExtensions -lServerGuts -lCrusher -ljson -lboost_filesystem-mt -lboost_thread-mt -lboost_regex-mt -lz -lMagickWand -lcrypto++ -lcppunit -llog4cplus -lyaz -lpodofo -lmysqlclient -lxerces-c -ljpeg -lpng -ltiff 
+4
source share
1 answer

The first step to resolve the problem is to find the place where IHawk::EncryptedHandle defined. This can be done using nm in object files, for example:

 nm -po *.o | c++filt | grep IHawk::EncryptedHandle | grep -v ' U ' | less 

If the definition is obtained from a library, you can add the appropriate libraries or use *.a and *.so in the respective directories. Once a symbol is and is in the library (since the undefined link belongs to the library, it is likely that the missing symbol is also in the library), you need to make sure that the library with the missing symbol is indicated after the link to it. It has been a while since I saw this happen, but if the symbol is from the same library, you may need to run ranlib in the library.

+4
source

All Articles