Showing original source when debugging generated code in GDB - c++

I am writing a programming language that compiles to C++, and wish to debug using GDB. When I debug the programs, I (of course) see the generated code. Is there a way to hav GDB instead display the source file that created the generated code?

Is there a way to hav GDB instead display the source file that created the generated code?
Sure: you must emit #line directives into your generated C++, and you need to generate already preprocessed source (which you very likely already do) into .ii files. Feeding .ii file into g++ will suppress preprocessing, and g++ will respect any #line directives it finds and emit appropriate source location debug info. Documentation.

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. :-)

Using clang or g++/gcc to print preprocessed code without including files from system paths

currently I'd like to debug my includes. To do this I want to get the preprocessed code, but without any system header files - just my own code.
I tried it with flag "-E" and "-nostdinc". But then I get errors that for example <string> is missing. How to disable such preprocessing errors?
How to disable such preprocessing errors?
You could create a set of headers files with names matching the standard library headers. Put those headers in the include directory. Let the files be empty.
Using clang or g++/gcc to print preprocessed code without including files from system paths
I can see two other approaches besides the empty header approach:
Instead of using the full pre-processor of the compiler, write your own pre-processor that only does the subset of processing that you want.
Or, write a post-pre-processor that removes the standard header content from the pre-processed result.
(It's not really an answer - just a "hack")
To solve this I created a text file with all system headers by:
rem my GCC STL-PATH
cd Z:\usr\include\c++\10
dir /b > F:\DummySTL\files.txt
Then I executed the following line of code:
for /f "delims=" %F in (files.txt) do copy nul "%F"
This creates an empty text file for every line in the file.
Now I can call gcc or clang just with:
-isystem"F:\DummySTL"
Using clang or g++/gcc to print preprocessed code without including files from system paths
This is not easily possible with GCC. Read about how to invoke GCC.
But you could get all the preprocessed code using g++ -C -E and use some script (perhaps with GNU gawk) to remove the useless parts.
currently I'd like to debug my includes.
I have the habit of generating all the preprocessed code and then use GNU less to look inside it. Disk space is cheap.
Alternatively, consider writing your own GCC plugin doing what you need.

can gdb allow to see ALL source code?

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

Can i compile a c++ file within a c++ file execution without any extra programs or installations?

I was reading on Clang and Ch (c++ interpreters), but its not clear for me, is it possible to run a newly generated .cpp file without any installations? Because i need to run the final program on any pc...
ps. if yes, does anyone have a good example, where a .cpp file is being executed within c++ code?
This is probably impossible or at least very hard. You would have to include the whole compiler (including linker, assembler, optimizer, preprocessor, ...) inside your program and that would make it extremely big.
One way of doing this is with Clang (as you already noted), there is even a demo project called "Clang interpreter" in the source: http://llvm.org/viewvc/llvm-project/cfe/trunk/examples/clang-interpreter/
However I once tried to compile this "beast" into my program and gave up halfway, because the file size of the result binary (or binaries with external libraries) gets into tens of megabytes (maybe even a hundred).
My suggestion is to either produce a different script (e.g. bash/sh script, which you could execute on any unix machine) that can be interpreted easily.
As far as I know, it is impossible, because compilation process of a CPP file is like this-
Preprocessing: the preprocessor takes a C++ source code file and deals with the #includes, #defines and other preprocessor directives. The output of this step is a "pure" C++ file without pre-processor directives.
Compilation: the compiler takes the pre-processor's output and produces an object file from it.
Linking: the linker takes the object files produced by the compiler and produces either a library or an executable file.
So, there should be intermediate files and executable files.
More can be found here-
https://stackoverflow.com/a/6264256/7725220
Kind of depends on what you mean by "installations".
Yes you can distribute your program with a full compiler, compile the source code and then execute the final result (all from the original exe).

How can I get the compiler tell me what file #define a value?

My code is linking against several other libraries that are also developed at my company, one of these libraries is redefining several values from errno.h, I would like to be able to fix this, however I am having trouble finding the exact file that is redefining these values, I am want to know if there is a way to make the compiler tell me when a file has defined a particular value.
You can probably do it by adding -include errno.h to the command line that builds the library in question. Here's a quick example. I have a C program called "file.c":
#define ESRCH 8
That's it - then I compile with:
cc -c -include errno.h file.c
And presto, a compiler warning:
file.c:1:1: warning: "ESRCH" redefined
In file included from /usr/include/errno.h:23,
from <command-line>:0:
/usr/include/sys/errno.h:84:1: warning: this is the location of the previous definition
That will tell you where your bad definitions are.
Have you tried searching with grep?
If you don't want to search through all your headers for the particular #define, you could use
#undef YOUR_MANIFEST_CONSTANT
after each #include in your source module and then start removing them from the bottom up and see where your definitions come from.
Also, your compiler may tell you that a #define has been redefined. Turn all your warnings on.
With GCC I did something similar with:
g++ input.cc -dD -E > cpp.out
-dD tells cpp to print all defines where they were defined. And in the cpp output there are also markers for the include file names and the line numbers.
It is possible that some environments, I'm thinking IDE's here, have configuration options tied into the "project settings" rather than using a configuration header. If you work with a lot of other developers in a place where this behavior is NOT frowned on then you might also check your tool settings.
Most compilers will tell you where the problem is, you have to look and think about what the diagnostic notification is telling you.
Short of that, grep/findstr on *nix/Windows is your friend.
If that yields nothing then check for tool settings in your build system.
Some IDE's will jump to the correct location if you right click on the usage and select 'go to definition'.
Another option if you're really stuck is a command line option on the compiler. Most compilers have an option to output the assembler they generate when compiling C++ code.
You can view this assembler (which has comments letting you know the relative line number in the C++ source file). You don't have to understand the assembler but you can see what value was used and what files and definitions were included when the compiler ran. Check your compiler's documentation for the exact option to use