Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

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
                I've done a grep -R OnNewSecretKey in /usr/include and /usr/local/include and find no matches....
– boatcoder
                Jan 3, 2013 at 22:40
                The interesting bit would be how you invoked the compiler to link the executable. It looks as if you either didn't include the object file for IHawk::EncryptedHandle or put the library containing its definition before the library libArchiveLib.a (or the -lArchiveLib option).
– Dietmar Kühl
                Jan 3, 2013 at 22:41
                I updated the end of the question to show that.  It does successfully link on 2 of 3 platforms with the same command.
– boatcoder
                Jan 3, 2013 at 22:53
                Is the missing symbol defined in libIHawk.a? (this seems to be a logical place for it to reside) This library would be in the correct location. Also, make sure that the libraries are build with compatible link options: if there are warnings about not found or ignored libraries these may be relevant.
– Dietmar Kühl
                Jan 3, 2013 at 22:58
                I'm thinking this is a bug in ld.  It is failing to go up the derivation tree to the base class to find the method.  Luckily I was able to switch from FC17 back to debian which has a newer version of ld.  This is not the first time this bug has popped up (bug might be in g++ instead of ld, but at this point that question is moot).
– boatcoder
                Jan 24, 2013 at 23:56

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.

That may indeed be the problem, but ranlib won't run on .so files. How do you deal with that? – boatcoder Jan 3, 2013 at 23:32 This didn't help solve the problem, but it did help me understand where the problem is. And the c++filt thing is awesome. – boatcoder Jan 24, 2013 at 23:57 I have the same problem, and i have followed the instruction, but not solved my problem. I found the symbol in the lib file, but the link also get the errors. I don't why? – Jimmy Oct 10, 2018 at 2:08 I used the above command to search the build tree of a multi-target project to find where the required symbols were being defined. I used find instead of *.o and needed to drop the pipe to | grep -v ' U ' | less. My command was find . -name "*.o" -exec ~/myScripts/checkSymbols.sh '{}' \; with nm -po "$1" | c++filt | grep MY::Symbol inside the script. – gone Feb 24, 2020 at 8:19

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.