Reputation: 1493
I am working on a compiler that translate the source language into C. Then any C compiler could compile that into executable binary.
Though C compiler can attach its own debugging information with the executable, however, those are C-level information. For example, the stack trace displays C functions and line numbers in C, instead of the source code functions and line numbers.
I am pretty much concerned about the following debugging information available to users:
What is the common approach to this when a compiler targets C?
I am looking at GDB's pretty printer. Will that be a possible solution to me?
Upvotes: 3
Views: 528
Reputation: 10261
The method described by Jonathan in his answer is in fact what the C++ compiler did for the first few years of its life; the translator was called cfront.
For printing out data types that aren't native C types, customizing stack traces, and displaying info about custom threading implementations, you can go a fair distance by writing python code to extend GDB. This can be effective whether your compiler's target is C or native code. Go
(which produces native code with its gc
compiler) provides runtime-gdb.py, for example.
Upvotes: 2
Reputation: 213606
What is the common approach to this when a compiler targets C?
There are no common compilers that target C and provide debugging info in the higher-level language. I can't think of any approach that would work at all.
I am looking at GDB's pretty printer. Will that be a possible solution to me?
You may be able to create some "smoke and mirrors" illusion that you are debugging the higher-level language. I doubt you'll find the illusion that you can build that way satisfactory.
Upvotes: 1
Reputation: 754050
If you are careful in your generated C, you can use as system like this. Assuming that your source language file is sourcefile.ext
and that you will generate sourcefile.c
from this.
#line 32 "sourcefile.ext"
C code for line 32 of sourcefile.ext
#line 33
C code for line 33 of sourcefile.ext
However, note that if you generate multiple lines of C code like this:
#line 62 "sourcefile.ext"
first line of C code - will be treated as line 62 of sourcefile.ext
second line of C code - will be treated as line 63 of sourcefile.ext
third line of C code - will be treated as line 64 of sourcefile.ext
#line 63 "sourcefile.ext"
line of C code - will be treated as line 63 of sourcefile.ext again!
people can get confused. You can 'deal' with that using:
#line 62 "sourcefile.ext"
first line of C code - will be treated as line 62 of sourcefile.ext
#line 62 "sourcefile.ext"
second line of C code - will be treated as line 62 of sourcefile.ext too
#line 62 "sourcefile.ext"
third line of C code - will be treated as line 62 of sourcefile.ext too
#line 63 "sourcefile.ext"
line of C code - will be treated as line 63 of sourcefile.ext
However, you can begin to imagine some of the difficulties. Ultimately, you need a native debugger for your language, but that is a daunting prospect. Failing that, I've usually found it best to generate the #line
directives as comments:
//#line 62 "sourcefile.ext"
first line of C code - will be treated as line 91 of sourcefile.c
//#line 62 "sourcefile.ext"
second line of C code - will be treated as line 93 of sourcefile.c
//#line 62 "sourcefile.ext"
third line of C code - will be treated as line 95 of sourcefile.c
//#line 63 "sourcefile.ext"
line of C code - will be treated as line 97 of sourcefile.c
Keep the C code around; debug in the C code, but the C code contains the line numbers that point back to the original source in sourcefile.ext
. You might consider including the source code in the generated C, too, so that the user can see what was written in sourcefile.ext
while debugging in sourcefile.c
.
I make no claims that this is pretty or good. In fact, it is pretty awful. But it does work.
Upvotes: 6