Valgrind not showing line numbers on GNU autotools project in spite of -g flag - valgrind

I'm working on a GNU Autotools project where I'm encountering some strange memory allocation errors. I want to use Valgrind to debug, however when I run my executable under it I don't get any line numbers or source file names. I even tried configuring so that optimization is -O0 and with the -g flag for debugging by using the command:
./configure 'CXXFLAGS=-g -O0'
Then I'll run the executable under Valgrind as follows:
valgrind -leak-check=full ./[exename]
and I still only see mysterious outputs like:
==3493== 24 bytes in 1 blocks are definitely lost in loss record 137 of 303
==3493== at 0x4A06409: malloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==3493== by 0x46904A: xmalloc (in /usr/bin/bash)

What you really want is:
libtool --mode=execute valgrind --leak-check=full exename ...

Complementing on ldav1s's answer, this is what I have on my .bashrc:
alias lgdb="libtool --mode=execute gdb"
alias lddd="libtool --mode=execute ddd"
alias lvalgrind="libtool --mode=execute valgrind"
alias lvalgrinddd="libtool --mode=execute valgrind --db-attach=yes --db-command=\"ddd %f %p\""
This way I don't have to type the rather long command line.

This is resolved by invoking the executable using libtool in "execute" mode as described by ldav1s and also in the manual here: libtool: Debugging-executables. Thanks for the insight ldav1s!

Related

How do I make makefile generatedby cmake output the last command when error occur? [duplicate]

I use CMake with GNU Make and would like to see all commands exactly (for example how the compiler is executed, all the flags etc.).
GNU make has --debug, but it does not seem to be that helpful are there any other options? Does CMake provide additional flags in the generated Makefile for debugging purpose?
When you run make, add VERBOSE=1 to see the full command output. For example:
cmake .
make VERBOSE=1
Or you can add -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON to the cmake command for permanent verbose command output from the generated Makefiles.
cmake -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON .
make
To reduce some possibly less-interesting output you might like to use the following options. The option CMAKE_RULE_MESSAGES=OFF removes lines like [ 33%] Building C object..., while --no-print-directory tells make to not print out the current directory filtering out lines like make[1]: Entering directory and make[1]: Leaving directory.
cmake -DCMAKE_RULE_MESSAGES:BOOL=OFF -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON .
make --no-print-directory
It is convenient to set the option in the CMakeLists.txt file as:
set(CMAKE_VERBOSE_MAKEFILE ON)
Or simply export VERBOSE environment variable on the shell like this:
export VERBOSE=1
cmake --build . --verbose
On Linux and with Makefile generation, this is likely just calling make VERBOSE=1 under the hood, but cmake --build can be more portable for your build system, e.g. working across OSes or if you decide to do e.g. Ninja builds later on:
mkdir build
cd build
cmake ..
cmake --build . --verbose
Its documentation also suggests that it is equivalent to VERBOSE=1:
--verbose, -v
Enable verbose output - if supported - including the build commands to be executed.
This option can be omitted if VERBOSE environment variable or CMAKE_VERBOSE_MAKEFILE cached variable is set.
Tested on Cmake 3.22.1, Ubuntu 22.04.
If you use the CMake GUI then swap to the advanced view and then the option is called CMAKE_VERBOSE_MAKEFILE.
I was trying something similar to ensure the -ggdb flag was present.
Call make in a clean directory and grep the flag you are looking for. Looking for debug rather than ggdb I would just write.
make VERBOSE=1 | grep debug
The -ggdb flag was obscure enough that only the compile commands popped up.
CMake 3.14+
CMake now has --verbose to specify verbose build output. This works regardless of your generator.
cd project
cmake -B build/
cmake --build build --verbose
It's worth noting however Xcode may not work with --verbose
Some generators such as Xcode don't support this option currently.
Another option it to use the VERBOSE environment variable.
New in version 3.14.
Activates verbose output from CMake and your build tools of choice when you start to actually build your project.
Note that any given value is ignored. It's just checked for existence.
cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=TRUE will generate a file with all compilation commands.
This file is required by some LSP to know how to compile a source file out of the box, but it could also help for debugging compilation problems.
The output file is named ${CMAKE_BINARY_DIR}/compile_commands.json.

How to fix libtool: undefined symbols not allowed in x86_64-pc-msys shared

