llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
28.79k stars 11.9k forks source link

Clang crashes when built with virtual-function-elimination #56257

Open EmmaJaneBonestell opened 2 years ago

EmmaJaneBonestell commented 2 years ago

System: Ubuntu 22.04, x86_64, libstdc++12 Trunk and previous versions seem to be affected.

Attached is a ~1000 line backtrace with variables, etc, from lldb.

When LLVM/Clang are built with -fvirtual-function-elimination, and any optimization above -O0, most of the LLVM binaries all SEGV almost immediately (e.g. lli, llc, clang, opt); --help* or no command are the only commands that will not cause a crash. 

I built twice (both with debug/assertions, ubsan, asan) once with -O0 and another with -Og.

Bugpoint may have found a problem in ipsccp, but after running for 48+ hours, it could not reduce it was not making progress towards a reasonable test case.

At -O0, llc and opt can process and output files seemingly okay and the sanitizers report nothing. Clang works likewise, but only since I used -fsanitize=recover.

Edit: Sometimes, llc and lli give this assertion:

decltype(auto) llvm::cast(From *) [To = llvm::MDNode, From = llvm::Metadata]: Assertion `isa<To>(Val) && "cast<Ty>() argument of incompatible type!"' failed.

These sanitizer errors may be unrelated to the Clang segmentation faults detailed further below, as Clang is the only binary emitting such errors, and only at -O0. The sanitizers emit the following errors:

/opt/venv/llvm-project/clang/include/clang/AST/Redeclarable.h:200:15: runtime error: downcast of address 0x621000017d08 which does not point to an object of type 'clang::TranslationUnitDecl'
0x621000017d08: note: object is of type 'clang::Decl'
00 00 00 00  10 90 78 08 b6 55 00 00  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  00 00 00 00
              ^~~~~~~~~~~~~~~~~~~~~~~
              vptr for 'clang::Decl'
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior /opt/venv/llvm-project/clang/include/clang/AST/Redeclarable.h:200:15 in 
/opt/venv/llvm-project/clang/include/clang/AST/Redeclarable.h:200:15: runtime error: downcast of address 0x621000018588 which does not point to an object of type 'clang::TypedefNameDecl'
0x621000018588: note: object is of type 'clang::TypeDecl'
be be be be  f0 9f 6d 08 b6 55 00 00  00 00 00 00 00 00 00 00  30 7d 01 00 10 62 00 00  00 00 00 00
              ^~~~~~~~~~~~~~~~~~~~~~~
              vptr for 'clang::TypeDecl'
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior /opt/venv/llvm-project/clang/include/clang/AST/Redeclarable.h:200:15 in 
/opt/venv/llvm-project/clang/include/clang/AST/Redeclarable.h:200:15: runtime error: downcast of address 0x621000018660 which does not point to an object of type 'clang::TagDecl'
0x621000018660: note: object is of type 'clang::TypeDecl'
be be be be  f0 9f 6d 08 b6 55 00 00  00 00 00 00 00 00 00 00  30 7d 01 00 10 62 00 00  00 00 00 00
              ^~~~~~~~~~~~~~~~~~~~~~~
              vptr for 'clang::TypeDecl'
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior /opt/venv/llvm-project/clang/include/clang/AST/Redeclarable.h:200:15 in 
/opt/venv/llvm-project/clang/include/clang/AST/Redeclarable.h:200:15: runtime error: downcast of address 0x6210000692d8 which does not point to an object of type 'clang::NamespaceDecl'
0x6210000692d8: note: object is of type 'clang::NamedDecl'
be be be be  d0 73 6d 08 b6 55 00 00  00 00 00 00 00 00 00 00  30 7d 01 00 10 62 00 00  cf 65 00 00
              ^~~~~~~~~~~~~~~~~~~~~~~
              vptr for 'clang::NamedDecl'
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior /opt/venv/llvm-project/clang/include/clang/AST/Redeclarable.h:200:15 in 
/opt/venv/llvm-project/clang/include/clang/AST/Redeclarable.h:200:15: runtime error: downcast of address 0x621000069700 which does not point to an object of type 'clang::FunctionDecl'
0x621000069700: note: object is of type 'clang::DeclaratorDecl'
be be be be  90 a6 6d 08 b6 55 00 00  00 00 00 00 00 00 00 00  d8 95 06 00 10 62 00 00  76 67 00 00
              ^~~~~~~~~~~~~~~~~~~~~~~
              vptr for 'clang::DeclaratorDecl'
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior /opt/venv/llvm-project/clang/include/clang/AST/Redeclarable.h:200:15 in 
/opt/venv/llvm-project/clang/include/clang/AST/Redeclarable.h:200:15: runtime error: downcast of address 0x621000097a98 which does not point to an object of type 'clang::RedeclarableTemplateDecl'
0x621000097a98: note: object is of type 'clang::TemplateDecl'
be be be be  90 4f 6d 08 b6 55 00 00  00 00 00 00 00 00 00 00  70 78 09 00 10 62 00 00  1a e3 02 00
              ^~~~~~~~~~~~~~~~~~~~~~~
              vptr for 'clang::TemplateDecl'
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior /opt/venv/llvm-project/clang/include/clang/AST/Redeclarable.h:200:15 in 
/opt/venv/llvm-project/clang/include/clang/AST/Redeclarable.h:200:15: runtime error: downcast of address 0x6210000d7288 which does not point to an object of type 'clang::VarDecl'
0x6210000d7288: note: object is of type 'clang::DeclaratorDecl'
be be be be  90 a6 6d 08 b6 55 00 00  00 00 00 00 00 00 00 00  30 7d 01 00 10 62 00 00  28 26 03 00
              ^~~~~~~~~~~~~~~~~~~~~~~
              vptr for 'clang::DeclaratorDecl'
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior /opt/venv/llvm-project/clang/include/clang/AST/Redeclarable.h:200:15 in 
/opt/venv/llvm-project/clang/include/clang/AST/Redeclarable.h:200:15: runtime error: downcast of address 0x62100002e9c0 which does not point to an object of type 'clang::UsingShadowDecl'
0x62100002e9c0: note: object is of type 'clang::NamedDecl'
be be be be  d0 73 6d 08 b6 55 00 00  00 00 00 00 00 00 00 00  f0 e8 02 00 10 62 00 00  05 0a 03 00
              ^~~~~~~~~~~~~~~~~~~~~~~
              vptr for 'clang::NamedDecl'
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior /opt/venv/llvm-project/clang/include/clang/AST/Redeclarable.h:200:15 in 

=================================================================
==89046==ERROR: LeakSanitizer: detected memory leaks 

Direct leak of 416 byte(s) in 16 object(s) allocated from:
    #0 0x55b5da44d216 in realloc (/opt/venv/llvm-project/assert/bin/clang-15+0x3a8cf216) (BuildId: eaccea4ce95303fc)
    #1 0x7f905981894a  (/lib/x86_64-linux-gnu/libstdc++.so.6+0xb094a) (BuildId: 725ef5da52ee6d881f9024d8238a989903932637) 

Objects leaked above:
0x602000000830 (16 bytes)
0x602000000850 (16 bytes)
0x6020000009b0 (16 bytes)
0x6020000009d0 (16 bytes)
0x6020000009f0 (16 bytes)
0x602000000a10 (16 bytes)
0x60300000b320 (32 bytes)
0x60300000b350 (32 bytes)
0x60300000b3b0 (32 bytes)
0x60300000b3e0 (32 bytes)
0x60300000d150 (32 bytes)
0x60300000d180 (32 bytes)
0x603000010240 (32 bytes)
0x603000010270 (32 bytes)
0x603000010360 (32 bytes)
0x603000010390 (32 bytes)

At -Og, Clang emits the following stack dump:

0.      Program arguments: /opt/venv/llvm-project/assert2/bin/clang-15 -cc1 -triple x86_64-unknown-linux-gnu -emit-obj -mrelax-all --mrelax-relocations -disable-free -clear-ast-before-backend -main-file-name math_example.cpp -mrelocation-model pic -pic-level 2 -pic-is-pie -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -mllvm -treat-scalable-fixed-error-as-warning -debugger-tuning=gdb -fcoverage-compilation-dir=/opt/venv/llvm-project/assert -resource-dir /opt/venv/llvm-project/assert2/lib/clang/15.0.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/12/../../../../include/x86_64-linux-gnu/c++/12 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/backward -internal-isystem /opt/venv/llvm-project/assert2/lib/clang/15.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/12/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fdeprecated-macro -fdebug-compilation-dir=/opt/venv/llvm-project/assert -ferror-limit 19 -fgnuc-version=4.2.1 -fcxx-exceptions -fexceptions -fcolor-diagnostics -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/math_example-2fd194.o -x c++ /home/csk/math_example.cpp
#0 0x000055c6e0bd52db backtrace (/opt/venv/llvm-project/assert2/bin/clang-15+0x2477d2db)
#1 0x000055c6e64fe101 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) /opt/venv/llvm-project/llvm/lib/Support/Unix/Signals.inc:569:13
#2 0x000055c6e64fe8eb PrintStackTraceSignalHandler(void*) /opt/venv/llvm-project/llvm/lib/Support/Unix/Signals.inc:636:1
#3 0x000055c6e64fa775 llvm::sys::RunSignalHandlers() /opt/venv/llvm-project/llvm/lib/Support/Signals.cpp:97:27
#4 0x000055c6e64fcd75 SignalHandler(int) /opt/venv/llvm-project/llvm/lib/Support/Unix/Signals.inc:0:3
#5 0x00007f7cb9d27520 (/lib/x86_64-linux-gnu/libc.so.6+0x42520)
AddressSanitizer:DEADLYSIGNAL
=================================================================
==88947==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x000000000000 bp 0x7fff012dfaf0 sp 0x7fff012dfab8 T0)
==88947==Hint: pc points to the zero page.
==88947==The signal is caused by a READ memory access.
==88947==Hint: address points to the zero page.
    #0 0x0  (<unknown module>)
    #1 0x55c6e6215a07 in (anonymous namespace)::CommandLineParser::ResetAllOptionOccurrences() /opt/venv/llvm-project/llvm/lib/Support/CommandLine.cpp:1411:17
    #2 0x55c6e6216172 in llvm::cl::ResetAllOptionOccurrences() /opt/venv/llvm-project/llvm/lib/Support/CommandLine.cpp:2732:17
    #3 0x55c6e0c60bd3 in ExecuteCC1Tool(llvm::SmallVectorImpl<char const*>&) /opt/venv/llvm-project/clang/tools/driver/driver.cpp:308:3
    #4 0x55c6e0c5db51 in clang_main(int, char**) /opt/venv/llvm-project/clang/tools/driver/driver.cpp:388:12
    #5 0x55c6e0e341c0 in main /opt/venv/llvm-project/assert2/tools/clang/tools/driver/clang-driver.cpp:11:42
    #6 0x7f7cb9d0ed8f in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16 

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV (<unknown module>) 
==88947==ABORTING

Running under lldb gives the following backtrace:

error: memory read failed for 0x0
(lldb) bt all
* thread #1, name = 'clang-15', stop reason = signal SIGSEGV: invalid address (fault address: 0x0)
  * frame #0: 0x0000000000000000
    frame #1: 0x000055557f2ef770 clang-15`llvm::cl::Option::reset(this=0x000055559c742ac0) at CommandLine.cpp:475:3 [opt]
    frame #2: 0x000055557f311a08 clang-15`(anonymous namespace)::CommandLineParser::ResetAllOptionOccurrences(this=<unavailable>) at CommandLine.cpp:1411:17 [opt]
    frame #3: 0x000055557f312173 clang-15`llvm::cl::ResetAllOptionOccurrences() at CommandLine.cpp:2732:17 [opt]
    frame #4: 0x0000555579d5cbd4 clang-15`ExecuteCC1Tool(ArgV=<unavailable>) at driver.cpp:308:3 [opt]
    frame #5: 0x0000555581a83518 clang-15`clang::driver::CC1Command::Execute(this=0x00007ffff5f3bd20) const::$_1::operator()() const at Job.cpp:407:34 [opt]
    frame #6: 0x0000555581a83443 clang-15`void llvm::function_ref<void ()>::callback_fn<clang::driver::CC1Command::Execute(callable=140737319779616) const::$_1>(long) at STLFunctionalExtras.h:45:12 [opt]
    frame #7: 0x000055557bb02104 clang-15`llvm::function_ref<void ()>::operator(this=<unavailable>)() const at STLFunctionalExtras.h:68:12 [opt]
    frame #8: 0x000055557f3257a7 clang-15`llvm::CrashRecoveryContext::RunSafely(this=<unavailable>, Fn=function_ref<void ()> @ 0x00007fffffffd500)>) at CrashRecoveryContext.cpp:425:3 [opt]
    frame #9: 0x0000555581a82f90 clang-15`clang::driver::CC1Command::Execute(this=<unavailable>, Redirects=<unavailable>, ErrMsg=<unavailable>, ExecutionFailed=<unavailable>) const at Job.cpp:407:12 [opt]
    frame #10: 0x0000555581992c18 clang-15`clang::driver::Compilation::ExecuteCommand(this=0x0000616000001280, C=<unavailable>, FailingCommand=<unavailable>, LogOnly=<unavailable>) const at Compilation.cpp:200:15 [opt]
    frame #11: 0x000055558199347f clang-15`clang::driver::Compilation::ExecuteJobs(this=<unavailable>, Jobs=<unavailable>, FailingCommands=<unavailable>, LogOnly=<unavailable>) const at Compilation.cpp:254:19 [opt]
    frame #12: 0x0000555581a73ea8 clang-15`clang::driver::Driver::ExecuteCompilation(this=<unavailable>, C=0x0000616000001280, FailingCommands=<unavailable>) at Driver.cpp:1735:5 [opt]
    frame #13: 0x0000555579d5b31c clang-15`clang_main(Argc=<unavailable>, Argv=<unavailable>) at driver.cpp:513:21 [opt]
    frame #14: 0x0000555579f301c1 clang-15`main(argc=<unavailable>, argv=<unavailable>) at clang-driver.cpp:11:42 [opt]
    frame #15: 0x00007ffff7a06d90 libc.so.6`__libc_start_call_main(main=(clang-15`main at clang-driver.cpp:11), argc=3, argv=0x00007fffffffdb18) at libc_start_call_main.h:58:16
    frame #16: 0x00007ffff7a06e40 libc.so.6`__libc_start_main_impl(main=(clang-15`main at clang-driver.cpp:11), argc=3, argv=0x00007fffffffdb18, init=<unavailable>, fini=<unavailable>, rtld_fini=<unavailable>, stack_end=0x00007fffffffdb08) at libc-start.c:392:3
    frame #17: 0x0000555579c93a25 clang-15`_start + 37

