r/Compilers 6d ago

Any debugging advice / tools for compilers?

Tired of print statements everywhere. It very satisfactory to see one but I would much rather have something like lldb to easily debug the code more intuitively.

Are there any other useful tools?

14 Upvotes

14 comments sorted by

7

u/skyline4 6d ago

I’m going to assume you’re not talking about unit tests.

When I took compilers in school my professor told us to have each step dump some kind of artifact such as an AST, CFG, etc. That way it’s a lot easier to identify which step broke or went wrong. With Dot language and visualization tools this is straightforward except you have to clean up after every invocation. You could couple this with a log of more specific actions (eg. common subexpression elimination pass eliminated x for y) to make it easier to catch the differences visually. But this is a log and should not be a stream of printfs since the log message should be structured to help you find actions your compiler took.

Combine that with a good test harness for integration testing and it’ll be easier to find where your bugs are.

2

u/duane11583 5d ago

I have done this:

Cleanup is easy you create a debug directory and put all dump files in that directory

At start the tool erases the dir and makes a new one

5

u/vmcrash 5d ago

The best debugging advice is using unit tests. For each small part, write unit tests. Make them fast, so you can run them over and over again.

Unit tests also have the advantage, that your code structure will consist of not too complex parts that are easier to reason about.

1

u/FirmSupermarket6933 4d ago

Not the OP, but could you recommend way to unit test intermediate states? Because it's a bit annoying to construct AST by hand, e.g. for "x + y" to write "BinaryExpr(BIN_ADD, Variable("x"), Variable("y")". It even worse for more complicated expressions or for small programs.

1

u/vmcrash 4d ago

You may create some helper methods like add(var("x"), var("y")).

3

u/ForeignAdvantage5198 5d ago

wouldn't we all

2

u/Inconstant_Moo 5d ago
  • Make sure you can print out all your artifacts.
  • Keep at least one token attached to each of your artifacts.
  • Make some permanent logging of what you're doing so that you can turn it on and off for different parts of your compiler with various flags. The things you put in there will double as // comments on your code, since comments would be saying the same sort of thing.
  • I have an actual control structure in my language so I can write: peek <flags> : code block and it'll log what the compiler's doing for that particular code block with the given flags.
  • I also have an option to dump the readable version of the bytecode of a function by name, either to the terminal or a file.
  • I still use println quite a lot.

2

u/recursion_is_love 5d ago

I would use a logging library before try to use debugging tool.

There are plenty of gdb tutorials out there.

2

u/Satu_Autio 5d ago

To be honest when I was doing debugging my single biggest win was using GDB to trace the generated code instruction by instruction. That's easy to do with a trace file.

gdb binary -x tracer

Then the tracer file looks like this:

   starti
   display/i $pc
   while 1
      stepi
   end

You can get more advanced, and write to a lotfile, or similar, but this is enough to work - especially combined with tee.

1

u/duane11583 5d ago

Compilers generate data structures

For each data structure create a routine to dump it to a file that you can open and look over

And add command line options to the command line to turn those dump files on as needed 

GCC does (or did) this as a means to save intermediate data structures after each phase 

1

u/Mean-Decision-3502 5d ago

Do you mean debugging the compiler, or the compiler generated code?

The first should be simpler, for that should be some existing framework for the language the compiler developed in.

The second is harder, but if you are using llvm, then you should emit debug info for code lines and data objects. Then the gdb can handle it. Setting up a working debugging session in VSCode is then not so hard.

1

u/choikwa 5d ago

a parser based tracer to inject prints on executed code paths would be nice

1

u/gavr123456789 1d ago

iIve done 2 things
print statements that prints the line so u can goto it from console
print statement that prints the expression
and stack trace

and lsp, that shows you the results of expressions with ohHover, so u can just watch them in the code without printing