New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
assertion thrown in codegen of debug info "Multiple main" #3866
Comments
I saw the same thing when doing LTO on a program with debug info. |
This is expected because LTO is not updated to handle debug info yet. The FE, marks one compile unit as "main". Here "main" is not associated with "main" function. It identifies the main source file (i.e. main_input_filename in GCC FE sources). For example, -- a.c --
|
I'm still confused. Where did this notion of main compile unit come from? Is it defined in DWARF? Or is it just a GCC and LLVM convention? Currently gold can't eliminate duplicate globals, but a patch exists and should be added soon. Is that what you're referring to when you write about "eliminate duplicate compile units" or are compile units some other construct in the .o file? Sorry I'm not familiar with this stuff. I appreciate you taking the time to explain! |
I do not know what gold can do today or in future. There are two kind of compile units
The llvm IR uses the term compile_unit to refer an input file. Now, code generator produces compile units as specified by DWARF. It seems DWARF allows multiple DW_TAG_compile_unit (per function or per include header), so that it can be compressed later on. I am not a DWARF expert. Section 3.1.1 from DWARF says, " In a compilation employing DWARF space compression and duplicate elimination techniques (see Appendix E), multiple compilation units using the tags DW_TAG_compile_unit and/or DW_TAG_partial_unit And there is "E.4.3 Single-function-per-DWARF-compilation-unit".So... the llvm code generator is responsible to take care of incoming multiple LLVM IR level compile units and generate appropriate number of DWARF compile units. If there is a many to many (LLVM IR -> DWARF) mapping then none of the LLVM IR level compile units should be marked as MainCU. If there is a many to one (LLVM IR -> DWARF) mapping then only one LLVM IR level compile unit should be marked as MainCU. |
If I understand right, the concept of a main compile unit |
No, you're mistaken. It is not a work around for a weakness of the darwin linker. |
Yesterday I asked Cary, a gold developer, about this PR and he agrees that option #2 is the right approach for gold as well. He also said that option #1 might not work in general. If you have a case where you've inlined function C (from compile unit C) into A and B (in compile units A and B respectively), and the debug info for C is modified in two different ways as a result of simplification from inlining, you'd get two (COMDAT?) sections that aren't mergable. |
OK, I guess I just don't understand what the "main compile unit" |
I hoped to get some insight into this using gcc's -combine option, |
Hi Devang, As a workaround, is there any way to do this manually in the large .ll file that I've created? i.e. what exactly am I looking for in the llvm.dbg intrinsics that marks a compile unit as a "main" compile unit? I don't mind doing a little processing to go through and strip this from all-but-one unit. Given that this is possible, is there some "preferred" main compile unit (ie, should I just associate the main tag with whichever unit "main" comes from)? Luke |
Luke, @llvm.dbg.compile_unit = internal constant %llvm.dbg.compile_unit.type { You can use DICompileUnit() from DebugInfo.h to access this info. It is easy to add setMainCU() to set this bit. There is not any "preferred" main compile unit. So using the one that holds "int main()" functions is reasonable. |
*** Bug llvm/llvm-bugzilla-archive#3718 has been marked as a duplicate of this bug. *** |
Is this still failing after rev. 74449 ? |
Works for me. I tested on a way bigger program. |
Thanks! |
Works here too. Thank. Luke |
mentioned in issue llvm/llvm-bugzilla-archive#3718 |
Extended Description
When building these with LLVMgold:
$ cat test.c
extern int foo(void);
int main (void) {
return foo();
}
$ cat test2.c
int foo (void) {
return 0;
}
we get an assertion failure. Note that there's only one main.
$ llc linked.bc
llc: DwarfWriter.cpp:2786: void llvm::DwarfDebug::ConstructCompileUnits(): Assertion `!MainCU && "Multiple main compile units are found!"' failed.
[New Thread 0xf7c296c0 (LWP 23830)]
Program received signal SIGABRT, Aborted.
[Switching to Thread 0xf7c296c0 (LWP 23830)]
0xffffe425 in __kernel_vsyscall ()
(gdb) bt
#0 0xffffe425 in __kernel_vsyscall ()
#1 0xf7c56640 in raise () from /lib/i686/cmov/libc.so.6
#2 0xf7c58018 in abort () from /lib/i686/cmov/libc.so.6
#3 0xf7c4f5be in __assert_fail () from /lib/i686/cmov/libc.so.6
#4 0x08a9412a in llvm::DwarfDebug::ConstructCompileUnits (this=0x8f983a8)
at DwarfWriter.cpp:2786
#5 0x08a946e5 in llvm::DwarfDebug::SetDebugInfo (this=0x8f983a8,
mmi=0x8f94a88) at DwarfWriter.cpp:2893
#6 0x08a729a0 in llvm::DwarfWriter::BeginModule (this=0x8f8c1d0, M=0x8f73840,
MMI=0x8f94a88, OS=@0x8f786b8, A=0x8f965b0, T=0x8f7e028)
at DwarfWriter.cpp:4233
#7 0x0872868b in llvm::X86ATTAsmPrinter::doInitialization (this=0x8f965b0,
M=@0x8f73840) at X86ATTAsmPrinter.cpp:742
#8 0x08cdbe0c in llvm::FPPassManager::doInitialization (this=0x8f76f68,
M=@0x8f73840) at PassManager.cpp:1356
#9 0x08cdc043 in llvm::FunctionPassManagerImpl::doInitialization (
this=0x8f74138, M=@0x8f73840) at PassManager.cpp:1250
#10 0x08cd2d54 in llvm::FunctionPassManager::doInitialization (this=0xffe2c5b8)
at PassManager.cpp:1233
#11 0x08414c01 in main (argc=2, argv=0xffe2c6d4) at llc.cpp:311
The intermediate result is 'linked.bc' attached. I've decided not to bugpoint it in case that discards useful information. (Is the .bc bad? Or is it a bug in dwarf emission?)
The text was updated successfully, but these errors were encountered: