How to trace or debug GMP? - c

I have downloaded the source of GMP library 5.02, and - as suggested here for maximum debuggability - I ran :
./configure --disable-shared --enable-assert --enable-alloca=debug --host=none CFLAGS=-g
and compiled it with make, then installed the library with make install. I then compiled my program like this: gcc -lgmp -std=c99 -g -c program.c and then I ran : ltrace ./a.out
However I realized that ltrace is not at all invoking the TRACE() functions I can find in the source code. I would like to trace the content that's in TRACE().
How should I go for that? Or is there any other straightforward way of debugging inside the GMP library? (I couldn't figure it out how to do it with gdb, it never wanted to step into gmp_printf)
Thanks.
EDIT:
I tried to investigate further, and realized that I couldn't modify the GMP library although I had the sources. I inserted a printf("hello\n"); at the very beginning of the mpz_init2 function which I do call at the beginning of my program, I recompiled all GMP (even after a make clean) re-installed the library with make install, then I compiled and launched my program, but it never printed "hello". I also made sure, I wasn't using another installed GMP library (when I do make uninstall my program cannot compile as it does not find the library). Still, I insisted that gcc looks for the library in the GMP source folder with the -L option.
I don't know what I'm doing wrong :(

Your final compile of a.out is not producing a statically linked a.out executable. So, even though as you state, during compilation of program.c the compiler is using your GMP library, at runtime it is picking up a shared library somewhere. You need to do one of two things:
Compile with -Bstatic (or something similar; check man page for your compiler)
Set the LD_LIBRARY_PATH (or something similar; check 'ld' or 'dyld' man pages)
I think #1 is actually your only choice given that you built only the static version of GMP. For #1 make sure you explicitly provide -L/path/to/gmplib in the compilation of program.c

Related

GCC 7.2 compiles shared library instead of executable

I have a virtual machine with ArchLinux installed. Here when I compile with GCC by running gcc file.c it gives me a shared library instead of an executable.
Later I find out that the problem is related only to GCC 7.2, in fact, when I compile with GCC 6.4, the output file is an executable.
How do I fix this?
The file utility is just incorrect in calling your program a shared library. It is a position-independent executable (PIE). If you really don't want this, you can specify -no-pie at link time, or build a gcc toolchain with --disable-default-pie, but in general you shouldn't need to change this.
To complement the answer that mentioned file as you pointed out in the comments, the default a.out generated by GCC is not a shared library but instead interpreted as a shared object by file maybe because of the content of your source code. Check this for more information.

Makefile for C code

I inherited a code which has a makefile, but so far I was unable to run it on a linux server. The main complain of the compiler is that it is unable to load libgmp.so.3 : error while loading shared libraries: libgmp.so.3. I know that libgmp.so.10 exists on this server, but I was wondering which part of the makefile needs to be changed so the compiler looks for libgmp.so.10 rather than libgmp.so.3.
OPTFLAG = -O2 -Wall -fPIC -fexceptions -DNDEBUG
LDFLAGS = -O2 -Wl,-no_compact_unwind -DNDEBUG -lm -pthread
COMPILER = gcc ${OPTFLAG}
LINKER = gcc ${LDFLAGS}
# CPLEX directory
CPLEX_HOME = /opt/ibm/ILOG/CPLEX_Studio1263/cplex
CPLEX_INC = ${CPLEX_HOME}/include/
CPLEX_LIB = ${CPLEX_HOME}/lib/x86-64_linux/static_pic/ -lcplex
# Compile the main file
code: code.c
${COMPILER} -c code.c -o code.o -I${CPLEX_INC}
${LINKER} -o code code.o -L${CPLEX_LIB}
clean::
rm -f *.o
rm -f ${LIB}/*.o
rm -f *~
rm -f ${SRC}/*~ ${INCLUDE}/*~
You need to rebuild whatever program or library uses libgmp.so.3 from source code. Could you provide the exact command run by make and the error message it produces?
EDIT The problem here is that the system has installed a version of the IBM CPLEX software which comes with its own GCC binary, and that GCC binary uses libgmp.so.3. The easiest way to fix this would be to upgrade the CPLEX software to a version which supports the operating system being used, or use the software on the operating system for which it was written (i.e., something really old that actually ships libgmp.so.3).
The most easy way it to install libgmp-dev package, from your linux distribution. GMP is a package library to do multiple precision calculations on large integers, which is probably needed by your program. As you put in some comments, adding -L/usr/lib64/libgmp.so.10 is an error, as -L option allows to add a directory to search for libraries, and not a specific library.
If only the library is needed and no header file is missing in your compilation (this is something strange, but sometimes happen) then you can still link with only the libgmp.so.10 object, but you have to do in a something nasty way. Just add /usr/lib64/libgmp.so.10 as an object file (not a library, with -l option) to your link command.
EDIT
From looking more closely your Makefile I see no reference to the libgmp.so.3 library, so I only can assume this is a indirect reference from some other already compiled library that comes from outside with your package. Just use
ldd lib<nameOfLibrary>.so.x.x
with all the libraries needed by your final executable, so see which shared objetc is the one that requests libgmp.so.3 soname, and then recompile it, reinstall it, or use your system's libraries ONLY, and not mesh anymore with libraries coming from another system. For example you can try (this is an expensive command, but it will get the answer)
find / -name "lib*.so.*" -print | xargs ldd > all_libs.lddout
and then find all_libs.lddout to see which library uses libgmp.so.3 (this will be the outdated library) You'll need to deinstall it or upgrade it, to be able to continue.
Linux systems have a library version system that allows an executable to be able to load different versions of the same library and allow them to live together in the same system. One of two: or you are able to locate the sources of version 3 of the shared libgmp.so.3 library and install it on your system, or you'll need to update the libraries your program uses to be able to link with the libgmp.so.10 already installed on your system.
2ND EDIT
As I see in the comments, you have changed the default compiler on your system by another coming possibly from other linux distribution (as your installed library is libgmp.so.10 while the one cc1 requests is libgmp.so.3, which is not installed on your system.
Installing a different compiler from the one you have installed, and doing that without previously deinstalling the other compiler, can lead you to this kind of problems.
The most reliable thing you can do is to reinstall the compiler from your distribution, or better, reinstall the whole linux system, as you have probably broken many things that will be emerging as you use your system. There's very poor info on what you have done to go further in your problem. Anyway, my recommendation is to not use the comment parts to add new information about your problem, just edit your question and add all those new information to it.

Compiling openmp on mac using gcc and Matlab

I am trying to compile a Matlab mex program that uses openmp on a mac. I would like to distribute this to other Matlab users so that they can use it, without them needing to install other software.
From what I can tell, xcode doesn't allow this, so I've installed gcc. I am able to compile the program fine, and run it locally, but it links to dependencies that are not available by default on a mac (I think). In particular, otool points to libgomp.1.dylib and libgcc_s.1.dylib, which from what I can tell, are not a part of the standard os installation.
I am able to link against libgomp.a statically, which from some testing (renaming the .dylib file) seems to have properly removed that dependency (i.e. the code still works when I rename the dylib file, and otool does not list it as well). However, I am unsure how to remove the libgcc_s.1.dylib dependency. In windows, copying the dll locally would fix the issue, but this doesn't work on a mac. I could not find a static library for that dependency. Instead, I am trying to get some version of rpath working (with a locally copied file), but otool consistently points to /usr/local/opt/gcc/lib/gcc/6/libgcc_s.1.dylib
The relevant parts of the Matlab command were:
'LDFLAGS="$LDFLAGS -fopenmp -Wl,-rpath,$ORIGIN/"' and
'-lgcc_s.1'
I found one solution here: Openmp with mex in Matlab on mac
However, for another project, I am using gcc specific commands so I'd really like to get this working with gcc.
So, I had some luck bypassing the mex compiling infrastructure and just passing the commands directly to gcc. To start, I ran what I currently had using the '-v' option to see the commands that Matlab was sending to the compiler. The 4 edits I then made were, 1) removed the crazy object output paths that Matlab creates (uses some temporary folder) 2) removed the reference to xcode 3) added a -L directive to the mex folder (although I will probably change this to the proper gcc directory - I'm just used to copying files locally to compile due to Matlab problems) and 4) added '-static-libgcc' (which I swear I had tried before ...) oh, and 5) I also updated the min osx version
This is the final line, the first two just had the -o options removed
/usr/local/Cellar/gcc/6.3.0_1/bin/gcc-6 -Wl,-twolevel_namespace -static-libgcc -L"/Users/jim/Documents/repos/matlab_git/matlab_sl_modules/plotBig_Matlab/+big_plot/private" -undefined error -arch x86_64 -mmacosx-version-min=10.12 -bundle -Wl,-exported_symbols_list,"/Applications/MATLAB_R2017a.app/extern/lib/maci64/mexFunction.map" -fopenmp reduce_to_width_mex.o c_mexapi_version.o -O -Wl,-exported_symbols_list,"/Applications/MATLAB_R2017a.app/extern/lib/maci64/c_exportsmexfileversion.map" libgomp.a -L"/Applications/MATLAB_R2017a.app/bin/maci64" -lmx -lmex -lmat -lc++ -o reduce_to_width_mex.mexmaci64
Oh and finally I should mention I just ran these commands in the terminal, rather than in the Matlab command window ...

Can't Link Psapi.h in Open Source Project Using MinGW

I am trying to modify the source code to an open source application on windows that uses mingw.
I am having a problem linking the psapi library.
psapi.h and libpsapi.a are in the mingw directory and I have tested it using the standard
gcc -o program program.c -lpsapi
method, and it works.
However, when I try to compile the program using the
./configure
make
method, it doesn't work I have tried,
./configure LDFLAGS=-lpsapi
make
and that doesn't work
and I tried going into the makefile.am and putting -lpsapi in AM_LDFLAGS but that doesn't work
The error it gives is just a standard "undefined reference to [function]", implying that the library with the functions is not linked
I have even tried putting psapi.h in the source directory and including it as #include "psapi.h" and that STILL didn't work.
LDFLAGS is the wrong one.
LIBS=-lpsapi should do the trick.
The order is important for the linker. The libraries (LIBS) have to come after the objects, LDFLAGS can be before.

How to created a shared library (dylib) using automake that JNI/JNA can use?

How do I convince LibTools to generate a library identical to what gcc does automatically?
This works if I do things explicitly:
gcc -o libclique.dylib -shared disc.c phylip.c Slist.c clique.c
cp libclique.dylib [JavaTestDir]/libclique.dylib
But if I do:
Makefile libclique.la (which is what automake generates)
cp .libs/libclique.1.dylib [JavaTestDir]/libclique.dylib
Java finds the library but can't find the entry point.
I read the "How to create a shared library (.so) in an automake script?" thread and it helped a lot. I got the dylib created with a -shared flag (according to the generated Makefile). But when I try to use it from Java Native Access I get a "symbol not found" error.
Looking at the libclique.la that is generated by Makefile it doesn't seem to have any critical information in it, just looks to be link overloads and moving things around for the convenience of subsequent C/C++ compiler steps (which I don't have), so I would expect libclique.1.dylib to be a functioning dynamic library.
I'm guessing that is where I'm going wrong, but, given that JNA links directly to a dylib and is not compiled with it (per the example in the discussion cited above), it seems all the subsequent compilation steps described in the LibTools manual are moot.
Note: I'm testing on a Mac, but I'm going to have to do this on Windows and Linux machines also, which is why I'm trying to put this into Automake.
Note2: I'm using Eclipse for my Java development and, yes, I did import the dylib.
Thanks
You should be building a plugin and in particular pass
libclique_la_LDFLAGS = -avoid-version -module -shared -export-dynamic
This way you tell libtool you want a dynamically loadable module rather than a shared library (which for ELF are the same thing, but for Mach-O are not.)

Resources