Using libunwind in a shared library - c++

I want to provide a generic call stack function as part of a library (.so) using libunwind. However, executables linked against the .so start to fail as soon as I link against libunwind. As I understand it, the problem I'm running into is that libunwind defines the same symbols as the GCC runtime, but the implementation is seemingly not compatible.
Linking statically or dynamically against libunwind doesn't change anything, I get a segfault when throwing an exception in _Unwind_Resume (if linked statically), otherwise the call-stack starts at __cxa_throw (presumably, it has been damaged before.)
Interestingly, the problems only occur when I use GCC, with Clang, everything works just fine.
Is it possible to use libunwind inside a shared library? If not, is there another library which allows me to obtained the name plus instruction pointer offset of the functions on the stack? backtrace() is nearly good enough, but backtrace_symbols() is doing too much formatting which I would have to "un-parse" first.

Related

Compile a shared object (.so) with static glibc

I am building some code that needs to be a shared object (.so).
The problem that the libc on my building machine may be newer than the published machines, so I want to link with it statically to avoid compatibilities issues. (My program uses memcpy which is apparently a GLIBC_2.14 thing when it can go as low as 2.5).
Compiling with both -shared and -static doesn't work since crtbeginT.o wasn't compiled with -fPIC.
Edit: Probably not a duplicate of GCC linking libc static and some other library dynamically, revisited? since that question talking about the main elf linking libc statically and this is about a shared object linking libc statically.
You want to statically link glibc in your shared library.
You should not do this.
If you try, you will end up with a C++ One Definition Rule (ODR) violation. This is because some parts of glibc will be from the "old" version of your target machine, and some will be from the "new" version of your library. The result is undefined behavior.
The right solution is simple: build with an older glibc (as old as your oldest target for deployment). Or build multiple times, once for each version of glibc you need (if you truly need new glibc features). Even if you think you need a new glibc feature, consider just copy-pasting that one feature into your library under a different name to avoid collisions.
Regarding memcpy in particular, see: https://stackoverflow.com/a/8823419/4323 - and for a manual fix: https://stackoverflow.com/a/5977518/4323

How to find who is calling the shared library functions?

I have some C++ code in place, which internally uses multiple third party libraries. The code compiles fine but during execution it is failing to load some shared library(libintbasic.so). Given the condition, I can not install any library into the system, the only way out is to find which function is calling that library. How could I find that out who is calling that library (my code does not call that directly).
I can not install any library into the system,
That appears to be a bogus claim: clearly you can copy your binary onto the system. Installing an additional library into the same directory is not much harder.
How could I find that out who is calling that library
There are two cases to consider:
your binary or one of the libraries it is directly linked with links to libintbasic.so. Your binary will not run at all, or
your binary, or one of the libraries it is directly linked with calls dlopen("libintbasic.so",...) and fails when that dlopen fails.
Debugging the first case is often easiest by setting LD_DEBUG=files,libs. The dynamic loader will then tell you which libraries are being loaded, and why they are required.
Debugging the second case is easy with gdb: set a breakpoint on dlopen, and execute where and info shared commands every time the breakpoint is hit.
Remove the linking option -lintbasic, you will see all the functions that needs this library in the error messages. This is not clean but it should work fine.
You may use ldd utility recursively for find all dependencies between shared libraries.
The following link also may be useful: Does ldd also show dependencies of dependencies?

Merge Mach-O executable with a static lib?

Suppose you have
a pre-built iOS executable app (for simulator or device).
a pre-built static archive library static library which among other things contains c++ static initializers.
Now it should be possible to merge the two built products to produce the a new iOS executable which is like the old one, except that it is now also linked with the additional static library, and on execution will run the static library's static initializers.
Which tool (if any) could help solve this merge problem?
Edit: An acceptable solution is also to dynamically load the library using dlopen. The whole purpose of this is for application testing, so the re-linked app will never see app store.
How a compiler work (in a simple explanation)
The most popular C++ compilers (like say, GCC), work by translating all the C++ (and Obj-C, C, etc...) code to ASM.
Then it calls the appropriate assembler for the target processor, and create the object binaries.
Then it calls the linker, that search on those binaries for the symbols that explain what links with what. A common optimisation that linkers can do, is also strip of the final binary anything from the statically linked libraries that was not used, other common optimisation is not attempt to link at all unused libraries.
Also finally, the linker removes the things that only it needed.
What this mean in your case
You have a library, the library has the linking symbols. You also has a executable, that one had its linking symbols stripped, in fact depending on how it was optimised the internal jumps might be only a couple of jmp instructions to arbitrary addresses on the code. No machine, can do what you want in a automatic manner, because you don't have the needed information on the executable.
How to do it anyway
You need to disassemble the executable, figure on your own where are the function calls, and then manually reassemble it with your library, changing those functions call to jump to addresses in your library instead.
This process is sometimes used by game moders to change the video drivers of old games (for example to update their OpenGL version, or to force Glide games to use some newer drivers, and so on).
So if you want to do that anyway (I warn you: it is absurdly crazy to do though...) ask those guys :) I don't remember right now anyone to point to you, but they exist.
Analogy
When you are in normal linking phase, the compiled object files are like a source code that the machine understands, full of function calls as needed.
After it is compiled, all function calls became goto.
So if you are a linker tasked in doing what you want to do, imagine that you would be reading a source code filled with goto to random places in the code (sometimes even to inside loops) and that you have to somehow figure what ones of those you want to change to jump to the new part you are trying to paste there.

