How to find what library was used during a program execution? - c

I want to know what libraries, external code were actually used during a program's execution. I am working with Inkscape's source code and interested in its command line function that converts svg to png. I want to strip out all its dependencies that's not needed in this execution path.
I am currently using gcov, but so far that only tells me about the Inkscape's code.
My development environment is Windows 2008, mingw gcc package.
Thanks.

Process Explorer will show you all the libraries loaded at runtime, both static and dynamic. It will also show you any handles actively touched during runtime.
You can also spawn and monitor processes from the UI, provided you have your path setup correctly.
Granted, if you have the source code, you can just search for link options during compile time, check the makefiles. For runtime, break point the LoadLibrary method in gdb. In addition, gdb also has an 'info sharedlibrary' command you can use.

If you have ldd under MinGW just use it:
ldd executable or you may use
objdump -p | grep DLL or even
gprof

Related

How can I make a binary that uses openmp and compiled with intel's C compiler portable?

Normally I compile code (all in a single file main.c) with the intel oneapi command prompt like so
icl.exe main.c -o binary_name
I can then run binary_name.exe without issue from a regular command prompt. However, when I recently exploited openmp multithreading and compiled like so.
icl.exe main.c -o binary_name /Qopenmp /MD /link libiomp5md.lib
Then, when I try to run it through an ordinary command prompt, I get this message:
I'd ultimately like to move this simple code around (say, to another computer with the same OS). Is there some procedure through a command prompt or batch file for packaging and linking a dynamic library? It is also looking like statically linking for openmp is not supported on windows
Either make a statically linked version, or distribute the dependency DLL file(s) along with the EXE file.
You can check the dependencies of your EXE with Dependency Walker.
As you correctly statedk statically linking for OpenMP is not supported on Windows. Depending on your use case you have a couple of options. The simplest one for simple testing is to just ship the Dynamic-Link Library with you executable and place it in the same directory in the target system. Having built a lot of systems using DLLs, this is typically what most developers do to ensure capability with their code in a production environment even.
If you are looking to do something more complex on the target system you can place the Dynamic-Link library in a shared location and follow the search order suggestions from the Microsoft Build site:
https://learn.microsoft.com/en-us/windows/win32/dlls/dynamic-link-library-search-order

C Codelite compile error

