I have a custom shared object file as an OpenSSL engine and it is working fine with pthread. I was trying to use a third-party thread library instead of pthread. However, upon linking and running the engine, I'm getting a Segmentation fault. I just could not figure out why. I have a hunch that my linking with the newly built dynamic library is not correct,
Following is what I did
Makefile to create a dynamic library
CC = GCC
CFLAGS = -Wall -fPIC -g -O3 -MD
LDFLAGS = -shared
OBJ = uthread.o
all: libuthread.so
libuthread.so: $(OBJ)
$(LD) -shared -o $(#) $(OBJ)
clean:
rm -f *.o *.d libuthread.so
-include *.d
%.o: %.c
$(CC) $(CFLAGS) -o $# -c $<
Copy libuthread.so library to /lib/x86_64-linux-gnu/
My Makefile to compile my OpenSSL engine
gcc -g -fPIC -c -fomit-frame-pointer testengine.c
gcc -g -shared -o libtestengine.so rsa-engine.o rsa/rsa.o rsa/bignum.o
rsa/aes.o -Wl,-Bstatic -Wl,-Bdynamic -lcrypto -luthread
mv libtestengine.so rsaEngine.so
After compilation, $ldd rsaEngine.so shows the following,
linux-vdso.so.1 => (0x00007ffded367000)
libcrypto.so.1.1 => /opt/openssl/lib/libcrypto.so.1.1 (0x00007f895c5fa000)
libuthread.so => /lib/x86_64-linux-gnu/libuthread.so (0x00007f895c3f4000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f895c02a000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f895be26000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f895bc09000)
/lib64/ld-linux-x86-64.so.2 (0x00007f895cd56000)
I use gdb to find out what causes the segmentation fault, and I find out that uthread_join(), is failing at some point. Can someone please tell me what I'm, doing wrong?
N.B: I checked the library with a simple program and the library works fine.
I just could not figure out why.
There could be a number of reasons:
A threading bug in your code (which happens not to cause a crash with system libpthread library, but causes a crash with uthread.o, whatever it is),
A bug in uthread.o which is exposed by your test, but not by the simple program you tried,
A bug somewhere else.
There is no way for us to tell with the info provided.
Your first step should be to run the program under debugger and figure out where it crashes, and then why.
I have a hunch that my linking with the newly built dynamic library is not correct
I have a hunch that your hunch is wrong. There doesn't seem to be anything wrong with your linking.
Related
I am attempting to create a shared library that provides an easier interface for calling FFT and IFFT functions from GSL in C.
My C file.
fft.c
Building the object file.
gcc -c -Wall -Wextra -O2 -fPIC fft.c -o fft.o
Object file builds perfectly.
Then the link command.
gcc -L/usr/local/lib -Wl,-rpath=/usr/local/lib -shared -o libfft.so fft.o -lgsl -lgslcblas
No errors...
However, running the following command
ldd libfft.so
prints the following output.
linux-vdso.so.1 found
libgsl.so => /usr/local/lib/libgsl.so <--- CORRECT
libc.so.6 => found
libm.so.6 => found
/lib64/ld-linux-x86-64.so.2
libgslcblas.so => not found <--- This is confusing me...
For some reason the libgsl.so is found in the correct location on my computer, but the libgslcblas.so is saying not found.
Both libraries are in that directory.
Thank you so much for any answers.
EDIT (09/07/2022)
After looking into the recommendation by
https://stackoverflow.com/users/2581418/vitsoft
the Dynamic section of the shared library was only showing libgsl.so as being (NEEDED). Then I thought maybe the actual libgsl.so I have is dependent upon libgslcblas.so.
Running the ldd command on libgsl.so, shows that it relies on libgslcblas.so, and it is not found. So, I may have built GSL incorrectly from source?..
This was exactly the problem, make sure to follow the directions of GSL when they tell you how to build their source code!
I am trying to cross compile my application for a arm based system.
I have 2 libraries compiled in the following way:
$ gcc -shared --sysroot=$DIR_PATH -o $LIBPATH/libfoo.so foo.o
$ gcc -shared --sysroot=$DIR_PATH -o $LIBPATH/libbar.so bar.o
A third library is compiled:
gcc -shared -o $LIBPATH/libfoobar.so --sysroot=$DIR_PATH -L$LIBPATH -Wl,rpath=$RUN_TIME_PATH foobar.o -lfoo -lbar
Then finally I compile a binary:
gcc -o app --sysroot=$DIR_PATH -L$LIBPATH -Wl,rpath=$RUN_TIME_PATH app.o -lfoobar
However when compiling app I get
warning: libfoo.so, needed by libfoobar.so, not found (try using -rpath or -rpath-link)
I believe you need to use -Wl,-rpath-link=$LIBPATH to tell the linker where to look to resolve runtime library references during the link operation.
More info can be found in the ld documentation: https://sourceware.org/binutils/docs-2.37/ld/Options.html
I need to build this Lua module and to be able to use it in another application that already has Lua core included. Module will be loaded via 'require'.
I'm using MinGW x64 on Windows 10. I successfully built Lua 5.2 with it, extracted lua.dll file and renamed it into liblua.dll.a.
Then I built the module using following Makefile:
CC = x86_64-w64-mingw32-gcc
LUA_INCDIR=$(STAGING_DIR)/usr/include
utf8.dll: lutf8lib.o
$(CC) -m64 -O -shared -fpic lutf8lib.c -o utf8.dll -llua
lutf8lib.o: lutf8lib.c
$(CC) -O2 -fpic -c -DLUA_BUILD_AS_DLL lutf8lib.c -I$(LUA_INCDIR)
The problem is file size, it's 420kb and it definetely includes Lua core (I got 'multiple VMs' error). I need to build the module without including the core.
Previously I installed usual MinGW (x86) and used following Makefile:
CC = gcc
LUA_INCDIR=$(STAGING_DIR)/usr/include
utf8.dll: lutf8lib.o
$(CC) -m32 -shared lutf8lib.c -o utf8.dll -llua
lutf8lib.o: lutf8lib.c
$(CC) -fPIC -c lutf8lib.c -I$(LUA_INCDIR)
And got 97kb file without Lua core. Unfortunately I specifically need x64 file.
UPD: I tried to build the same module using MSVC, but it seems that IDE changes luaopen_utf8 function name. If I'll add this to fix it:
int __declspec(dllexport)
IDE will include Lua core VM into DLL file. Again.
Im developing an android app thats loading two shared libraries. One is external, its called libpcan.so . Usually its build to libpcan.so.0.6, this somehow cant be used by my android, i so changed the gcc flags compiling it from:
arm-linux-androideabi-gcc src/libpcan.c -fPIC -shared -O2 -Wall -Wl,-soname,-libpcan.so.0 -lc -I. -I../driver -DNO_RT -o -libpcan.so.0.6
ln -sf libpcan.so.0.6 libpcan.so
to
arm-linux-androideabi-gcc src/libpcan.c -fPIC -shared -O2 -Wall -lc -I. -I../driver -DNO_RT -o -libpcan.so
This .so has the same size as the so.0.6 so i assume it worked fine.
My own c-code is getting compiled with
arm-linux-androideabi -shared src/receivetest.c src/common.c -I. -I../lib -I../driver -L../lib -L/lib -L/usr/lib -L/usr/local/lib -o libreceivetest.so
I load both of these files, so the libpcan.so and the libreceivetest.so to my app
static {
System.loadLibrary("pcan");
System.loadLibrary("receivetest");
}
When I'm trying to launch that app i get the error message:
07-14 11:12:43.812: E/AndroidRuntime(753): java.lang.ExceptionInInitializerError
07-14 11:12:43.812: E/AndroidRuntime(753): Caused by: java.lang.UnsatisfiedLinkError: Cannot load library: reloc_library[1306]: 36 cannot locate 'CAN_Open'...
My receivetest is using that function, but since it declared in the libpcan.so and im also loading that library, i don't know where that error could come from.
I'd just guess its an error in my clags, since I'm new to building .so files via using gcc in the shell i don't really understand all the flags im using.
It's quite long since i solved this. But I haven't ever marked this question as solved.
Thanks to jww for reminding me.
As I've said in the comment to my question, the link to the function CAN_Open was missing due to a missing parameter at compiling the .so-file. The function CAN_Open is a part of the libpcan.so and by skipping the link to that file the CAN_Open function just never made it into the receivetest.so .
Under gcc (g++), I have compiled a static .a (call it some_static_lib.a) library. I want to link (is that the right phrase?) this .a file into another dynamic library (call it libsomeDyn.so) that I'm building. Though the .so compiles, I don't see content of .a under .so using nm command:
/usr/bin/g++ -fPIC -g -O2 -Wall -Werror -pipe -march=pentium3
-mtune=prescott -MD -D_FILE_OFFSET_BITS=64 -DLINUX -D_GNU_SOURCE -D_THREAD_SAFE -I../../../../../../../../ -I../../../../../../../..//libraries -Wl,-rpath,/usr/lib -o libsomeDyn.so some.o another.o some_static_lib.a -shared -Wl -x
-Wl,-soname,libsomeDyn.so
I do not see functions under some_static_lib.a under libsomeDyn.so. What am I doing wrong?
Static libraries have special rules when it comes to linking. An object from the static library will only be added to the binary if the object provides an unresolved symbol.
On Linux, you can change that behavior with the --whole-archive linker option:
g++ -Wl,--whole-archive some_static_lib.a -Wl,--no-whole-archive
For every one that comes across that problem like me (and has not understand the answer properly): here is a short howto generate a dynamic library (libmylib.so) from a static one (mylib.a):
1.) create a mylib.c file that only imports the mylib.h file
2.) compile this mylib.c to mylib.o with
gcc -c -fPIC mylib.c -o mylib.o
3.) generate a dynamic library with the following command:
gcc --whole-archive -shared -Wl,-soname,libmylib.so -o libmylib.so mylib.o mylib.a
That worked at least for me, turning a static library (compiled with -fPIC) to
a dynamic library. I'm not sure wether this will work for other libraries too.