Preloading dynamically loaded libraries in linux - linux

I have a 7 year old game that a friend built & I have very little of the source code left.
It works perfect on CentOS 4.8 and below, so I'm thinkin' it's a TLS error. I transfered a new folder with all the CentOS 4.8 libraries the program called to the new one... I'm trying to load the old libraries it called for in ldd specifically to that program,. This is what I'm trying:
LD_PRELOAD="/glibs/ld-linux.so.2 /glibs/libc.so.6 /glibs/libgcc_s.so.1 /glibs/libm.so.6 /glibs/libpthread.so.0 /glibs/libstdc++.so.5 /glibs/libz.so.1 /glibs/libxml2.so.2" /home/g/gameserver
I keep getting a Segmentation Fault error, does anyone know why? Maybe I don't fully understand what LD_PRELOAD does or something. How would I be able to load old libraries without messing up the originals? Thanks in advance!

LD_PRELOAD is more used to override a functionality in a library before the normal ones get used (e.g. custom malloc, socksify all sockets etc). What you probably need is to put all your old libraries into their own directory and then set LD_LIBRARY_PATH so that it attempts to find the library first in this directory.

Related

Linking problem with R package AsioHeaders

I am using Asio in a Rcpp package, and am therefore using the package AsioHeaders.
I have added BH and AsioHeaders in the "LinkingTo" part of the DESCRIPTION file of my package. I have also added comments
// [[Rcpp::depends(BH)]]
// [[Rcpp::depends(AsioHeaders)]]
in my code. So normally, the linking should be fine when compiling the package.
And it is when I compile it on Linux. But when trying to compile it on Windows, I get linking errors that are solved by linking -lws2_32 and -lwsock32.
I am thus wondering, whether I should edit the Makevars file so that these are linked on Windows but ignored on Linux, or if I have done something wrong using AsioHeaders?
AsioHeaders maintainer here. Quick questions:
Which version of AsioHeaders? It just updated at CRAN. Is this a change from the new version (which would suprise me ...)?
Make sure you are not accidentally using Asio functionality from Boost which will require linking. See the three packages using AsioHeaders.
If your package is truly header-only then LinkingTo: is all you need. R will find the header directories for you. In particular, you do not need link instructions in src/Makevars* because, well, header-only.
Also, you probably meant // forward slashes for your C++ comments above...

Modifying gethostbyname (res_search) source code - Linux Ubuntu 14.04 LTS

I am trying to modify the behaviour of the DNS lookup functions in Linux for my project by setting it to write a random string in a file as a test.
Linux use some DNS resolver functions, mainly gethostbyname. Looking forward, I found out that the resolver functions are within the glibc6 library. So, I downloaded it, compiled, generating the libresolv.so, libnss_dns.so dynamic libraries. Then, I replaced the existing ones on my system, at /usr/lib/x86_64-linux-gnu/.
Note: I found out these libraries are the ones that resolves queries by modifying gethostbyname code and compiling again. Then, I saw which dynamic libraries changed.
By creating a program that uses res_query directly (a resolver function) and compiling with -lresolv, it works (I used ldd command and it uses the resolver library I created). But, using gethostbyname directly from the code, using wget or browsing the web I can't get it right.
What am I doing wrong?
I discovered what should I do:
Firstly, the function called isn't gethostbyname. It is _nss_dns_gethostbyname3_r, defined in resolv/nss_dns/dns-host.c. Looking at the source I realized that this function called another one to resolve DNS names, __libc_res_nsearch, defined in resolv/res-query.c. So this is the function! I added some file writting commands there and it worked like a charm. I called it from C code using gethostbyname, used wget and Firefox, all worked. When you compile the code you should replace the libresolv.so of your system by the new one.
Note: my glibc version is 2.19.
I hope this helps someone.

Is it feasible to bundle dynamic libraries with dependencies in a Tcl Starkit/Starpack?

