can gdb allow to see ALL source code? - c++

I was debugging an application created in C ++ for Linux when I realized that the executables in release version were compiled with the -g flag.
My concern is whether it is possible to read the source code of the executable through gdb using list or backtrace (exploiting some know core dump or antoher method)

No, the source code is not included in the executable, even when compiled with -g. What is included are references to the source code, so there's a mapping between program addresses and file and line numbers.
There will also be information in the debug that describe the functions in your program, so there will be information describing each function, the types taken and returned, and what local variables it contains, there's also information about which addresses correspond to which functions. All your types and global variables will also be described in the debug information.
It is possible to split the debug information out of you program using objcopy, the following is taken from the gdb online manual (https://sourceware.org/gdb/onlinedocs/gdb/Separate-Debug-Files.html)
objcopy --only-keep-debug foo foo.debug
strip -g foo
objcopy --add-gnu-debuglink=foo.debug foo
This takes the debug information out of foo and places it in foo.debug, the strips the debug information out of foo and adds a link between foo.debug back to foo.
Now you, as the developer can debug release builds by loading the additional foo.debug file containing the debug data, while the customer is only given foo and so does not see the debug information.
A more detailed look at creating split debug information can be found here How to generate gcc debug symbol outside the build target?

No, source code is not included in a binary built with -g and therefore it will not be possible to read it using only the binary.
Things that they may be able to read include:
Names of variables and functions
For each intruction: full path of source file, line in the file and name of the function it is in

Related

How to debug and step into custom language sources transpiled to C++?

I would like to use a custom preprocessor language along with C++. My sources would be first transpiled to valid C++ with my custom transpiler, then compiled with a regular C++ compiler. Example:
my_transpiler -o source_gen.cpp source.mycpp
g++ -o myapp source_gen.cpp
In that scenario, the debug information generated are associated with the source_gen.cpp file. So I could debug and step into source_gen.cpp. But what if I want to step into the original source file source.mycpp ?
Does debugger as gdb or visual studio, or compiler as clang, gcc, or msvc provide mechanisms to map debug information to the original source file?
As was hinted in a comment to the question, the usual approach to this issue is the #line directive. In particular,
# line digit-sequence " s-char-sequenceopt " new-line
Your transpiler should put this directive for each source line in the original file into the generated file:
#line 3 "source.mycpp"
If your C++ compiler generates debug information based on these directives (the ones I've used do), when you step into the code you'll step into the appropriate spot in source.mycpp.
Instead of generation xxx_gen.cpp files, you can create an additional directory for the generated files and keep the file name for the files. If you have a directory hierarchy, you also can duplicate the whole tree.
After compilation you can in gdb set the source path. This will result in finding the "original" files.
The information will only by valid, if each source line will only generate a single target line. :-)

callgrind no source available for a couple of functions only

I am using linux and I am trying to debug an executable that I launch from the command line. It calls some functions from another custom library that I linked to it. I built both my executable and my library with the debug flags (-g3) then I ran it with callgrind this way:
valgrind --tool=callgrind --trace-children=yes ./my_exe --some_args
For most of the functions, kcachegrind shows the name and the location. But for a couple it just shows the address in hexadecimal format and complains about missing debug information. I just know that the functions come from my custom library.
The functions not being shown call some pthread functions (mainly pthread_mutex_lock and pthread_mutex_unlock) and are themselves called by other functions from the same library that are also not shown.
Despite that, I have some functions from my custom library that are fully displayed (name, file and even source code).
I tried compiling my_exe by linking dynamically my_lib.so:
kcachegrind displays the function location as being in my_lib.so but the name and the file of the function are not shown.
I then tried compiling my_exe by linking statically my_lib.a:
kcachegrind displays the function location as being in my_exe but once again it doesn't show the name nor the file and complains about missing debug infos.
Other functions called from my_exe are also fully displayed as expected (name, file, source code...).
I don't understand why some functions would be displayed and some would not, given that they're in the same executable/library and that I compiled with debug symbols. I expected having either no function names at all or all of them. Am I missing some debug flags from valgrind ? Any ideas ?
Answering my own question in case it helps someone:
I discovered that my custom library A was itself linked with another static library B and that the unsourced functions were arising from B. Since it was static, valgrind considered it as part of A.
I managed to understand that by linking A dynamically with B (B.so), and valgrind told me the function was in libB.so. I could not find the exact name though since I don't have the sources to recompile lib B with debug flags but at least I was able to figure out where the problem was coming from.

GDB Shared Object unable to get symbols in current context

I have a piece of software that is compiled with several shared libraries. My code is calling a function inside the shared object and crashing inside. I believe my problem is how the parameters are being constructed for this function. I want to validate this by viewing what is happening inside the .so such that I can make the correct changes for how I am constructing the parameters.
The problem I a am running into is not being able to resolve local variables within the shared object. For instance gdb will print out:
0x<addr> in <function>(int const* , int, int const*)
Based on this I know where I am inside the .so. When I navigate here and try to find what different variables are being set to gdb complains with:
No symbol <var> in current context.
Now I know for a fact where I am within the code. Additionally, I have checked to make sure the .so was compiled with symbols on and I have also made sure gdb is loading these symbols.
Can anyone inform me on why gdb is unable to see these local variables?
As a note - I haven't used gdb in a while and not to this level of debugging so I am sorry in advance is this is just a limitation of gdb that I am unaware of.
GDB Version: 7.7.1
Edit for comment:
Yes the .so was compile with symbols. I have verified this with:
file <.so>
This tells me it was dynamically linked and not stripped.
As for commands, I simply trying to print variables.
Overall I am not sure why gdb is unable to resolve the source/exact function of the .so when I explicitly loaded it and made sure the .so was compiled with symbols.
I have checked to make sure the .so was compiled with symbols on
Every .so is compiled with symbols on -- it would be useless without symbols.
It's the debugging info that you are compiling without. Add -g flag to your compile lines, and make sure to not have -s or --strip anywhere on your link line.
and I have also made sure gdb is loading these symbols.
Yes, this output <function>(int const* , int, int const*) tells us that GDB has read symbols, and also that it did not load debugging info (these are two completely separate things).

GCC: how to find why an object file is not discarded

I have an executable which links to a big .a archive that contains lots of functions. The executable only uses a small fraction of the functions in this archive, but for some reason it pulls everything from it and ends up being very big.
My suspicion is that some of the functionality that the executable is using somehow references something it shouldn't and that causes everything else to be pulled.
Is it possible to make gcc tell me what reference causes a specific symbol to be added in the executable? Why else can this happen?
I've tried using --gc-sections with no effect.
I've tried using --version-script to make all the symbols in the executable local with no effect
I'm not interested in -ffunction-sections and -fdata-sections since it is while object files I want to discard, not functions.
Other answers mention -why_live but that seem to be implemented only for darwin and I am in linux x86_64
Use -Wl,-M to pass -M to the linker, causing it to print a link trace. This will show you the reasons (or at least the first-found reason) for every object file that gets linked from an archive.

What is *.o file?

I'm compiling own project. And it halted by this error:
LINK||fatal error LNK1181: cannot open
input file
'obj\win\release\src\lua\bindings.o'|
Compiling using Code::Blocks with VS 2005/2008 compiler under win7.
There are also lot of another empty directories where *.o files are missing.
What do they do?
A file ending in .o is an object file. The compiler creates an object file for each source file, before linking them together, into the final executable.
You've gotten some answers, and most of them are correct, but miss what (I think) is probably the point here.
My guess is that you have a makefile you're trying to use to create an executable. In case you're not familiar with them, makefiles list dependencies between files. For a really simple case, it might have something like:
myprogram.exe: myprogram.o
$(CC) -o myprogram.exe myprogram.o
myprogram.o: myprogram.cpp
$(CC) -c myprogram.cpp
The first line says that myprogram.exe depends on myprogram.o. The second line tells how to create myprogram.exe from myprogram.o. The third and fourth lines say myprogram.o depends on myprogram.cpp, and how to create myprogram.o from myprogram.cpp` respectively.
My guess is that in your case, you have a makefile like the one above that was created for gcc. The problem you're running into is that you're using it with MS VC instead of gcc. As it happens, MS VC uses ".obj" as the extension for its object files instead of ".o".
That means when make (or its equivalent built into the IDE in your case) tries to build the program, it looks at those lines to try to figure out how to build myprogram.exe. To do that, it sees that it needs to build myprogram.o, so it looks for the rule that tells it how to build myprogram.o. That says it should compile the .cpp file, so it does that.
Then things break down -- the VC++ compiler produces myprogram.obj instead of myprogram.o as the object file, so when it tries to go to the next step to produce myprogram.exe from myprogram.o, it finds that its attempt at creating myprogram.o simply failed. It did what the rule said to do, but that didn't produce myprogram.o as promised. It doesn't know what to do, so it quits and give you an error message.
The cure for that specific problem is probably pretty simple: edit the make file so all the object files have an extension of .obj instead of .o. There's room for a lot of question whether that will fix everything though -- that may be all you need, or it may simply lead to other (probably more difficult) problems.
A .o object file file (also .obj on Windows) contains compiled object code (that is, machine code produced by your C or C++ compiler), together with the names of the functions and other objects the file contains. Object files are processed by the linker to produce the final executable. If your build process has not produced these files, there is probably something wrong with your makefile/project files.
It is important to note that object files are assembled to binary code in a format that is relocatable. This is a form which allows the assembled code to be loaded anywhere into memory for use with other programs by a linker.
Instructions that refer to labels will not yet have an address assigned for these labels in the .o file.
These labels will be written as '0' and the assembler creates a relocation record for these unknown addresses. When the file is linked and output to an executable the unknown addresses are resolved and the program can be executed.
You can use the nm tool on an object file to list the symbols defined in a .o file.
Ink-Jet is right. More specifically, an .o (.obj) -- or object file is a single source file compiled in to machine code (I'm not sure if the "machine code" is the same or similar to an executable machine code). Ultimately, it's an intermediate between an executable program and plain-text source file.
The linker uses the o files to assemble the file executable.
Wikipedia may have more detailed information. I'm not sure how much info you'd like or need.