Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to troubleshoot: undefined reference to `non-virtual thunk to ...`

Tags:

c++

g++

I'm trying to figure out how to troubleshoot this further. I'd also like to know how I could install a newer version of ld if that makes sense. All the package managers involved tell me that I'm up to date.

The code compiles and links and runs with g++ (4.7.2) on ubuntu 12.04 and 12.10, but fails to 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&)'

Versions of ld:

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

Versions of g++:

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 the 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 is like g++ forgets to pass the virtual part on to ld so that it can resolve it at link/ld time. This appears to have happened back in 2002 and 2009, and maybe a few other times, but in that case the later version appears to have fixed the problem. This time, it appears to be platform specific which makes no sense given the code it is upset about.

The usage where the build error comes from is:

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

The Class derivations look like:

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 command looks like this on all platforms, we are using scons and up to this point have been able to be platform agnostic.... (sorry for the long line, just didn't want to risk messing it up 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
like image 485
boatcoder Avatar asked Jan 03 '13 22:01

boatcoder


1 Answers

The first step to troubleshoot the problem is to locate the place where IHawk::EncryptedHandle is defined. This can be done using nm on the object files, e.g.:

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

If the definition comes from a library, you can add the corresponding libraries or use *.a and *.so on the appropriate directories. Once the symbol is located and is in a library (since the undefined reference is from a library, it is likely that the missing symbol is in a library, too), you need to make sure that the library with the missing symbol is specified after the one referencing it. It is a while since I saw it happen but if the symbol is from the same library you might need to run ranlib on the library.

like image 105
Dietmar Kühl Avatar answered Oct 07 '22 02:10

Dietmar Kühl