[patch] New feature: debug info in add2line format (--jit-emit-debug-addr2line)

This new option will allow to output function information in the same format as addr2line from binutils emits:
...
0xABCDEF01 T function_name_is_here
...

This feature is useful to profile the code when it is run in JIT by external tools like valgrind and google-perftools.
For example, google-perftools runs addr2line on executable and uses the resulting file to resolve memory addresses to function names. In case of LLVM JIT the resulting from --jit-emit-debug-addr2line option addr2line-formatted file can be just appended to the original addr2line file to allow google-perftools to show created by JIT functions as well.

Thank you,
Yuri

patch-addr2line.txt (5.08 KB)

Please do not check this in yet.
I will post an updated patch.

Yuri

This new option (--jit-emit-debug-function-range) will allow to output function information for memory ranges that functions occupy in memory while they run in JIT. File format generated is like this:
...
0x5000000 0x5001000 function_name_is_here
...

This feature is useful for external tools like valgrind and google-perftools to profile the code when it is run in JIT. Particularly google-perftools will have a special option (--external_symbols) that will be able to import this file.

Note: to be useful this flag should be used with -disable-fp-elim to generate standard prologs.

Thank you,
Yuri

patch-debug-info.txt (4.91 KB)

Have you found http://llvm.org/docs/DebuggingJITedCode.html? The JIT
already has support for something like this for gdb's benefit.
Perftools and valgrind just don't know how to find it yet.

Yes, I saw it and tried it. -jit-emit-debug generates ELF image in memory with debug info.
Another option -jit-emit-debug-to-disk creates .o ELF files with debug info, one per function. If there are thousands of functions there will be thousands of files.

perftools can't use the first option, since it only collects stack address information during the run. And it would be very difficult/impractical to list all (thousands) of the resulting .o files into pprof's command line. Same with valgrind and very slow to load them since pprof runs addr2line per object file. This will take forever.

So option -jit-emit-debug-function-range is meant to amend the above two. It creates just one file with information just sufficient for perftools.

Yuri

Sounds good. It's probably overkill, but it would be nice if
perftools could be made to Just Work with the JIT debugging interface.

Reid

Here is the corresponding patch to google-perftools. Both patches create a nice perftools profile with all functions in JIT.

http://code.google.com/p/google-perftools/issues/detail?id=255

Yuri

patch-debug-info.txt (4.78 KB)

Anybody can check this in?

Yuri

Hi Yuri,

This doesn't seem specific to the JIT. Can you add this to the normal code generator, and have the JIT leverage off that? Here are some minor comments, but the bigger issue of how this integrates seems important.

Instead of begin a flag in TargetOptions, can this be an ExecutionEngine parameter?

This doesn't look like a valid forward declaration:

+ raw_fd_ostream* JITEmitDebugInfoFunctionRangeStream(NULL);

+EmitJitDebugInfoFunctionRange("jit-emit-debug-function-range",
+ cl::desc("Emit debon memory address range information, one line per function"),

Typo in the cl::desc value.

+ // write brief debug info is requested
+ if (JITEmitDebugInfoFunctionRange) {
+ *JITEmitDebugInfoFunctionRangeStream << I.FnStart << " " << I.FnEnd << " " << F->getName() << "\n";
+ }

This doesn't seem specific to the JIT. Can you add this to the normal code generator, and have the JIT leverage off that? Here are some minor comments, but the bigger issue of how this integrates seems important.
   
Why this isn't specific to JIT? It outputs memory addresses of functions while they are run in JIT. Can code be run within LLVM in some other way than JIT?

This doesn't look like a valid forward declaration:

+ raw_fd_ostream* JITEmitDebugInfoFunctionRangeStream(NULL);
   
This isn't the forward declaration, but the definition of the static value.

Yuri

This doesn't seem specific to the JIT. Can you add this to the normal code generator, and have the JIT leverage off that? Here are some minor comments, but the bigger issue of how this integrates seems important.
  
Why this isn't specific to JIT? It outputs memory addresses of functions while they are run in JIT. Can code be run within LLVM in some other way than JIT?

I don't know, good question. If it really is specific to the JIT, please sink it down into JIT specific code.

This doesn't look like a valid forward declaration:

+ raw_fd_ostream* JITEmitDebugInfoFunctionRangeStream(NULL);
  
This isn't the forward declaration, but the definition of the static value.

Ok, well that is extremely non-obvious. Please use initialization syntax with "= NULL".

-Chris

I resubmitted the similar patch as a PR: http://llvm.org/bugs/show_bug.cgi?id=8518
Its all in JIT code now, except the new option definition itself.

Yuri