And again, if if may be helpful, a verbose backtrace of the above is attached. lldb_verbose_backtrace.txt

EmmaJaneBonestell commented 2 years ago

The ubsan failures are not present when built with libc++, instrumented or not, but the stack traces elsewise provided are still relevant.

Edit: The reason I cannot readily reduce with bugpoint is because llc/lli/opt do not support llvm.type.checked.load (and ungracefully crash when given it). I'm trying to use a custom command now, so we'll see.

EmmaJaneBonestell commented 2 years ago

Documents that --wholeprogramdevirt-skip takes comma separated fields and that it accepts glob patterns (not regex nor only complete matches.)

I don't have enough experience with bugpoint, nor are there really any examples showing any more advanced use of it when using llc/lli are not an option due to llvm.type.chevked.load So, if anyone wishes to attempt to reduce this test-case of llc bitcode into something meaningful, it's here;

https://drive.google.com/file/d/1kTrd0pZSx_Hql5DBY21Q-OcVgixeOHGy/view?usp=sharing

or, you can build from source yourself. Any configuration including "-fvirtual-function-elimination" and "-O" >0 will reproduce, but you will probably need the patch, here, for missing headers:

https://github.com/llvm/llvm-project/issues/55239

EmmaJaneBonestell commented 2 years ago