How and when is static linking performed (MinGW)?

I had a lot of pain linking a C++ application to another C++ library with Fortran90 dependencies (MinGW, TDM g++ and gfortran). I either have to use gfortran for linking or the application crashes on startup (in global constructors keyed to __cxa_get_globals_fast). However this is not acceptable, I would like to use g++ for linking (Qt GUI).
It seems to me that the dependencies of the libraries cannot be linked statically with gcc, linking is only performed when main() is available. Why?
I guess partly because code for certain initializations have to be inserted before main().
Why is it that the statically linked application needs DLL-s, such as mingwm10.dll or pthreadGCE2.dll at runtime? Why can't these be statically linked?
UPDATE: I just found these websites:
http://www.deer-run.com/~hal/sol-static.txt
http://www.iecc.com/linker/
The main difference between linking with gfortran and using ld/gcc/g++ to link is that gfortran links the standard fortran libraries by default, whereas with another linker you will need to manually specify the libraries to link. I wasn't able to find them with a quick search, but it should be along the lines of -lgfortran.
Also, gfortran has some specific instructions for initialisation routines that need to be called for certain fortran intrinsics to work if your main program is not written in fortran. If you haven't called these routines then this might cause a crash.
Why is it that the statically linked application needs DLL-s, such as mingwm10.dll or pthreadGCE2.dll at runtime? Why can't these be statically linked?
They can, but static library versions are not provided due to the fundamental advantage of dynamic libraries: bugs can be fixed without rebuilding the executables.

GCC / Linux: adding a static library to a .so?

I've a program that implements a plugin system by dynamically loading a function from some plugin_name.so (as usual).
But in turn I've a static "helper" library (lets call it helper.a) whose functions are used both from the main program and the main function in the plugin. They don't have to inter-operate in any way, they are just helper functions for text manipulation and such.
This program, once started, cannot be reloaded or restarted, that's why I'm expecting to have new "helper" functionality from the plugin, not from the main program.
So my questin is.. is it possible to force this "plugin function code" in the .so to use (statically link against?) a different (perhaps newer) version of "helper" than the main program?
How could this be done? perhaps by statically linking or otherwise adding helper.a to plugin_name.so?
Nick Meyer's answer is correct on Windows and AIX, but is unlikely to be correct on every other UNIX platform by default.
On most UNIX platforms, the runtime loader maintains a single name space for all symbols, so if you define foo_helper in a.out, and also in plugin.so, and then call foo_helper from either, the first definition visible to the runtime loader (usually that from a.out) is used by default for both calls.
In addition, the picture is complicated by the fact that foo_helper may not be exported from a.out (and thus may be invisible to runtime loader), unless you use -rdynamic flag, or some other shared library references it. In other words, things may appear to work as Nick described them, then you add a shared library to the a.out link line, and they don't work that way anymore.
On ELF platforms (such as Linux), you have great control over symbol visibility and binding. See description of -fvisibility=hidden and -rdynamic in GCC man page, and also -Bsymbolic in linker man page.
Most other UNIX platforms have some way to control symbol bindings as well, but this is necessarily platform-specific.
If your main program and dynamic library both statically link to helper.a, then you shouldn't need to worry about mixing versions of helper.a (as long as you don't do things like pass pointers allocated in helper.a between the .exe and .so boundaries).
The code required from the helper.a is inserted to the actual binary when you link against it. So when you call into helper.a from the .exe, you will be executing code from the code segment of your executable image, and when you call into helper.a from the .so, you will be executing code from the portion of the address space where the .so was loaded. Even if you're calling the same function inside helper.a, you're calling two different 'instances' of that function depending on whether the call was made from the .exe or the .so.
i think this question is the same as yours. How to force symbols from a static library to be included in a shared library build?
The --whole-archive linker option should do this. You'd use it as e.g.
gcc -o libmyshared.so foo.o -lanothersharedlib -Wl,--whole-archive -lmystaticlib
and it works for me.