Skip to content

[DebugInfo] Allow DISubrange/DIGenericSubrange without count/upperBound. #96474

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

Merged
merged 7 commits into from
Jul 9, 2024

Conversation

abidh
Copy link
Contributor

@abidh abidh commented Jun 24, 2024

Due to the current order of metadata in DISubprgram, Type is processed before Unit by the Verifier. This can cause a race and
use of garbage data. Consider the following code:

int test(int a[][5])
{
    return a[0][2];
}

when compiled with clang, the control reaches Verifier::visitDISubrange first with CurrentSourceLang still equal to dwarf::DW_LANG_lo_user (32768). The Verifier::visitDICompileUnit which sets the value of CurrentSourceLang is reached later. So Verifier::visitDISubrange ends up using a wrong value of CurrentSourceLang.

This behavior does not effect C like language much but is a problem for Fortran. There is special processing in Verifier::visitDISubrange when CurrentSourceLang is Fortran. With this problem, that special handling is missed and verifier fails for any code that has Fortran's assumed size array in a global subroutine.

To fix this, I have swapped the position of Type and Unit. They were already adjacent so it does not require changing position of anything else.

@llvmbot
Copy link
Member

llvmbot commented Jun 24, 2024

@llvm/pr-subscribers-debuginfo

@llvm/pr-subscribers-llvm-ir

Author: Abid Qadeer (abidh)

Changes

Due to the current order of metadata in DISubprgram, Type is processed before Unit by the Verifier. This can cause a race and
use of garbage data. Consider the following code:

int test(int a[][5])
{
    return a[0][2];
}

when compiled with clang, the control reaches Verifier::visitDISubrange first with CurrentSourceLang still equal to dwarf::DW_LANG_lo_user (32768). The Verifier::visitDICompileUnit which sets the value of CurrentSourceLang is reached later. So Verifier::visitDISubrange ends up using a wrong value of CurrentSourceLang.

This behavior does not effect C like language much but is a problem for Fortran. There is special processing in Verifier::visitDISubrange when CurrentSourceLang is Fortran. With this problem, that special handling is missed and verifier fails for any code that has Fortran's assumed size array in a global subroutine.

To fix this, I have swapped the position of Type and Unit. They were already adjacent so it does not require changing position of anything else.


Full diff: https://github.com/llvm/llvm-project/pull/96474.diff

2 Files Affected:

  • (modified) llvm/include/llvm/IR/DebugInfoMetadata.h (+8-7)
  • (modified) llvm/lib/IR/DebugInfoMetadata.cpp (+3-4)