(For llc) Still not sure exactly where the cause of the error is, but single stepping through a debugger shows that as it goes through all the defaults/checking command line changes to them, when it reaches ImplicitItMode

llvm::cl::generic_parser_base::findOption (this=0x555559a313f0 <(anonymous namespace)::ImplicitItMode+160>, Name=...) at /opt/venv/llvm-project/llvm/lib/Support/CommandLine.cpp:2000

Specifically this instruction,

0x555557141f34 <llvm::cl::generic_parser_base::findOption(llvm::StringRef)+20>    call   qword ptr [rax + 0x10]

Most of the register values are garbage through the whole routine. Instead of having a call to a parser, e.g.

*RAX  0x5555599e0a30 —▸ 0x555556b6b040 (llvm::cl::parser<llvm::EmitDwarfUnwindType>::~parser()) ◂— push   rax

We have

*RAX  0x5555599df890 ◂— 0x0
...
*RIP  0x555557141f34 (llvm::cl::generic_parser_base::findOption(llvm::StringRef)+20) ◂— call   qword ptr [rax + 0x10]

So it tries to read from 0x0.

Enabling optimizations seems to completely remove

llvm::cl::parser<(anonymous namespace)::ImplicitItModeTy>::~parser() 

, so I'm not sure what it (the compiler) has done, or why the other *::~parser functions were kept.