I am trying to build heimdal package for msys2. To my dismay, during linking of the first constituent library, roken, dlls fail to be built, and that causes sort of a chain reaction further on.
The only message i get is:
libtool: undefined symbols not allowed in x86_64-pc-msys shared ... only static will be built
however, there is no information provided on what symbols are undefined. How can i find that out?
If i turn on output of commands wuth make V=1 i get libtool command that links from a large numbert of .lo files. If i try to run gcc over them (copying command from there), it does not recognize them as anything.
I am trying to follow instructions as outlined in msys2 package build script for heimdal.
On Windows building a shared library while allowing undefined symbols is not allowed.
Try to build with the -Wl,-no-undefined linker flag, for example by adding LDFLAGS="-Wl,-no-undefined" to the ./configure command.
If that didn't work try this after ./configure and before make:
sed -i.bak -e "s/\(allow_undefined=\)yes/\1no/" libtool
If you already had a failed build earlier you should also clean up any .la files like this before running make again:
rm $(find -name '*.la')

Why I cannot get Valgrind diagnostic information with CMake?

I am now running CTest with or without Valgrind in Ubuntu Linux. Firstly, I set up a CMakeLists.txt script to enable testing:
enable_testing()
include(CTest)
if(UNIX)
set(CTEST_MEMORYCHECK_COMMAND, "usr/bin/valgrind")
set(CTEST_MEMORYCHECK_COMMAND_OPTIONS, "--trace-children=yes --leak-check=full")
endif()
add_test(NAME test
WORKING_DIRECTORY ${my_outputdirectory}
COMMAND test_exe)
When I run the test without valgrind, I use the following command:
cmake -G "CodeBlocks - Unix Makefiles"
ctest -D ExperimentalBuild
ctest -R test -D ExperimentalTest
That works fine. However, when I run the following command to invoke valgrind:
cmake -G "CodeBlocks - Unix Makefiles"
ctest -D ExperimentalBuild
ctest -R test -D ExperimentalMemChec
the following message appear:
--Processing memory checking output:
Memory checking results:
This is definitely not the diagnostic information I expect. I was wondering what I should do next. Thanks!
EDIT:
Later on, I find that the diagnostic information can be available only in the case where the memory leak happens. However, the diagnostic information is very vague in the sense that the location where the error occurs is not given. How could I obtain more detailed information?
By default, CMake does not build debug symbols for Makefile projects, so Valgrind is unable to determine the exact location of a leak in source code.
Try running cmake with
cmake -DCMAKE_BUILD_TYPE=Debug /path/to/source
which should add the compiler option for building debug symbols.
I use a python script which parses my memory leaks from valgrind it is available here.
In CMake I use the following command to add a memory test:
ADD_TEST(testName ${Test_Dir}/memtest.py ${CMAKE_CURRENT_BINARY_DIR}/testExecutable ${CMAKE_BINARY_DIR})
Such that I do not need to parse the memory leak errors direct in cmake. The python script simply executes a memory check with valgrind on the executable and returns an error if a leak was found. If a leak was found the test then fails otherwise it passes. Hope this might help you.
CMake by default uses the following command line arguments for valgrind memcheck:
--log-file=/Path/to/build-dir/Testing/Temporary/MemoryChecker.1.log \
-q --tool=memcheck --leak-check=yes --show-reachable=yes --num-callers=50
Note that the --log-file argument means that any valgrind errors ends up in that file. I find it more useful when valgrind posts the information to the stderr, so a build server like Jenkins or TeamCity can show it more easily. In order to do that, you have to set the MEMORYCHECK_COMMAND_OPTIONS variable with --log-fd=2 (and other options if you'd like) so it overrides the --log-file option.
More info here.

G++: error: unrecognized option ‘-soname’

I am trying to build SLitrani on Ubuntu 12.04 64-bit. I have already built ROOT 5.34.03 from source and I did figure out how to set the LD_LIBRARY_PATH and PATH variables for $ROOTDEV so the problem is not there but when I try to make SplineFit I get
>>> g++: error: unrecognized option ‘-soname=libSplineFit.so’
make: *** [libSplineFit.so] Error 1
I also did change all the -m32 to -m64 in the Makefiles so I don't know what is going on. I was able to get TwoPad installed but I can't continue from SplineFit. I have been on this build for quite some time and would appreciate any help.
From memory, soname is a linker operation, not a compiler one. So, if you're doing it with g++, you may need to change the option into something like:
-Wl,-soname=libSplineFit.so
The following transcript shows that this is necessary:
pax> g++ --soname=x -Wall -o qq qq.cpp
cc1plus: error: unrecognized command line option "-fsoname=x"
pax> g++ -Wl,-soname=x -Wall -o qq qq.cpp
pax>
From the online GNU docs for gcc:
-Wl,option: pass option as an option to the linker. If option contains commas, it is split into multiple options at the commas.
I know this is an old question but after a week of struggling I thought I should post my findings.
I've successfully edited the makefiles for this so they can compile on Ubuntu 12.04 x64.
You can remove the -soname option completely, it seemingly is unnecessary.
As mentioned: all "m32" change to "m64".
You can replace "$ROOTSYS/libs" with "$ROOTLIBS"
and with TwoPad makefile reorder the library order (under LIBS += (.....)) so that -lTwoPad is NOT last on the list, and for VisuSLitrani make -lPhysMore last in its group.
As far as I know the errors saying "set but not used" can be ignored.
If any of this still doesn't work contact me back and I can send you my makefiles.
Here a nice explanation of the -soname linker option, how to call it and what it is good for.
Summary
You can simply use gcc -shared -Wl,-soname,libfoo_v1.so -o libfoo_v1.so libfoo_v1.o and skip the following discussion ;)
call it as gcc -shared -Wl,-soname,libfoo.so -o libfoo_v1.so libfoo_v1.o
after compiling you need to create an symbolic link pointing to libfoo_v1.so ln -s libfoo_v1.so libfoo.so before you can execute your code.
This is used to link against different shared libraries during compiletime and runtime. Obviously these libraries need a similar interface. You can use this for managing different versions.

