Search code examples
clangllvmllvm-clangllvm-irdwarf

How to dump DWARF information into a file while llvm compiles?


I'd like to know how I might insert some code while llvm compiles IR so that a DWARF information file can be generated.

(I'm not asking for using objdump/llvm-dwarfdump tools after the binary is generated)

Thx in advance.


I tried Eli's answer and I got seg fault here, probably I misused it?

clang-3.7 -g -emit-llvm -c main.c -o build/main.bc
clang-3.7 -g -emit-llvm -c sum.c  -o build/sum.bc
llvm-link-3.7 build/main.bc build/sum.bc -o build/main.linked.bc
llc-3.7 -split-dwarf Enable build/main.linked.bc -o build/main

main.c:

#include <stdio.h>

int sum(int x, int y);

int main()
{
    int r = sum(3, 4);
    printf("r = %d\n", r);
    return 0;
}

sum.c:

int sum(int x, int y) {
    return x + y;
}

Seg fault info:

0  libLLVM-3.7.so.1 0x00002b332cdf0af8 llvm::sys::PrintStackTrace(llvm::raw_ostream&) + 56
1  libLLVM-3.7.so.1 0x00002b332cdeff59
2  libc.so.6        0x00002b332e0bdd40
3  libLLVM-3.7.so.1 0x00002b332c86d146 llvm::MCExpr::print(llvm::raw_ostream&, llvm::MCAsmInfo const*) const + 134
4  libLLVM-3.7.so.1 0x00002b332c86d243 llvm::MCExpr::print(llvm::raw_ostream&, llvm::MCAsmInfo const*) const + 387
5  libLLVM-3.7.so.1 0x00002b332c84e356
6  libLLVM-3.7.so.1 0x00002b332c2f4927 llvm::AsmPrinter::EmitLabelPlusOffset(llvm::MCSymbol const*, unsigned long, unsigned int, bool) const + 87
7  libLLVM-3.7.so.1 0x00002b332c2fe6df llvm::AsmPrinter::emitDwarfDIE(llvm::DIE const&) const + 111
8  libLLVM-3.7.so.1 0x00002b332c2fe713 llvm::AsmPrinter::emitDwarfDIE(llvm::DIE const&) const + 163
9  libLLVM-3.7.so.1 0x00002b332c325a29 llvm::DwarfFile::emitUnits(bool) + 105
10 libLLVM-3.7.so.1 0x00002b332c323bf0 llvm::DwarfDebug::endModule() + 992
11 libLLVM-3.7.so.1 0x00002b332c2fc251 llvm::AsmPrinter::doFinalization(llvm::Module&) + 513
12 libLLVM-3.7.so.1 0x00002b332c6424b5 llvm::FPPassManager::doFinalization(llvm::Module&) + 69
13 libLLVM-3.7.so.1 0x00002b332c64c09d llvm::legacy::PassManagerImpl::run(llvm::Module&) + 797
14 llc-3.7          0x0000000000413d1f
15 llc-3.7          0x000000000040ea50 main + 384
16 libc.so.6        0x00002b332e0a8ec5 __libc_start_main + 245
17 llc-3.7          0x000000000040eaa9
Stack dump:
0.  Program arguments: llc-3.7 -split-dwarf Enable build/main.linked.bc -o build/main

Solution

  • (Adding as an answer because the comment was becoming too long)

    FWIW we only support split dwarf on linux right now due to needing an objcopy that supports the use, OS X does it's own thing, and we don't have any solution for windows right now.

    That said, for linux:

    clang -gsplit-dwarf -g foo.c -o foo.o
    clang -gsplit-dwarf -g bar.c -o bar.o
    

    will produce .dwo files for foo.o (foo.dwo) and bar.o (bar.dwo) respectively.

    If you want a dwarf file for the entire program you'll need to use the dwp utility to merge all of the various .dwo files into a single package file. You need to use the clang driver to do the first part since it knows how to invoke objcopy on each individual file, llc doesn't have the knowledge built into it (though it'll produce correct dwarf output, it just won't split it out).

    For Mac OSX you can do this via the dsymutil program which comes on the system. clang -g foo.c -o foo will produce a .dSYM directory which has the dwarf for the entire program.

        issola:~/tmp> ls -l a.x.dSYM/Contents/Resources/DWARF/a.x   
        -rw-r--r--  1 echristo  5001  9071 Jul 19 20:28  a.x.dSYM/Contents/Resources/DWARF/a.x