This is an archive of the discontinued LLVM Phabricator instance.

[clang][clangd] Don't crash/assert on -gsplit-dwarf=single without output
ClosedPublic

Authored by DmitryPolukhin on Jul 6 2023, 5:53 AM.

Details

Summary

The crash happens in clang::driver::tools::SplitDebugName when Output is
InputInfo::Nothing. It doesn't happen with standalone clang driver because
output is created in Driver::BuildJobsForActionNoCache.

Example backtrace:

* thread #1, name = 'clangd', stop reason = hit program assert
  * frame #0: 0x00007ffff5c4eacf libc.so.6`raise + 271
    frame #1: 0x00007ffff5c21ea5 libc.so.6`abort + 295
    frame #2: 0x00007ffff5c21d79 libc.so.6`__assert_fail_base.cold.0 + 15
    frame #3: 0x00007ffff5c47426 libc.so.6`__assert_fail + 70
    frame #4: 0x000055555dc0923c clangd`clang::driver::InputInfo::getFilename(this=0x00007fffffff9398) const at InputInfo.h:84:5
    frame #5: 0x000055555dcd0d8d clangd`clang::driver::tools::SplitDebugName(JA=0x000055555f6c6a50, Args=0x000055555f6d0b80, Input=0x00007fffffff9678, Output=0x00007fffffff9398) at CommonArgs.cpp:1275:40
    frame #6: 0x000055555dc955a5 clangd`clang::driver::tools::Clang::ConstructJob(this=0x000055555f6c69d0, C=0x000055555f6c64a0, JA=0x000055555f6c6a50, Output=0x00007fffffff9398, Inputs=0x00007fffffff9668, Args=0x000055555f6d0b80, LinkingOutput=0x0000000000000000) const at Clang.cpp:5690:33
    frame #7: 0x000055555dbf6b54 clangd`clang::driver::Driver::BuildJobsForActionNoCache(this=0x00007fffffffb5e0, C=0x000055555f6c64a0, A=0x000055555f6c6a50, TC=0x000055555f6c4be0, BoundArch=(Data = 0x0000000000000000, Length = 0), AtTopLevel=true, MultipleArchs=false, LinkingOutput=0x0000000000000000, CachedResults=size=1, TargetDeviceOffloadKind=OFK_None) const at Driver.cpp:5618:10
    frame #8: 0x000055555dbf4ef0 clangd`clang::driver::Driver::BuildJobsForAction(this=0x00007fffffffb5e0, C=0x000055555f6c64a0, A=0x000055555f6c6a50, TC=0x000055555f6c4be0, BoundArch=(Data = 0x0000000000000000, Length = 0), AtTopLevel=true, MultipleArchs=false, LinkingOutput=0x0000000000000000, CachedResults=size=1, TargetDeviceOffloadKind=OFK_None) const at Driver.cpp:5306:26
    frame #9: 0x000055555dbeb590 clangd`clang::driver::Driver::BuildJobs(this=0x00007fffffffb5e0, C=0x000055555f6c64a0) const at Driver.cpp:4844:5
    frame #10: 0x000055555dbe6b0f clangd`clang::driver::Driver::BuildCompilation(this=0x00007fffffffb5e0, ArgList=ArrayRef<const char *> @ 0x00007fffffffb268) at Driver.cpp:1496:3
    frame #11: 0x000055555b0cc0d9 clangd`clang::createInvocation(ArgList=ArrayRef<const char *> @ 0x00007fffffffbb38, Opts=CreateInvocationOptions @ 0x00007fffffffbb90) at CreateInvocationFromCommandLine.cpp:53:52
    frame #12: 0x000055555b378e7b clangd`clang::clangd::buildCompilerInvocation(Inputs=0x00007fffffffca58, D=0x00007fffffffc158, CC1Args=size=0) at Compiler.cpp:116:44
    frame #13: 0x000055555895a6c8 clangd`clang::clangd::(anonymous namespace)::Checker::buildInvocation(this=0x00007fffffffc760, TFS=0x00007fffffffe570, Contents= Has Value=false ) at Check.cpp:212:9
    frame #14: 0x0000555558959cec clangd`clang::clangd::check(File=(Data = "build/test.cpp", Length = 64), TFS=0x00007fffffffe570, Opts=0x00007fffffffe600) at Check.cpp:486:34
    frame #15: 0x000055555892164a clangd`main(argc=4, argv=0x00007fffffffecd8) at ClangdMain.cpp:993:12
    frame #16: 0x00007ffff5c3ad85 libc.so.6`__libc_start_main + 229
    frame #17: 0x00005555585bbe9e clangd`_start + 46