Can not compile simple C# application with mkbundle

I have written some console "Hello world"-like app. and have followed c# cywgwin mono mkbundle windows 7 - cannot compile file answer. But I have got:
$ mkbundle -o Fur Furries.exe --deps -z
OS is: Windows
Sources: 1 Auto-dependencies: True
embedding: C:\Monotest\Furries.exe
compression ratio: 40.43%
embedding: C:\Soft\Mono\lib\mono\4.0\mscorlib.dll
compression ratio: 34.68%
Compiling:
as -o temp.o temp.s
gcc -mno-cygwin -g -o Fur -Wall temp.c `pkg-config --cflags --libs mono-2|dos2un
ix` -lz temp.o
temp.c: In function `main':
temp.c:173: warning: implicit declaration of function `g_utf16_to_utf8'
temp.c:173: warning: assignment makes pointer from integer without a cast
temp.c:188: warning: assignment makes pointer from integer without a cast
/tmp/ccQwnxrF.o: In function `main':
/cygdrive/c/Monotest/temp.c:173: undefined reference to `_g_utf16_to_utf8'
/cygdrive/c/Monotest/temp.c:188: undefined reference to `_g_utf16_to_utf8'
collect2: ld returned 1 exit status
[Fail]
It's in Windows XP.
First of all, prepare development environment:
Install Mono. For example, you have installed it into "C:\Soft\Mono".
Install Cygwin. When selecting which packages to install select following: gcc-mingw, mingw-zlib, pkg-config, nano.
Start Cygwin Bash shell (either using a link or "bash --login -i" command).
Open "$HOME/.bashrc" with "nano" ("nano ~/.bashrc"). Don't use editors which don't preserve end-of-line-s ("CR", "LF", "CR/LF" or other), or it will corrupt the file!
Add following lines to the end of the file:
export PKG_CONFIG_PATH=/cygdrive/c/Soft/Mono/lib/pkgconfig
export PATH=$PATH:/cygdrive/c/Soft/Mono/bin
Restart Cygwin Bash shell.
After that you can compile your assemblies with "mkbundle":
Perform the following command: "mkbundle -c -o host.c -oo bundle.o --deps YourAssembly.exe <additional arguments>". You also may optionally pass "-z" to compress resultant bundle. You should get "host.c" and "bundle.o" files.
In "host.c" you should remove "_WIN32" "branch" (except "#include <windows.h>" one). It doesn't work. You may do it just by adding "#undef _WIN32" right after following lines in it:
#ifdef _WIN32
#include <windows.h>
#endif
So you'll get:
#ifdef _WIN32
#include <windows.h>
#endif
#undef _WIN32
Perform the following command: "gcc -mno-cygwin -o ResultantBundle.exe -Wall host.c `pkg-config --cflags --libs mono-2|dos2unix` bundle.o <additional arguments>". If you added a -z additional argument in step 2, you must add a -lz additional argument in this step.
You will get "ResultantBundle.exe". This is your Mono application packed as standalone executable.
It still requires "mono-2.0.dll" and some additional DLL-s and resources you depended on during development (for example, it may require GTK# native DLL-s) but it doesn't require full Mono runtime to run.
Just wanted to add that if you pass -z to mkbundle then you'll need to pass -lz to gcc. I had some issues getting an application with winforms and net access to work properly, and I had to copy machine.config from C:\Mono\etc\mono\4.0\machine.config to where my application was. I then passed --machine-config machine.config to mkbundle.
All of these steps are pretty confusing and frustrating, why is not as simple as just typing mkbundle --deps app.exe? I tried making a change to the template used by mkbundle and compiling it myself, but it wont run. I've gone as far now as to download the mono source and attempt to build the whole thing, but I doubt it will work. If anyone can explain what the hell is going on with mkbundle to make this so annoying, I'd be interested in contributing.
after you have the temp.o and temp.c, you can add them to visual c++ to make a windows application with other sources.