undefined symbol when using -c compiling option

{

std::vector<int> v;

v.push_back(1);

}

after I compile the code above in a library using the -c option and I run nm -u I see an undefined symbol:

__1cDstdGvector4Cin0AJallocator4CiM__insert_aux6Mpirki_v_

The library is loaded using dlopen by an external executable. The executable crashes and my guess is that it happens because of that symbol. Any suggestions are most welcome. Thank you.

Message was edited by:

oulisee

[483 byte] By [oulisee] at [2007-11-26 9:32:05]
# 1
Please show the complete command line you are using to compile the source file that has this code.Please also list the compiler and version you are using. If it is Sun C++, run the commandCC -Vto find the version.
clamage45 at 2007-7-7 0:18:06 > top of Java-index,Development Tools,Solaris and Linux Development Tools...
# 2
Good point clamage45 .Here it is:CC -VCC: Sun WorkShop 6 update 2 C++ 5.3 Patch 111685-22 2005/04/29and the compiling command I use is justCC -c test.cppPlease advise. Thanks.
oulisee at 2007-7-7 0:18:06 > top of Java-index,Development Tools,Solaris and Linux Development Tools...
# 3

I didn't realize you were using such an old compiler. You really, really should upgrade to the current release, Sun Studio 11, which is free. You can get it here:

http://developers.sun.com/sunstudio/

C++ 5.3 uses a template cache to hold template instances that are generated. The missing symbol is in the cache, but apparently you built your library without including the template instances from the cache.

If you use the CC command (instead of the ld command) to build your shared library, template instances will be included automatically in the shared library.

Here is an example command to build libXXX.so:

CC -G -o libXXX.so -zdefs. *.o -lCstd -lCrun -lc

We recommend using -zdefs when building a shared library. The option causes the linker to complain about unresolved symbols, so you get a problem at library build time instead at program run time. Usually, it's easy to tell what you need to include in the link to get any missing symbols.

As explained in the C++ User's Guide chapter on building libraries, you need to list explicitly the system libraries your library depends on. Unlike when building an executable, no libraries are included automatically. Listing the dependencies explicitly ensures that those libraries get loaded before code in your library begins to run.

By default, C++ 5.3 does not link libCstd.so, but picks up the static (.a) version from the compiler area. We recommend that you modify the compiler installation, as descirbed in the documentation, to link the dynamic (.so) version instead. All compilers since C++ 5.3 link the dynamic version by default.

If you upgrade to any recent compiler (Sun Studio 8 or later, C++ 5.5), the compiler by default no longer uses a template cache. All the problems created by needing a cache vanish.

Newer compilers generate better code, run faster, support modern hardware and OS versions, and have better development tools. Unless you need to support obsolete versions of Solaris older than Solaris 8, you should upgrade as soon as possible to Sun Studio 11.

clamage45 at 2007-7-7 0:18:06 > top of Java-index,Development Tools,Solaris and Linux Development Tools...
# 4

Thank you very much for the reply clamage45.

I will indeed push for the upgrade of the compiler. Unfortunately, there are people here that consider the upgrade being a serious risk, believing that the production environment needs to be updated as well. As most organizations, we have DEV, UAT and PROD environments, all with the same operating system version. Now, things are working fine in UAT and PROD but I am not able to use STL. Can you please comment on the risks involved when compiling code with a new version of the compiler and then porting the libraries in PROD? The libraries are invoked using dlopen by a third party executable we don't have control upon. Thank you.

oulisee at 2007-7-7 0:18:06 > top of Java-index,Development Tools,Solaris and Linux Development Tools...
# 5

You should be able to fix your problem without changing compilers by following the suggestions I outlined already.

Sun supports binary compatibility going forward: You can link a binary created by an older compiler into a program created by a newer compiler, but you must use the newer compiler to build the program.

In general, you cannot link a binary created by a newer compiler into a program being built with an older compiler.

The reason for the one-way compatibility has mostly to do with interface changes. A newer compiler might depend on interfaces not available in an older compiler or its runtime libraries, but the newer compiler continues to allow interfaces defined by older compilers and libraries.

If you build a shared library to be used by another application written in C++, you might run into problems if that application was built by an older compiler. If the application does not use C++, the compiler you use to build your shared library probably does not matter.

As I discussed before, your shared library must be built with explicit depenencies on all the system libraries it needs. Newer compilers have dependencies on newer versions of system libraries. (Each release requires a patch level of system libraries to work properly.) Your shared library can inherit a dependency on the newer system library versions, which might require clients to upgrade their systems.

The rule we recommend to address all these issues is a simple one:

Decide on the earliest compiler version and the earliest Solaris version that you intend to support. Build and test your code using a system configured exactly that way. Your binaries can then be used on later versions of Solaris, and with later compiler versions.

clamage45 at 2007-7-7 0:18:06 > top of Java-index,Development Tools,Solaris and Linux Development Tools...
# 6

I don't think I answered your question about risks associated with changing compilers.

When you make a huge jump like C++ 5.3 to C++ 5.8, you will probably spend time fixing errors that the old compiler didn't complain about, and making adjustment to makefiles due to the different template compilation model. The build issues would occur only if you used -instances= or -template= options, or if the build process refers explicitly to template cache directories.

It is also possible that code having undefined behavior that the compiler doesn't flag could behave differently.

You therefore want to allocate some time to make the changeover, preferably at the beginning of a new development cycle. I would start by taking the sources from the previous release and building them with the new compiler, then running all the same tests. When it all builds and passes testing, you can proceed with confidence.

C++ 5.3 is End Of Life, meaning little support is available for it. It is not supported at all on Solaris 10. It does not support current processors, generating code by default for obsolete processors. The code will run on modern processors, but will not be efficient.

The current compilers run faster, generate better code, support current versions of Solaris (and now Linux in the Sun Studio Express preview version), and support modern hardware. I would advise any company that is not locked into obsolete hardware and software to plan to upgrade as development schedules permit.

clamage45 at 2007-7-7 0:18:06 > top of Java-index,Development Tools,Solaris and Linux Development Tools...