Test Plan: ninja ClangDriverTests && tools/clang/unittests/Driver/ClangDriverTests

Diff Detail

Event Timeline

DmitryPolukhin created this revision.Jul 6 2023, 5:53 AM
Herald added a project: Restricted Project. · View Herald TranscriptJul 6 2023, 5:53 AM
DmitryPolukhin published this revision for review.Jul 6 2023, 5:56 AM

Rebase and uun clang-format

yaxunl added inline comments.Jul 6 2023, 3:02 PM
clang/lib/Driver/ToolChains/CommonArgs.cpp
1277

I am wondering in what situation the Output here is not a file name. Is it possible to have a lit test for this?

DmitryPolukhin added inline comments.Jul 7 2023, 4:56 AM
clang/lib/Driver/ToolChains/CommonArgs.cpp
1277

It is possible to create lit test but still will be clangd lit test. I was not able to find case when it happens with clang driver itself. Nothing Output appears from https://github.com/llvm/llvm-project/blob/main/clang/lib/Driver/Driver.cpp#L5580 in case of clangd. In case of clang driver next else is taken and it produces file based Output. As far as I understand clangd prefers unittests over lit tests. But I can convert it to lit test if you think it is better.

MaskRay requested changes to this revision.Jul 9 2023, 11:48 AM

Thanks for the patch! But I share the concern that the test is added to a wrong layer (https://maskray.me/blog/2021-08-08-toolchain-testing#the-test-checks-at-the-wrong-layer).

We can add a clang::createInvocation test to clang/unittests/Driver/ToolChainTest.cpp.

This revision now requires changes to proceed.Jul 9 2023, 11:48 AM

Moved test to clang/unittests/Driver/ToolChainTest.cpp

Thanks for the patch! But I share the concern that the test is added to a wrong layer (https://maskray.me/blog/2021-08-08-toolchain-testing#the-test-checks-at-the-wrong-layer).

We can add a clang::createInvocation test to clang/unittests/Driver/ToolChainTest.cpp.

Thank you for the suggestion. Done, please take another look.

DmitryPolukhin edited the summary of this revision. (Show Details)Jul 11 2023, 8:48 AM
MaskRay accepted this revision.Jul 11 2023, 10:35 AM

https://maskray.me/blog/2021-08-08-toolchain-testing#the-test-checks-at-the-wrong-layer I think there is a minor "The test checks too little" issue as we can utilize the test to check a few more properties, but I am fine with this.
And I may try improving the test at spare time..

This revision is now accepted and ready to land.Jul 11 2023, 10:35 AM
MaskRay added inline comments.Jul 11 2023, 10:36 AM
clang/unittests/Driver/ToolChainTest.cpp
371

Without a concrete target triple, the default is used. If the default target triple uses an object file format not supporting -gsplit-dwarf, this will fail.

Added -target arm-linux-gnueabi

clang/unittests/Driver/ToolChainTest.cpp
371

Oh, could you please advise how to select right target triple for the test or limit it to the case when triple I specify here is supported? I had issue in the past with triples and it was tricky to select something that makes all llvm bots happy. I added -target arm-linux-gnueabi and test seems to be working if only x86 arch is enabled.

MaskRay accepted this revision.Jul 11 2023, 1:00 PM
MaskRay added inline comments.
clang/unittests/Driver/ToolChainTest.cpp
371

-target has been deprecated since Clang 3.4. Use --target=arm-linux-gnueabi.

If you just run the driver, you don't need a target in LLVM_TARGETS_TO_BUILD.
If you do code generation, LLVM_TARGETS_TO_BUILD is needed.
This is tricky, you likely need two build directories to check this...

% /tmp/out/custom1/bin/clang --target=aarch64 -c a.cc
error: unable to create target: 'No available targets are compatible with triple "aarch64"'
1 error generated.

Use --target=arm-linux-gnueabi

Run clang-format

DmitryPolukhin added inline comments.Jul 11 2023, 2:01 PM
clang/unittests/Driver/ToolChainTest.cpp
371

Yes, my driver test works fine regardless LLVM_TARGETS_TO_BUILD, also tested with -###
Will wait for build bots completion just in case and push tomorrow. Thank you for review and the detailed explanation.

This revision was landed with ongoing or failed builds.Jul 12 2023, 1:00 AM
This revision was automatically updated to reflect the committed changes.