GCC - generate absolute paths for #includes in debug symbols - gcc

OS is Windows, GCC is 4.7.2, GDB is 7.3.
I have a .c file in the C:/project/src/ folder with an include:
#include "../inc/header.h"
After the compilation I have a relative path in the debug symbols:
> objdump -WL obj.o | grep header.h
C:/project/src/../inc/header.h
...
Yet I want it to be C:/project/inc/header.h, because setting BPs in gdb fail for me if I use absolute paths when issuing the set breakpoint command.
This situation is artificial, but due to the environmental conditions the only solution to my issue will be either absolute paths generation in the debug symbols or teaching GDB to resolve relative paths.
Is there a switch for GCC to turn on the absolute path generation in the debug symbols?

The solution is in GDB, not GCC.
The easiest way is to add the directory containing the header to the search path:
(gdb) directory /path/to/include/
A more complicated one that you might need is pathname substitution rules:
(gdb) set substitute-path ../inc /path/to/inc

Related

Understanding the gcc abbreviations

I just took a look to the gcc-arm-none-eabi compiler binaries which are listed bellow but I really do not know all the used abbreviations. I would like to know which binary is the preprocessor, the linker, the compiler and so on ...
$ ls /opt/gcc-arm-none-eabi-5_4-2016q3/bin/
arm-none-eabi-addr2line
arm-none-eabi-ar
arm-none-eabi-as
arm-none-eabi-c++
arm-none-eabi-c++filt
arm-none-eabi-cpp
arm-none-eabi-elfedit
arm-none-eabi-g++
arm-none-eabi-gcc
arm-none-eabi-gcc-5.4.1
arm-none-eabi-gcc-ar
arm-none-eabi-gcc-nm
arm-none-eabi-gcc-ranlib
arm-none-eabi-gcov
arm-none-eabi-gcov-tool
arm-none-eabi-gdb
arm-none-eabi-gdb-py
arm-none-eabi-gprof
arm-none-eabi-ld
arm-none-eabi-ld.bfd
arm-none-eabi-nm
arm-none-eabi-objcopy
arm-none-eabi-objdump
arm-none-eabi-ranlib
arm-none-eabi-readelf
arm-none-eabi-size
arm-none-eabi-strings
arm-none-eabi-strip
I just can guess: gcc is the compiler? ld is the linker?
What is the exact purpose of all these binaries?
The leading 'arm-none-eabi' is the type of compiler. This is known as the tuple and is specified as a configure 'prefix'. Many of the binaries may be links or short wrapper scripts that call another binary (gcc). Also some of the names are just in case you have existing system binaries with the same name or multiple gcc installs.
You can find this information by running a man command on the program name. Briefly,
addr2line - convert an address (hex) to a code line number.
ar - a static library (or archive) tool.
as - an assembler
c++ - the C++ front-end
c++filt - convert a mangled name to function with prototypes.
cpp - the preprocessor only.
elfedit - elf header manipulation.
g++ - C++ with gnu extensions.
gcc - standard binary (given options can do the same as wrappers).
gcc-5.4.1 - full name for system with multiple GCC installs.
gcc-ar - rename in case of multiple 'ar'.
gcc-nm - rename in case of multiple 'nm'.
gcc-ranlib - rename in case of multiple 'ranlib'.
gcov - code coverage
gcov-tool - code coverage
gdb - the debugger
gdb-py - more minimal debugger
gprof - call graph/profiler.
ld - the linker (most likely gold).
ld.bfd - an older style linker with a few more features; MUCH slower for large C++ projects.
nm - display 'names' in a binary.
objcopy - manipulate a binary (sections).
objdump - information on a binary.
ranlib - generate a library index.
readelf - information on ELF binaries.
size - program section sizes
strings - dump all strings in a binary.
strip - remove debug information from a binary.
As a concept, the name 'gcc-ar' and 'ar' are physically the same thing. However, another 'ar' may exist in the path (a Solaris, or other Unix system) and the 'gcc-ar' name can be used to get the gcc specific 'ar'; all the 'gcc-XXX' things are for this use case.

What is difference between objcopy and dsymutil?

