Is there a debugger for LLVM IR?

I would like to go through some LLVM IR code that I created. The code is syntactic and type valid for llc and lli, but the results are not what I expected.

The columns are large enough that I was unsuccessful by simply reading the error, and it is difficult for me to create a smaller example with the same error.

I decided that I could use something like a debugger, but for LLVM IR. In other words, I want to go through the llvm code, examine the "infinite" registers (given the names in the LLVM IR file) and memory locations, set breakpoints until I find where my code went wrong.

I looked through lli and lldb , but none of them are the tool I'm looking for. lli will run my code, but will not let me step by step. lldb it seems that the code was generated by C-fronts.

Am I wrong about lldb and lli ? Does anyone know a tool that does even 50% of what I want?

+6
source share
2 answers

I do not know about this (I suspect that this does not exist). Although I enjoyed sharing my thoughts on debugging llvm code.

  • Debug generated code (step though it is in gdb).
  • Use the built-in debugtrap (which just generates int3 or any equivalent of your architecture). You can make statements with this thing and see which ones fail.
  • Give the names of your instructions (therefore they are not %0 , %1 , but significant %names ) - they are displayed as comments in llc .
  • Create a CFG (control flow graph) for your function: opt --dot-cfg 1.ll; dot cfg.funcname.dot -Tpng > 1.png opt --dot-cfg 1.ll; dot cfg.funcname.dot -Tpng > 1.png
  • Remember to disable llvm optimization (you may have a backend -O3 optimization level, but passing IR conversions can make debugging difficult).

So, the workflow that I propose is as follows. Create CFG (4.) and assembly (via llc). Go to the generated code in gdb and go through it (or let it trap on one of your asserions). Compare the point at which you stopped in gdb before the release of llc, read the comment, connect to CFG. Grok.

You can also create a CFG view from the generated code. Of the tools that I know, IDA Pro (a very expensive way to create CFGs) and Saga offers such functionality.

PS: It was originally a comment, but it's been taking too long.

+2
source

I am looking for the same thing and I found this: Debugging JIT-ed Code with GDB .

1) compile with clang and emit bytecode

 clang++ -emit-llvm -D_GNU_SOURCE -D__STDC_LIMIT_MACROS -DDEBUG -O0 -m64 -fomit-frame-pointer -c a.cpp -g -fno-use-cxa-atexit clang++ -emit-llvm -D_GNU_SOURCE -D__STDC_LIMIT_MACROS -DDEBUG -O0 -m64 -fomit-frame-pointer -c b.cpp -g -fno-use-cxa-atexit 

2) link with llvm-link

 llvm-link -o all.bc a.bc b.bc 

3) debugging using gdb and lli using jit

 gdb --quiet --args lli -jit-kind=mcjit all.bc (gdb) b initCloneLookups Function "initCloneLookups" not defined. Make breakpoint pending on future shared library load? (y or [n]) y Breakpoint 1 (initCloneLookups) pending. (gdb) r Starting program: lli -jit-kind=mcjit all.bc [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1". ...... Breakpoint 1, initCloneLookups () at a.cpp:66 66 clone_lookups = new BitBoard64[61]; 

Answer "y" to the given breakpoint.

+1
source

All Articles