I just installed CodeLite onto a brand new PC and I am not able to compile anything. I want to write a console application in C
Simple Executable (gcc)
Compiler: gnu gcc
Debugger: GNU gdb debugger
However, I can't even build a default "hello world" application. All I get is this error:
C:\Windows\system32\cmd.exe /C mingw32-make.exe -j 4 -e -f Makefile
'mingw32-make.exe' is not recognized as an internal or external command,
operable program or batch file.
Now I "googled" this and found out, I have to set up mingw32-make, (which I didn't have to do on 3 other computers) but I can't find a tutorial on how to do that.
Any advice will be highly appreciated!
Thanks in advance.
CodeLite does not install MinGW for you. You need to do it for yourself.
Obviously, CodeLite does not know where to find mingw32-make.exe otherwise, it wouldn't use just mingw32-make.exe instead it uses the full path to mingw32-make, something like C:\TDM-GCC-64\bin\mingw32-make.exe
What you need to do is:
Run CodeLite setup wizard again from Help->Run the Setup Wizard
Follow the steps (5 in total), pay close attention to the Setup Compilers step
If you have installed MinGW before, just click on the Scan button
If you don't have, click the Install button
Open your project settings->General page and select the compiler you just installed in the Compiler field
Make enables the end user to build and install your package without knowing the details of how that is done -- because these details are recorded in the makefile that you supply.
Make figures out automatically which files it needs to update, based on which source files have changed. It also automatically determines the proper order for updating files, in case one non-source file depends on another non-source http://file.As a result, if you change a few source files and then run Make, it does not need to recompile all of your program. It updates only those non-source files that depend directly or indirectly on the source files that you changed.
Make is not limited to any particular language. For each non-source file in the program, the makefile specifies the shell commands to compute it. These shell commands can run a compiler to produce an object file, the linker to produce an executable, ar to update a library, or TeX or Makeinfo to format documentation.

Overcome DLL Hell with Code::Blocks

I'm using Code::Blocks for a project. I have not used an IDE on Linux in years, so I'm a bit out of touch with Linux IDEs.
I'm working with an OpenSSL project that uses FIPS validated library. I duplicated the GCC compiler toolchain and modified it to use OpenSSL's fipsld (and set it as default).
When the project's code executes under Code::Blocks via F8, FIPS_mode_set fails with error 252104805 (0xF06D065). 0xF06D065 is:
$ openssl errstr 0xF06D065
error:0F06D065:common libcrypto routines:FIPS_mode_set:fips mode not supported
which tells me Code::Blocks is not using the OpenSSL I specified in /usr/local/ssl/lib. Rather, the program is using the non-FIPS library provided by Debian in /usr/lib/x86_64-linux-gnu/.
An image of the link library settings is below. Note that the libraries are fully specified, and nothing is left to chance.
CodeBlocks is clearly doing things with LD_LIBRARY_PATH (shown below).
I've also verified the project is using the correct search directories - /usr/local/ssl/include for headers and /usr/local/ssl/lib for the linker.
With compiler logging set to "Full Command Line" set, here's what I get from the build log:
-------------- Build: Debug in ac ---------------
Compiling: main.cpp
/home/jwalton/Desktop/ac/main.cpp:8:5: warning: unused parameter ‘argc’ [-Wunused-parameter]
/home/jwalton/Desktop/ac/main.cpp:8:5: warning: unused parameter ‘argv’ [-Wunused-parameter]
Linking console executable: bin/Debug/ac
Output size is 569.67 KB
Process terminated with status 0 (0 minutes, 0 seconds)
0 errors, 2 warnings
I'm aware of Basile Starynkevitch's suggestions on rpath's and LD_PRELOAD tricks, but this seems like one of those things the IDE should be handling for me (Visual Studio will handle it properly, and even gives us an input box to set Working Directories to find additional libraries).
Any ideas how to make Code::Blocks use the shared objects in /usr/local/ssl/lib when executing the program under the debugger?
Your IDE instructs the compiler to link against the specified libraries, but not to load them at run time. For this latter thing to happen, you need to pass another option to the linker, namely
-rpath=/path/to/directory/with/your/libraries
or, if the linker is invoked by the compiler,
-Wl,-rpath=/same/thing
Code::Blocks don't use shared objects (DLL are a Windows thing). Because Code::Blocks is simply an IDE. IDEs are glorified source code editors with the ability to run external software development tools. You could (and sometimes you should, at least to learn how things happen) edit your code with a plain good editor like emacs, and build it with commands. Your IDE is just running commands, notably a compiler and a linker, probably using gcc
So what is using shared objects in /usr/local/ssl/lib/ is the compiler and linker (and the runtime dynamic linker). BTW, /usr/local/ssl/lib/ is a very strange name for a directory containing shared objects; you should have configured OpenSSL to be installed in /usr/local/lib/ !
First, I really believe you should reconfigure and recompile and rebuild and reinstall your SSL to get it installed under /usr/local/ (or perhaps /opt/) prefix (i.e. shared libraries in /usr/local/lib).
Then you could add appropriate options for the ld linker (from binutils). You probably want -L/usr/local/ssl/lib (to the gcc command which is running ld), and you may want to pass -Wl,-rpath (see this).
I would suggest to reinstall your SSL in /usr/local/, add /usr/local/lib/ into /etc/ld.so.conf (or at least into your LD_LIBRARY_PATH...) and run ldconfig
Otherwise, add at least /usr/local/ssl/lib/ in front of your LD_LIBRARY_PATH (and also -L/usr/local/ssl/lib/ to your linking command).
Read Program Library HowTo, the answers to this, and Drepper's How To Write Shared libraries paper.
Just open the terminal and type
export LD_LIBRARY_PATH=/path/to/your/libraries
sudo ldconfig

Linking a library built from source code to a program managed by autotools

I have a c program which needs a library named libnuma to be installed. But I dont have root access in the parallel machine in which I need to run this program. So I downloaded the source code of libnuma and compiled it. I have a libnuma.a file which i assume is the library. I need to link this library with the c program that I have. This program uses autotools for generating the configuration files and the makefile. I am new to autotools. Please tell me what I have to do to link this library without being root.
Ajay.
It should be sufficient to set CPPFLAGS and LDFLAGS. First, try:
$ ./configure LDFLAGS=-L/path/to/lib CPPFLAGS=-I/path/to/include
(where libnuma.a is /path/to/lib/libnuma.a and numa.h is /path/to/include/numa.h.
That is, specify the directories.) If that does not work, check config.log to see what went wrong. If the configure script for the program you are using was built with an old version of autoconf, you may need to do:
$ LDFLAGS=-L/path/to/lib CPPFLAGS=-I/path/to/include ./configure
instead. (The second invocation will only work in Bourne shells. With csh/tcsh, you will need to set the environment variables some other way, for example with env.) You also have the option of making those settings in the environment of your shell (eg, in a .bashrc) or in a config.site file.

Debugging cross-compiled code: Linux->Windows

I'm cross-compiling a project from Linux to target Windows (using mingw). The output is a DLL and p-invoking into it from C# works, but debugging is very difficult. The build outputs a .o file, which can provide symbols to gdb, but basically all I can do there is break on exceptions and find the name of the function that was executing when the exception happened; not even the full stack trace. I can't debug with WinDbg because I don't have .pdb files.
This is an open source project set up to build on Linux; I believe their build process relies on several installed Linux packages to work.
Do I have any options here? Is there a utility that can convert .o files into .pdb? Or some program that can give me more information than gdb when debugging?
Try a IDE that support mingw. For example the open source Code::blocks.
Another possibility is to do it manually: compile it with debug symbols, start you application and attach the GDB debugger to it. It is also part of the MingW32 distribution. Then you can set your breakpoints and debug your application
But I guess using Code::Block is more comfortable
By the way, the GCC compiler does not generate pdb files because it is a propietary format
What xpol means is maybe: if you have a complete mingw installation then Code::blocks can use gdb to visualize a debugging session like it is done in Visual Studio or Eclipse. See chapter "Debugger" at http://www.codeblocks.org/features
You can generate a .pdb file using cv2pdb.exe from Visual D. This works even for programs not written in D if they were compiled with mingw. Once you've downloaded and installed Visual D cv2pdb.exe can be found at C:\Program Files (x86)\VisualD\cv2pdb\cv2pdb.exe.
You can run cv2pdb.exe against an executable like this:
cv2pdb.exe -n target.exe
This will produce a file called target.pdb. Assuming both target.pdb and target.exe are in the current director, you can then use windbg like this:
windbg -sflags 0x80030377 -y . -z target.dmp
In this case I'm also passing a minidump file as target.dmp. This can be omitted. The -sflags 0x80030377 option tells windbg to load target.pdb even though it thinks it doesn't match target.exe.
Note, that it can take windbg a very long time to load target.pdb. Just wait until it no longer says *BUSY* to the left of the command entry box.
Alternatively you can try DrMinGW.

Resources