Are these two commands on linux:
objcopy --only-keep-debug foo foo.dbg
objcopy --add-gnu-debuglink=foo.dbg foo
equivalent to below on mac
dsymutil <binary> -o <binary>.dSYM
Equivalent in the sense that,
It creates a standalone debug info file.
It create a link between the executable and debug info file.
Then for stripping
is the commands on linux:
objcopy --strip-debug foo
OR
strip -g <binary>
equivalent to below on mac
strip -S <binary>
The --only-keep-debug part of the objcopy does functionally the same thing as dsymutil.
There isn't any tool to record the binary location in the dSYM. Rather the dSYM & the binary share a common UUID, and clients that want to find symbol files use the DebugSymbols framework, which uses various tricks (e.g. a Spotlight importer, search paths, a "dSYM finding external script", etc) to find the separate debug file. So there isn't a need for an equivalent to --add-gnu-debuglink.
The mac version of strip -S does strip debug information the same way that the binutils version does. The difference is that strip -S on OS X won't actually decrease the size of the binary much. On OS X, the debug information is always kept out of the executable - residing either in the .o files or in the dSYM. The executable only has a small "debug map" that tells lldb or dsymutil how to link the dwarf from the .o files. strip -S only has to remove the debug map.

Having CMake include_directories SYSTEM dirs prefix with equals character (=)

Is there a way to have CMake include_directories include the system directory prefix with equals(=) character? So that I can have gcc prefix the associated dirs with -isysroot flag for the cross compilation.
When I try to include the path with equals(=) prefix, assumes relative path and prefixes with current source path:
include_directories(AFTER SYSTEM "=/usr/include")
results:
-isystem /root/opencv-2-4-9/opencv/modules/highgui/=/usr/include/
what I expect is:
-isystem=/usr/include/
I checked the source code of CMake (both 2.8.12.2 and 3.0.0); It seems CMake adds current source directory all paths which are not starting with '/' in non windows systems.
Only exception is generator expressions. If path starts with "$<", then it skips prefixing the path and does not prefix it after evaluation of the generator expression. Therefore
include_directories(AFTER SYSTEM "$<1:=>/usr/include")
generates
-isystem =/usr/include/
This seems to be working at least for CMake 3.0.0. Ofcourse you should set CMAKE_SYSROOT for gcc to prefix with proper path.
set(CMAKE_SYSROOT /usr/arm-linux-gnueabi)
Set it together in one command:
set_target_properties(<targetname> PROPERTIES COMPILE_FLAGS "-isystem=/usr/include/")

Does relative path within the debug info depends on compiler or makefile?

anyone knows the relative path within the debug info depends on compiler or makefile ?
i like relative info, because i can put my project everywhere;
but sometimes, debugger can't find source code due to the dismatching path.
I don't know who controls using relative path or absolute path in debug info, maybe the compiler, maybe makefile, and maybe both;
anyone knows exactly?
Your question is a little fuzzy around the edges, but...
With the compiler and debugger I use, the choice of relative or absolute is determined by the paths passed to the compiler. So if you want to change the behavior, you have to change the command which invokes the compiler, which means changing the command in the makefile.
anyone knows exactly?
You didn't provide sufficient details in your question to answer it exactly.
The Makefile defines the command your make will execute.
If you execute $(CC) -g -c foo.c -o foo.o, then most compilers will
encode relative path foo.c into the object file. Some compilers
will also encode current compilation directory, so the debugger can
find the original foo.c even after you've copied the binary
somewhere else (gcc on Linux will do that, as would most other
compilers that use DWARF debug info).
On the other hand, if you Makefile executes $(CC) -g -c /path/to/src-directory/foo.c -o /path/to/obj-dir/foo.o, then most compilers will encode full path into the object file.

How to write Makefiles to get a relative path in debug symbols?

I have a structure of code like this:
project_dir/
source1.c
subdir/
source2.c
The Makefile calls subdir/Makefile, so that the file subdir/source2.c is compiled in this way:
gcc -g -someoptions source2.c
and symbols in GDB link to source2.c instead of subdir/source2.c (with the result that GDB can not find symbols in source files). How should I write a Makefile or what options to use in gcc to get symbols using the relative path to the project main directory (or eventually the absolute path)?
I can not use:
cd .. && gcc -g -someoptions ../subdir/source2.c
because I would have to change references to header files in all files in subdir.
Your question is platform-specific (e.g. on Linux GDB should just work(TM), so I assume you are not on Linux).
One option is to build like this:
gcc -g ${PWD}/source2.c -o ...
Another option is to use GDB dir command to add ${TOP}/project_dir/subdir to the list of directories that GDB will search for sources.

Resources