diff --git a/llvm/include/llvm/IR/DebugInfoMetadata.h b/llvm/include/llvm/IR/DebugInfoMetadata.h
index 524945862e8d4..a1d2f4c1791cf 100644
--- a/llvm/include/llvm/IR/DebugInfoMetadata.h
+++ b/llvm/include/llvm/IR/DebugInfoMetadata.h
@@ -1865,6 +1865,11 @@ class DISubprogram : public DILocalScope {
   /// Only used by clients of CloneFunction, and only right after the cloning.
   void replaceLinkageName(MDString *LN) { replaceOperandWith(3, LN); }
 
+  DICompileUnit *getUnit() const {
+    return cast_or_null<DICompileUnit>(getRawUnit());
+  }
+  void replaceUnit(DICompileUnit *CU) { replaceOperandWith(4, CU); }
+
   DISubroutineType *getType() const {
     return cast_or_null<DISubroutineType>(getRawType());
   }
@@ -1873,13 +1878,9 @@ class DISubprogram : public DILocalScope {
   }
   void replaceType(DISubroutineType *Ty) {
     assert(isDistinct() && "Only distinct nodes can mutate");
-    replaceOperandWith(4, Ty);
+    replaceOperandWith(5, Ty);
   }
 
-  DICompileUnit *getUnit() const {
-    return cast_or_null<DICompileUnit>(getRawUnit());
-  }
-  void replaceUnit(DICompileUnit *CU) { replaceOperandWith(5, CU); }
   DITemplateParameterArray getTemplateParams() const {
     return cast_or_null<MDTuple>(getRawTemplateParams());
   }
@@ -1903,8 +1904,8 @@ class DISubprogram : public DILocalScope {
   Metadata *getRawScope() const { return getOperand(1); }
   MDString *getRawName() const { return getOperandAs<MDString>(2); }
   MDString *getRawLinkageName() const { return getOperandAs<MDString>(3); }
-  Metadata *getRawType() const { return getOperand(4); }
-  Metadata *getRawUnit() const { return getOperand(5); }
+  Metadata *getRawUnit() const { return getOperand(4); }
+  Metadata *getRawType() const { return getOperand(5); }
   Metadata *getRawDeclaration() const { return getOperand(6); }
   Metadata *getRawRetainedNodes() const { return getOperand(7); }
   Metadata *getRawContainingType() const {
diff --git a/llvm/lib/IR/DebugInfoMetadata.cpp b/llvm/lib/IR/DebugInfoMetadata.cpp
index 161a30dfb3828..438ac7b96f345 100644
--- a/llvm/lib/IR/DebugInfoMetadata.cpp
+++ b/llvm/lib/IR/DebugInfoMetadata.cpp
@@ -1138,10 +1138,9 @@ DISubprogram *DISubprogram::getImpl(
                          RetainedNodes, ThrownTypes, Annotations,
                          TargetFuncName));
   SmallVector<Metadata *, 13> Ops = {
-      File,           Scope,          Name,        LinkageName,
-      Type,           Unit,           Declaration, RetainedNodes,
-      ContainingType, TemplateParams, ThrownTypes, Annotations,
-      TargetFuncName};
+      File,        Scope,       Name,          LinkageName,    Unit,
+      Type,        Declaration, RetainedNodes, ContainingType, TemplateParams,
+      ThrownTypes, Annotations, TargetFuncName};
   if (!TargetFuncName) {
     Ops.pop_back();
     if (!Annotations) {

@jmorse
Copy link
Member

jmorse commented Jun 24, 2024

As far as I understand this patch, it's swapping which field of a DISubprogram the data is stored in, and all the accessors are updated, so this patch should be transparent to any code using the accessors.

Thus, surely the problem is caused by code that directly accesses the fields of DISubprogram and is exposed to their ordering -- shouldn't such code instead examine fields in a logical manner rather than the order of storage?

@abidh
Copy link
Contributor Author

abidh commented Jun 24, 2024

As far as I understand this patch, it's swapping which field of a DISubprogram the data is stored in, and all the accessors are updated, so this patch should be transparent to any code using the accessors.

Thus, surely the problem is caused by code that directly accesses the fields of DISubprogram and is exposed to their ordering -- shouldn't such code instead examine fields in a logical manner rather than the order of storage?

The caller here is Verifier::visitMDNode. It does not directly access the fields of DISubprogram. That code does not even know it is processing DISubprogram. It is processing the fields of an MDNode in order they are returned by the MDNode.operands().

@jmorse
Copy link
Member

jmorse commented Jun 24, 2024

Most curious; my understanding of Verifier::visitMDNode [0] is that it should be calling out into visitDISubprogram by switching on the metadata ID -- do you have a reproducer for the behaviour you're observing? It sounds like something is broken, but if it's fixed by re-ordering fields then there's something even bigger that's broken lurking under the surface.

[0]

visit##CLASS(cast<CLASS>(MD)); \

@abidh
Copy link
Contributor Author

abidh commented Jun 24, 2024

Most curious; my understanding of Verifier::visitMDNode [0] is that it should be calling out into visitDISubprogram by switching on the metadata ID -- do you have a reproducer for the behaviour you're observing? It sounds like something is broken, but if it's fixed by re-ordering fields then there's something even bigger that's broken lurking under the surface.

[0]

visit##CLASS(cast<CLASS>(MD)); \

Problem comes from the loop a few lines below [0]. It calls the visitMDNode on operands in order. You can reproduce it using following code.

int test(int a[][5])
{
    return a[0][2];
}

You will see that control reaches Verifier::visitDISubrange first with CurrentSourceLang still equal to dwarf::DW_LANG_lo_user (32768). The Verifier::visitDICompileUnit which sets the value of CurrentSourceLang will be called later.

[0]

for (const Metadata *Op : MD.operands()) {

@jmorse
Copy link
Member

jmorse commented Jun 26, 2024

Aaaaahhh, I get it now, thanks for bearing with me -- I see that the Verifier class has a CurrentSourceLang field that gets populated while exploring the metadata tree, and visiting the Unit before the Type in a subprogram ensures that CurrentSourceLang gets set before further exploration occurs.

I still feel flipping the order of fields is fixing the symptom rather than the cause -- stepping back a bit, by having state in the Verifier object we're implicitly requiring metadata to be explored in a particular order. This patch will fix one incorrect order, but there might be other incorrect orders or it might expose more.

Instead: how about setting CurrentSourceLang in visitDISubprogram instead, skipping that behaviour if the Unit appears to be invalid. Whenever we visit a subprogram, we're about to visit a collection of variables, types and other entities that may depend on the source language, and verifying a Function independently is a fairly common use-case IMHO. This also avoids relying on an implementation detail of the DISubprogram class layout.

I get the feeling that the state in Verifier will cause trouble in LTO contexts where there are multiple compile units in a Module, but I'm not familiar enough with metadata in LTO contexts to give an opinion.

@abidh
Copy link
Contributor Author

abidh commented Jun 26, 2024

Aaaaahhh, I get it now, thanks for bearing with me -- I see that the Verifier class has a CurrentSourceLang field that gets populated while exploring the metadata tree, and visiting the Unit before the Type in a subprogram ensures that CurrentSourceLang gets set before further exploration occurs.

I still feel flipping the order of fields is fixing the symptom rather than the cause -- stepping back a bit, by having state in the Verifier object we're implicitly requiring metadata to be explored in a particular order. This patch will fix one incorrect order, but there might be other incorrect orders or it might expose more.

Instead: how about setting CurrentSourceLang in visitDISubprogram instead, skipping that behaviour if the Unit appears to be invalid. Whenever we visit a subprogram, we're about to visit a collection of variables, types and other entities that may depend on the source language, and verifying a Function independently is a fairly common use-case IMHO. This also avoids relying on an implementation detail of the DISubprogram class layout.

I get the feeling that the state in Verifier will cause trouble in LTO contexts where there are multiple compile units in a Module, but I'm not familiar enough with metadata in LTO contexts to give an opinion.

Thanks for taking a look. Setting CurrentSourceLang in visitDISubprogram is a good suggestion. I have changed the PR to use it. If it looks ok then I will update the heading and description of the PR accordingly.

@jmorse
Copy link
Member

jmorse commented Jun 26, 2024

In principle this LGTM, perhaps other reviewers could chime in though. In an ideal world we'd have a test that ensures this behaviour continues to be present, is there an LLVM-IR input from flang that triggers the previous error, and that we can have in the LLVM DebugInfo test suite?

@abidh
Copy link
Contributor Author

abidh commented Jun 26, 2024

In principle this LGTM, perhaps other reviewers could chime in though. In an ideal world we'd have a test that ensures this behaviour continues to be present, is there an LLVM-IR input from flang that triggers the previous error, and that we can have in the LLVM DebugInfo test suite?

I have added a test.

@dwblaikie
Copy link
Collaborator

In principle this LGTM, perhaps other reviewers could chime in though.

Yeah, bit janky - I don't totally object.

But alternatively: Could we remove the use/need for CurrentSourceLang? Guess it was added for fortran support, but perhaps we should've gone the toher way and weakened the checks? Just don't check for count/upperbound at all? (in visitDISubrange)

Presumably LLVM can produce whatever DWARF we do for Fortran given such info, and do that for C++ too - even if it's incorrect for C++, maybe we move that to just be up to the IR generator to get that right?

@abidh
Copy link
Contributor Author

abidh commented Jun 27, 2024

In principle this LGTM, perhaps other reviewers could chime in though.

Yeah, bit janky - I don't totally object.

But alternatively: Could we remove the use/need for CurrentSourceLang? Guess it was added for fortran support, but perhaps we should've gone the toher way and weakened the checks? Just don't check for count/upperbound at all? (in visitDISubrange)

Presumably LLVM can produce whatever DWARF we do for Fortran given such info, and do that for C++ too - even if it's incorrect for C++, maybe we move that to just be up to the IR generator to get that right?

I did a bit of digging and it seems that those checks for count/upperBound were added for Fortran's allocatable array in https://reviews.llvm.org/D80197. Later they had to be modified for Fortran's assumed size arrays in https://reviews.llvm.org/D87500. So the checks were added for a Fortran feature and later had to be disabled for Fortran. Removing/weakening them seems reasonable to me. Please let me know if you prefer this solution.

@dwblaikie
Copy link
Collaborator

Yeah, lets weaken the verification here - if LLVM's DWARF generation can succeed (not crash), I think that's all we should care about. If someone makes a DISubrange with an upper bound lower than the lower bound (implicit or explicit) - shrug garbage in, garbage out. I don't think it's worth trying to save them from themselves with the IR verifier.

@dwblaikie
Copy link
Collaborator

(might be worth checking where the earlier version of the check was (before fortran - looks like it just checked the upper bound was >= 0) - and if the author is still around, cc them on this in case they want to protest that checking that is really important or something)

@abidh
Copy link
Contributor Author

abidh commented Jun 28, 2024

(might be worth checking where the earlier version of the check was (before fortran - looks like it just checked the upper bound was >= 0) - and if the author is still around, cc them on this in case they want to protest that checking that is really important or something)

I have removed the check that Subrange/GenericSubrange must contain count or upper bound. I have also removed CurrentSourceLang and updated the tests accordingly.

From your comments, I guess that you also wanted to remove the count >= -1 check. I have left it there for now. AsmParser catches the case if you give it a file with count < -1. I thought that similar check should stay on the Verifier too. The count >= -1 check was added by @dexonsmith in 53855f0.

abidh added 6 commits July 2, 2024 18:33
In current order, `Type` is processed before `Unit` by the Verifier.
This can cause a race condition. Take the following example code:

```
int test(int a[][5])
{
    return a[0][2];
}
```

when compiled with clang, you will notice that control reaches
`Verifier::visitDISubrange` first with `CurrentSourceLang` still equal
to dwarf::DW_LANG_lo_user (32768). The control reaches
`Verifier::visitDICompileUnit` later and sets the value of
`CurrentSourceLang` correctly.

This behavior does not effect C like language much but is a problem for
Fortran. There is special processing in `Verifier::visitDISubrange` when
`CurrentSourceLang` is Fortran. With this problem, that special handling
is missed and verifier fails for any code that has Fortran's assumed
size array in a global subroutine.

To fix this, I have swapped the position of `Type` and `Unit`. They
were already adjacent so it does not require changing position of
anything else.
When visiting metadata attached to DISubprogram, it was possible to
read `CurrentSourceLang` before `visitDICompileUnit` has a chance to set
it to proper value. This happened because `Type` is processed before
`Unit` because of the order of the metadata in DISubprogram.

My initial fix was to change the order. But @jmorse suggested setting
`CurrentSourceLang` in `visitDISubprogram` which eliminates the need
for changing the order of metadata fields.
Test checks that DISubrange without a count or upper bound entry is
accepted when source language is Fortran.
@dwblaikie
Copy link
Collaborator

Yeah... @alokkrsharma in case they've got thoughts on this issue/changes...

@dwblaikie
Copy link
Collaborator

This change will need test coverage - it might be worth keeping the existing tests around and turning them into code generation tests, to check we can generate DWARF even when we violate these verifier checks?
And we'll need a new test for the intended functionality that motivated you to look into this issue in the first place? (the missing language code/incorrect bounds checking issue? Though I realize it's sort of a non-issue once there's no bounds checking at all anyway... )

@abidh
Copy link
Contributor Author

abidh commented Jul 3, 2024

This change will need test coverage - it might be worth keeping the existing tests around and turning them into code generation tests, to check we can generate DWARF even when we violate these verifier checks? And we'll need a new test for the intended functionality that motivated you to look into this issue in the first place? (the missing language code/incorrect bounds checking issue? Though I realize it's sort of a non-issue once there's no bounds checking at all anyway... )

I have added a test that checks that debug info is generated correctly when these conditions are violated. The test covers the original motivating case that compilation does not fail for things like !DISubrange().

@alokkrsharma
Copy link
Contributor

Yeah... @alokkrsharma in case they've got thoughts on this issue/changes...

I'll have a look and get back on this. Thanks.

@alokkrsharma
Copy link
Contributor

This LGTM.

Initially (Before enhancements for the Fortran debugging) Verifier had a restriction for DISubrange to have count as REQUIRED field. As languages do have default values for lowerBound, count explicitly gives number of elements and upper bound can be calculated (upper - lower +1).
We have relaxed this restriction for the first time due to the need of the Fortran language where upperBound is used more naturally and if needed count can be calculated. Now DISubrange should either have count or upperBound.
This restriction further relaxed again for the Fortran assumed size array where for last dimension count/upper bound can be absent.

Removing restriction completely in place of relaxing would make any language (like Fortran) with prosperous arrays happy. I agree with the point that back-end should have common/minimum restrictions which applies to all the languages, any extra restriction should be moved to respective front-ends if needed. Thanks.

Copy link
Member

@jmorse jmorse left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM; please leave a day or two before landing so that other reviewers can chip in.

@abidh abidh changed the title [DebugInfo] Swap 'Unit' and 'Type' positions in DISubprogram. [DebugInfo] Allow DISubrange/DIGenericSubrange without count/upperBound. Jul 9, 2024
@abidh abidh merged commit 2a36ef5 into llvm:main Jul 9, 2024
7 checks passed
@llvm-ci
Copy link
Collaborator

llvm-ci commented Jul 9, 2024

LLVM Buildbot has detected a new failure on builder llvm-nvptx64-nvidia-ubuntu running on as-builder-7 while building llvm at step 6 "test-build-unified-tree-check-llvm".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/160/builds/1378

Here is the relevant piece of the build log for the reference:

Step 6 (test-build-unified-tree-check-llvm) failure: test (failure)
******************** TEST 'LLVM :: DebugInfo/subrange-missing-upperBound.ll' FAILED ********************
Exit Code: 2

Command Output (stderr):
--
RUN: at line 1: /home/buildbot/worker/as-builder-7/ramdisk/llvm-nvptx64-nvidia-ubuntu/build/bin/llc /home/buildbot/worker/as-builder-7/ramdisk/llvm-nvptx64-nvidia-ubuntu/llvm-project/llvm/test/DebugInfo/subrange-missing-upperBound.ll -filetype=obj -o - | /home/buildbot/worker/as-builder-7/ramdisk/llvm-nvptx64-nvidia-ubuntu/build/bin/llvm-dwarfdump - | /home/buildbot/worker/as-builder-7/ramdisk/llvm-nvptx64-nvidia-ubuntu/build/bin/FileCheck /home/buildbot/worker/as-builder-7/ramdisk/llvm-nvptx64-nvidia-ubuntu/llvm-project/llvm/test/DebugInfo/subrange-missing-upperBound.ll
+ /home/buildbot/worker/as-builder-7/ramdisk/llvm-nvptx64-nvidia-ubuntu/build/bin/llc /home/buildbot/worker/as-builder-7/ramdisk/llvm-nvptx64-nvidia-ubuntu/llvm-project/llvm/test/DebugInfo/subrange-missing-upperBound.ll -filetype=obj -o -
+ /home/buildbot/worker/as-builder-7/ramdisk/llvm-nvptx64-nvidia-ubuntu/build/bin/llvm-dwarfdump -
+ /home/buildbot/worker/as-builder-7/ramdisk/llvm-nvptx64-nvidia-ubuntu/build/bin/FileCheck /home/buildbot/worker/as-builder-7/ramdisk/llvm-nvptx64-nvidia-ubuntu/llvm-project/llvm/test/DebugInfo/subrange-missing-upperBound.ll
Program aborted due to an unhandled Error:
createMCCodeEmitter failed
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace.
Stack dump:
0.	Program arguments: /home/buildbot/worker/as-builder-7/ramdisk/llvm-nvptx64-nvidia-ubuntu/build/bin/llc /home/buildbot/worker/as-builder-7/ramdisk/llvm-nvptx64-nvidia-ubuntu/llvm-project/llvm/test/DebugInfo/subrange-missing-upperBound.ll -filetype=obj -o -
 #0 0x0000783565f94c70 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/home/buildbot/worker/as-builder-7/ramdisk/llvm-nvptx64-nvidia-ubuntu/build/lib/libLLVMSupport.so.19.0git+0x1dac70)
 #1 0x0000783565f9208f llvm::sys::RunSignalHandlers() (/home/buildbot/worker/as-builder-7/ramdisk/llvm-nvptx64-nvidia-ubuntu/build/lib/libLLVMSupport.so.19.0git+0x1d808f)
 #2 0x0000783565f921e5 SignalHandler(int) Signals.cpp:0:0
 #3 0x0000783565642520 (/lib/x86_64-linux-gnu/libc.so.6+0x42520)
 #4 0x00007835656969fc __pthread_kill_implementation ./nptl/pthread_kill.c:44:76
 #5 0x00007835656969fc __pthread_kill_internal ./nptl/pthread_kill.c:78:10
 #6 0x00007835656969fc pthread_kill ./nptl/pthread_kill.c:89:10
 #7 0x0000783565642476 gsignal ./signal/../sysdeps/posix/raise.c:27:6
 #8 0x00007835656287f3 abort ./stdlib/abort.c:81:7
 #9 0x0000783565eaec8b llvm::Error::fatalUncheckedError() const (/home/buildbot/worker/as-builder-7/ramdisk/llvm-nvptx64-nvidia-ubuntu/build/lib/libLLVMSupport.so.19.0git+0xf4c8b)
#10 0x0000783567dea758 llvm::LLVMTargetMachine::addAsmPrinter(llvm::legacy::PassManagerBase&, llvm::raw_pwrite_stream&, llvm::raw_pwrite_stream*, llvm::CodeGenFileType, llvm::MCContext&) (/home/buildbot/worker/as-builder-7/ramdisk/llvm-nvptx64-nvidia-ubuntu/build/lib/libLLVMCodeGen.so.19.0git+0x318758)
#11 0x0000783567dea8a5 llvm::LLVMTargetMachine::addPassesToEmitFile(llvm::legacy::PassManagerBase&, llvm::raw_pwrite_stream&, llvm::raw_pwrite_stream*, llvm::CodeGenFileType, bool, llvm::MachineModuleInfoWrapperPass*) (/home/buildbot/worker/as-builder-7/ramdisk/llvm-nvptx64-nvidia-ubuntu/build/lib/libLLVMCodeGen.so.19.0git+0x3188a5)
#12 0x00005668ee036820 compileModule(char**, llvm::LLVMContext&) llc.cpp:0:0
#13 0x00005668ee02c6fe main (/home/buildbot/worker/as-builder-7/ramdisk/llvm-nvptx64-nvidia-ubuntu/build/bin/llc+0xf6fe)
#14 0x0000783565629d90 __libc_start_call_main ./csu/../sysdeps/nptl/libc_start_call_main.h:58:16
#15 0x0000783565629e40 call_init ./csu/../csu/libc-start.c:128:20
#16 0x0000783565629e40 __libc_start_main ./csu/../csu/libc-start.c:379:5
#17 0x00005668ee02d255 _start (/home/buildbot/worker/as-builder-7/ramdisk/llvm-nvptx64-nvidia-ubuntu/build/bin/llc+0x10255)
error: -: The file was not recognized as a valid object file
FileCheck error: '<stdin>' is empty.
FileCheck command line:  /home/buildbot/worker/as-builder-7/ramdisk/llvm-nvptx64-nvidia-ubuntu/build/bin/FileCheck /home/buildbot/worker/as-builder-7/ramdisk/llvm-nvptx64-nvidia-ubuntu/llvm-project/llvm/test/DebugInfo/subrange-missing-upperBound.ll

--

********************


@llvm-ci
Copy link
Collaborator

llvm-ci commented Jul 9, 2024

LLVM Buildbot has detected a new failure on builder llvm-nvptx-nvidia-ubuntu running on as-builder-7 while building llvm at step 6 "test-build-unified-tree-check-llvm".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/180/builds/1377

Here is the relevant piece of the build log for the reference:

Step 6 (test-build-unified-tree-check-llvm) failure: test (failure)
******************** TEST 'LLVM :: DebugInfo/subrange-missing-upperBound.ll' FAILED ********************
Exit Code: 2

Command Output (stderr):
--
RUN: at line 1: /home/buildbot/worker/as-builder-7/ramdisk/llvm-nvptx-nvidia-ubuntu/build/bin/llc /home/buildbot/worker/as-builder-7/ramdisk/llvm-nvptx-nvidia-ubuntu/llvm-project/llvm/test/DebugInfo/subrange-missing-upperBound.ll -filetype=obj -o - | /home/buildbot/worker/as-builder-7/ramdisk/llvm-nvptx-nvidia-ubuntu/build/bin/llvm-dwarfdump - | /home/buildbot/worker/as-builder-7/ramdisk/llvm-nvptx-nvidia-ubuntu/build/bin/FileCheck /home/buildbot/worker/as-builder-7/ramdisk/llvm-nvptx-nvidia-ubuntu/llvm-project/llvm/test/DebugInfo/subrange-missing-upperBound.ll
+ /home/buildbot/worker/as-builder-7/ramdisk/llvm-nvptx-nvidia-ubuntu/build/bin/llc /home/buildbot/worker/as-builder-7/ramdisk/llvm-nvptx-nvidia-ubuntu/llvm-project/llvm/test/DebugInfo/subrange-missing-upperBound.ll -filetype=obj -o -
+ /home/buildbot/worker/as-builder-7/ramdisk/llvm-nvptx-nvidia-ubuntu/build/bin/llvm-dwarfdump -
+ /home/buildbot/worker/as-builder-7/ramdisk/llvm-nvptx-nvidia-ubuntu/build/bin/FileCheck /home/buildbot/worker/as-builder-7/ramdisk/llvm-nvptx-nvidia-ubuntu/llvm-project/llvm/test/DebugInfo/subrange-missing-upperBound.ll
Program aborted due to an unhandled Error:
createMCCodeEmitter failed
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace.
Stack dump:
0.	Program arguments: /home/buildbot/worker/as-builder-7/ramdisk/llvm-nvptx-nvidia-ubuntu/build/bin/llc /home/buildbot/worker/as-builder-7/ramdisk/llvm-nvptx-nvidia-ubuntu/llvm-project/llvm/test/DebugInfo/subrange-missing-upperBound.ll -filetype=obj -o -
 #0 0x000074ab75689c70 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/home/buildbot/worker/as-builder-7/ramdisk/llvm-nvptx-nvidia-ubuntu/build/lib/libLLVMSupport.so.19.0git+0x1dac70)
 #1 0x000074ab7568708f llvm::sys::RunSignalHandlers() (/home/buildbot/worker/as-builder-7/ramdisk/llvm-nvptx-nvidia-ubuntu/build/lib/libLLVMSupport.so.19.0git+0x1d808f)
 #2 0x000074ab756871e5 SignalHandler(int) Signals.cpp:0:0
 #3 0x000074ab74e42520 (/lib/x86_64-linux-gnu/libc.so.6+0x42520)
 #4 0x000074ab74e969fc __pthread_kill_implementation ./nptl/pthread_kill.c:44:76
 #5 0x000074ab74e969fc __pthread_kill_internal ./nptl/pthread_kill.c:78:10
 #6 0x000074ab74e969fc pthread_kill ./nptl/pthread_kill.c:89:10
 #7 0x000074ab74e42476 gsignal ./signal/../sysdeps/posix/raise.c:27:6
 #8 0x000074ab74e287f3 abort ./stdlib/abort.c:81:7
 #9 0x000074ab755a3c8b llvm::Error::fatalUncheckedError() const (/home/buildbot/worker/as-builder-7/ramdisk/llvm-nvptx-nvidia-ubuntu/build/lib/libLLVMSupport.so.19.0git+0xf4c8b)
#10 0x000074ab774df758 llvm::LLVMTargetMachine::addAsmPrinter(llvm::legacy::PassManagerBase&, llvm::raw_pwrite_stream&, llvm::raw_pwrite_stream*, llvm::CodeGenFileType, llvm::MCContext&) (/home/buildbot/worker/as-builder-7/ramdisk/llvm-nvptx-nvidia-ubuntu/build/lib/libLLVMCodeGen.so.19.0git+0x318758)
#11 0x000074ab774df8a5 llvm::LLVMTargetMachine::addPassesToEmitFile(llvm::legacy::PassManagerBase&, llvm::raw_pwrite_stream&, llvm::raw_pwrite_stream*, llvm::CodeGenFileType, bool, llvm::MachineModuleInfoWrapperPass*) (/home/buildbot/worker/as-builder-7/ramdisk/llvm-nvptx-nvidia-ubuntu/build/lib/libLLVMCodeGen.so.19.0git+0x3188a5)
#12 0x00005959cdb1d820 compileModule(char**, llvm::LLVMContext&) llc.cpp:0:0
#13 0x00005959cdb136fe main (/home/buildbot/worker/as-builder-7/ramdisk/llvm-nvptx-nvidia-ubuntu/build/bin/llc+0xf6fe)
#14 0x000074ab74e29d90 __libc_start_call_main ./csu/../sysdeps/nptl/libc_start_call_main.h:58:16
#15 0x000074ab74e29e40 call_init ./csu/../csu/libc-start.c:128:20
#16 0x000074ab74e29e40 __libc_start_main ./csu/../csu/libc-start.c:379:5
#17 0x00005959cdb14255 _start (/home/buildbot/worker/as-builder-7/ramdisk/llvm-nvptx-nvidia-ubuntu/build/bin/llc+0x10255)
error: -: The file was not recognized as a valid object file
FileCheck error: '<stdin>' is empty.
FileCheck command line:  /home/buildbot/worker/as-builder-7/ramdisk/llvm-nvptx-nvidia-ubuntu/build/bin/FileCheck /home/buildbot/worker/as-builder-7/ramdisk/llvm-nvptx-nvidia-ubuntu/llvm-project/llvm/test/DebugInfo/subrange-missing-upperBound.ll

--

********************


@abidh
Copy link
Contributor Author

abidh commented Jul 9, 2024

I am adding REQUIRES: object-emission in the test and also using -o %t instead of -o -. This probably will be enough to fix the failure reported above.

dwblaikie pushed a commit that referenced this pull request Jul 9, 2024
The test added in #96474 seems to cause buildbot failure on some system.
I have added `REQUIRES: object-emission` in the test and also used `%t`
instead of `-` for output.
aaryanshukla pushed a commit to aaryanshukla/llvm-project that referenced this pull request Jul 14, 2024
…nd. (llvm#96474)

Due to the current order of metadata in DISubprgram, `Type` is processed
before `Unit` by the Verifier. This can cause a race and
 use of garbage data. Consider the following code:

```
int test(int a[][5])
{
    return a[0][2];
}
```

when compiled with clang, the control reaches
`Verifier::visitDISubrange` first with `CurrentSourceLang` still equal
to dwarf::DW_LANG_lo_user (32768). The `Verifier::visitDICompileUnit`
which sets the value of `CurrentSourceLang` is reached later. So
`Verifier::visitDISubrange` ends up using a wrong value of
`CurrentSourceLang`.

This behavior does not effect C like language much but is a problem for
Fortran. There is special processing in `Verifier::visitDISubrange` when
`CurrentSourceLang` is Fortran. With this problem, that special handling
is missed and verifier fails for any code that has Fortran's assumed
size array in a global subroutine.

Various solutions were tried to solve this problem before it was decided that
best course of action is to remove these checks from Verifier.
aaryanshukla pushed a commit to aaryanshukla/llvm-project that referenced this pull request Jul 14, 2024
The test added in llvm#96474 seems to cause buildbot failure on some system.
I have added `REQUIRES: object-emission` in the test and also used `%t`
instead of `-` for output.
@abidh abidh deleted the disubprogram branch October 9, 2024 16:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants