c++ symbols received from backtrace_symbols does not show function in g++ - c++

I'm trying to print a backtrace in code progrematically, compiling all my source with -g, as well as linking with it, and I also added fvisibility=internal.
but when I call the symbol list, all my code looks like:
module() [0x424b69]
why does the function name does not appear in the braces, what other possible flag should I add?
Thanks.

You should use
-rdynamic
Something like:
g++ -g -rdynamic main.cpp
From http://gcc.gnu.org/onlinedocs/gcc/Link-Options.html:
-rdynamic
Pass the flag -export-dynamic to the ELF linker, on targets that support it. This instructs the linker to add all symbols, not only
used ones, to the dynamic symbol table. This option is needed for some
uses of dlopen or to allow obtaining backtraces from within a program.

Related

Undefined reference when combining C++ and Fortran [duplicate]

I am trying to link a .o file generated using g++ and another .o file generated using gfortran.
g++ -c mycppcode.cpp
produces the file mycppcode.o and the command
gfortran -c myfortrancode.f
produces the file myfortrancode.o
When I link these two files to get an output file
g++ -O mycppcode.o myfortrancode.o
I get the following error
Undefined symbols for architecture x86_64:
"__gfortran_pow_c8_i4", referenced from:
Could some one help me with this? Should I use another compiler? Also, I would like to know what functions or subroutines call "__gfortran_pow_c8_i4", so that I can try to avoid these functions or subroutines in fortran in future.
The following assumes you are using the GNU compiler tools. Things may be slightly different if you are using other compilers.
You can use either compiler to link the two together, but you need to provide the appropriate libraries.
Typically, you can use either
gfortran fortobj.o cppobj.o -lstdc++
or
g++ fortobj.o cppobj.o -lgfortran
This assumes that you are using a setup where both compilers know about each other's libraries (like if you installed through a linux repository).
In the case of the OP the C compilers came from XCode and gfortran is from homebrew. In that case, gfortran knows about the g++ libraries (since they were used to compile the compiler), but g++ doesn't know about the gfortran libraries. This is why using gfortran to link worked as advertised above. However, to link with g++ you need to add the path to libgfortran.* when you call the linker using the -L flag, like
g++ fortobj.o cppobj.o -L/path/to/fortran/libs -lgfortran
If for some reason your gfortran compiler is unaware of your g++ libs, you would do
gfortran fortobj.o cppobj.o -L/path/to/c++/libs -lstdc++
Note that there shouldn't be any difference in the final executable. I'm no compiler expert, but my understanding is that using the compiler to link your objects together is a convenience for calling the linker (ld on UNIX-like OS's) with the appropriate libraries associated with the language you are using. Therefore, using one compiler or the other to link shouldn't matter, as long as the right libraries are included.

How can I tell GCC to use custom library for -l instead of the system one?

I have a custom build of SQLite3 at /somepath, so /somepath/.libs contains libsqlite3.so.0.8.6 and the symbolic links to it. I wanted to link a program against it and assumed
g++ -O3 -g -fPIC -I /somepath -I /somepath/src -L /somepath/.libs -lsqlite3 -o myfile.so myfile.cpp
would work. It compiles, but I get a segmentation fault due to some problem in my code, and when trying to debug I run into the issues which look like LD_PRELOAD not working with my program and Setting my lib for LD_PRELOAD makes some processes produce loader errors: I can run LD_PRELOAD=myfile.so /somepath/sqlite3 ..., but under GDB I get symbol lookup error and LD_DEBUG=all LD_PRELOAD=myfile.so gdc -c core /somepath/sqlite3 ... reveals symbols are getting looked up in /usr/lib/x86_64-linux-gnu/libsqlite3.so.0 instead of /somepath/libsqlite3.so.0, and unsurprisingly missing the symbols for functions added in the custom build. How can I fix this and debug my code?
The -lsqlite3 argument should be last. Order of arguments to g++ matters a lot. You should read more about runpath and perhaps pass -Wl,-rpath,/somepath/.libs
You may want to pass -v once to g++ to understand what is happening (what programs are actually running). You might also pass -Wl,--verbose to ask a more verbose link.
Then you can use ldd on your executable (and also readelf) to find out more what are its link time dependencies.
With suitable arguments to g++ you should not need additional options to gdb
From http://visualgdb.com/gdbreference/commands/set_solib-search-path
Inside gdb use the commands below.
set solib-search-path [Directories]
show solib-search-path

NVCC attempting to link unnecessary objects

I have a project that I'm working on making run with CUDA. For various reasons, it needs to compile an executable either with or without GTK support, without recompiling all of the associated files. Under C, I accomplished this by compiling a base version of the objects to *.o and a GTK version of the objects to *.gtk.o. Thus, I can link to that library and if it needs to use GTK it will pull in those functions (and their requirements); if it doesn't it won't touch those objects.
Converting to nvcc has caused some issues: it works in either always or never GTK mode; but if I compile the libraries with the additional GTK objects, it refuses to ignore them and link a GTKless executable. (It fails with errors about being unable to find the cairo functions I call.)
I'm guessing that nvcc is linking to (at least one of) its helper functions embedded in the object, which is causing the linker to resolve the entire object.
Running ar d <lib> <objects.gtk.o> to manually strip them from the library will "fix" the problem, so there isn't a real dependency there.
I'm compiling/linking with
/usr/local/cuda/bin/nvcc --compiler-options -Wall --compiler-options -pipe
-rdc=true -O0 -g -G -I inc -I inc/ext -arch compute_20 -o program
program.cu obs/external.o libs/base.a libs/extra.a libs/core.a -lm
How can I get nvcc to ignore the unneeded objects?
How can I get nvcc to ignore the unneeded objects?
Before you can achieve that, you need to understand which symbol is causing the *.gtk.o objects to be pulled in from the library when they shouldn't be.
The way to do that is to run link with -Wl,--print-map, and look for linker messages such as:
Archive member included because of file (symbol)
libfoo.a(foo.o) main.o (foo)
Above, main.o referenced foo, which is defined in libfoo.a(foo.o), which caused foo.o to be pulled in into the main binary.
Once you know which symbols cause xxxx.gtk.o to be pulled into the link, searching the web and/or NVidia documentation may reveal a way to get rid of them.

Undefined Reference Error When Linking to Static Library

I am trying to compile a project that depends on the Xerces XML Parser. The project compiles for Windows without any difficulty, but I'm having some trouble compiling it with g++ in Cygwin.
In order to use Xerces, I am trying to compile my code against the static library libxerces-c.a. But when I do so, I get errors that look like this:
/tmp/cc2QGvMh.o:test.cpp:(.text+0x3a): undefined reference to `xercesc_2_8::DOMImplementationRegistry::getDOMImplementation(unsigned short const*)'
I've inspected the static library using ar, and confirmed that it contains the DOMImplementationRegistry.o file that defines the function that I am calling.
ar -t libxerces-c.a
...
DOMImplementationImpl.o
DOMImplementationRegistry.o
DOMLocatorImpl.o
...
I've also extracted the object files from the library, and used 'nm' to make sure that the function I am calling actually exists:
ar -x libxerces-c.a
nm --demangle DOMImplementationRegistry.o
...
00000080 T xercesc_2_8::getDOMImplSrcVectorMutex()
00000300 T xercesc_2_8::DOMImplementationRegistry::getDOMImplementation(unsigned short const*)
000002a0 T xercesc_2_8::DOMImplementationRegistry::addSource(xercesc_2_8::DOMImplementationSource*)
...
Since I can compile everything for Windows but not with g++, I thought that the error could be in the linker order (similar to the problem described in this question). However, even after changing the linker order, I am still getting the same compiler error. I have tried both
g++ -o test.exe test.cpp -Llib -lxerces-c
and
g++ -o test.exe test.cpp lib/libxerces-c.a
Any ideas?
Your project uses method from xercesc_2_6 namespace as pointed by compiler error message but your library offers xercesc_2_8 version. Problem is probably caused by mismatch between headers you use and library object file.
You didn't say the source of the archive. If it isn't compiled with cygwin, it could be a name mangling problem. Compiling the library from source might well fix this.
It could also be that the archive is built incorrectly so that it has internal resolution problems. Try giving the library name twice.
g++ -o test.exe test.cpp lib/libxerces-c.a lib/libxerces-c.a
If this works, the archive is broken and you should look for or build a new one.
Try the linker option --enable-stdcall-fixup (see 'man ld'). It will care for name mangling and calling conventions:
g++ -o test.exe test.o -Wl,--enable-stdcall-fixup -Llib -lxerces-c

Missing symbols from static library in linked executable

I have a problem with static library symbols missed in linked executable.
Here is the description of my problem:
I have static library built from several object files. These object files provides sevaral groups of symbols, associated with:
A set of C functions and structs (several object files). Let's call corresponding symbols level1 symbols.
A set of C++ wrapper classes for this C functions and structs (another object file). Let's call corresponding symbols level2 symbols.
A set of C++ wrapper classes inhereted from level 2 classes (another object file) with extended functionality. Let's call corresponding symbols level3 symbols.
Undeground C code uses several other project and external libs. Some of them are static, so currently this lib is static too.
Library is linked with executable file. This file used directly only level2 symbols from lib. But some dynamic libraries loaded by this executable during execution needs level3 symbols.
The problem is, that level3 symbols for some reason are missed into this executable(nm approved).
Library itself contains all groups of symbols. ALso there is another executable linked with this library and it also contains all groups of symbols. The main difference between these executables is that second executable (where all symbols are presented) uses leve3 symbols directly.
The whole project is built with CMake in debug configuration (this means "-g" option is presented in g++ commands). The underlying OS is GNU/Linux x86_64. g++ version is 4.4.
I've checked several similiar questions on StackOverflow but I haven't found any acceptable solution.
I've already tried several linking options to solve the problem (--export-dynamic, --whole_archive) but neither helps.
I'll be glad to see any ideas to solve this problem or, at least, possible reasons of this strange behaviour.
This is command line used to build executable. Command was generated by CMake. I only add --whole_archive option, then delete executable and rerun command. I also hope you will excuse me for replacing all project specific names with "???".
exec_name - name of executable we are talking about
lib_name - name of library we are talking about
/usr/bin/c++ - symlink to g++ v4.4 executable
/usr/bin/c++ -Wextra -g -fPIC CMakeFiles/exec_dir.dir/main.cpp.o CMakeFiles/exec_dir.dir/options.cpp.o CMakeFiles/exec_dir.dir/runtime.cpp.o CMakeFiles/exec_dir.dir/plugins.cpp.o CMakeFiles/exec_dir.dir/CServer.cpp.o -o exec_name -rdynamic ../lib/???/lib???.a --whole-archive ../../lib/???/???/lib_name.a ../lib/???/lib???.so ../../lib/???/???/lib???.a ../../???/???/lib???.a ../../lib/???/lib???.a -ldl -lboost_filesystem -lboost_signals -lboost_system -lboost_thread ../../lib/???/lib???.so /usr/local/ssl/lib64/libcrypto.so -ldl -luuid -lodbc ../lib/log/lib???.so ../lib/config/lib???a -lpthread ../../???/???/lib???.a -Wl,-rpath,/home/beduin/???/build/deb/???/lib/???:/home/beduin/???/build/deb/lib/???:/usr/local/ssl/lib64
Use -rdynamic -Wl,-whole-archive <all your libs> -Wl,-no-whole-archive <boost, pthread and so on> - one of your libs aren't within --whole-archive