I've written a Tcl script that uses the TclMagick extension together with GraphicsMagick.
For GraphicsMagick, I've both the Windows DLLs and the Linux SO files. I want to be able to make two Starkit/Starpack applications bundled with those libraries: one for Windows (with the DLLs) and one for Linux (with the SO files).
Is this reasonable? Can it be done?
EDIT
I cannot seem to use DLLs with dependencies under Windows. In my case, I want to use the TclMagick extension, but it needs the GraphicsMagick's DLLs and the starkit cannot find those. What should I do in this situation?
Yes. In the lib/tclmagick subdirectory of $starkit::topdir, you'll place the dynamic library and an appropriate pkgIndex.tcl file that loads the library. Use a Makefile or some other build script to use the correct dynamic library file, and generate the pkgIndex, depending the target platform.
The directory hierarchy:
appname.vfs/
main.tcl
lib/
app-appname/
appname.tcl
pkgIndex.tcl
tclmagick/
pkgIndex.tcl
tclMagick.so
package require tclmagick will work as you expect, for some capitalization of "tclmagick"
You can do it, but you might need some extra windows trickery to get things to work properly.
Windows has quite a few options to load dependent libraries, this page explains the basics:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms682586%28v=vs.85%29.aspx
There are is one part that can help you:
If a DLL with the same module name is already loaded in memory, the system checks only for redirection and a manifest before resolving to the loaded DLL, no matter which directory it is in. The system does not search for the DLL.
So, to get the dependencies right, you could get the dependent libraries loaded into memory first (sadly you cannot use load for this, but could use something from twapi, e.g. twapi::load_libary (see http://wiki.tcl.tk/9886) to get the library loaded from some temporary location).
Sadly most OS's do not provide an easy or portable way to load a dynamic library directly from memory, so you need to copy the dependent libs to a temporary location first (you can do it with appropriate hacks or by using something like an installable filesystem on windows/FUSE on Linux).
In most cases the easiest route is to just link all dependencies statically into the extension instead.

How to link with specific name (version) of a shared library

I searched this problem here and find some similar question but there solutions not work for me. Here is my problem:
My application is compiling with shared library of openldap-2.3. Openldap has /usr/lib/libldap-2.3.so.0 which is linked to /usr/lib/libldap-2.3.so.0.2.31. I passed -lldap option to gcc, which linked the libldap-2.3.so.0 file to my application.
But i want to link with specific name like libldap.so. Please correct me, in future if i change the openldap version to 2.4 in development system, it will then link to the libldap-2.4.so.XXX version.
So How can I link my application to specific name, so that it will always look for same name like libldap.so.
NOTE: I created a softlink of /usr/lib/libldap-2.3.so.0 as /usr/lib/libldap.so and then pass the library name /usr/lib/libldap.so to compiler without -l then application compiled successfully without any linking error but still showing same libldap-2.3.so.0 in dependency.
The shared library mechanism (the link is oldish, but still relevant) in Unix works by linking the executable at build time against e.g. liba.so, which is a symbolic link to liba.so.1, which in turn is a link to liba.so.1.2. The executable then records liba.so.1 to load when starting up. If you update liba.so, it could be to liba.so.1.5 (no ABI change, first digit doesn't change), the links look like liba.so --> liba.so.1 --> liba.so.1.5, and your executable now uses 1.5 transparently. If the version goes to liba.so.2.0 (API change!), the system makes liba.so --> liba.so.2 --> liba.so.2.0. Your old executable still uses 1.5, any newly built program will now reference 2. All this works as long as 1.x stays around, obviously. Presumably your distribution offers library packages that can be installed in paralell, or some compat-liba-1 package for the benefit of old executables.

Differences between compiled dalvik binaries

I'm compiling dalvik on Android 4.1 with both host and target set to x86. The make command is:
make dalvikvm core ext framework android.policy services
However, there are multiple compiled binaries:
out/host/linux-x86/bin/dalvikvm
out/host/linux-x86/bin/dalvik
out/target/product/generic_x86/system/bin/dalvikvm
out/target/product/generic_x86/symbols/system/bin/dalvikvm
But the target versions don't work. When run, they show:
bash: ./dalvikvm: No such file or directory
This error is so strange that, I mean, the file is just there.
Could anyone please tell me which one is the compiled result? I mean, if I make some modification to dalvik source, which one will contain the modified result? Thank you.
This is almost certainly a linkage issue. The host version is linked against the normal host libc, but the target versions are linked against the android libc that lives in /system/lib on the device, which your host ld knows nothing about.
You might try something like:
LD_LIBRARY_PATH=<android_root>/out/target/product/generic_x86/system/lib out/target/product/generic_x86/symbols/system/bin/dalvikvm
Although I'm not entirely sure if that would work

Resources