dotnet / runtime

.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
https://docs.microsoft.com/dotnet/core/
MIT License
15.36k stars 4.75k forks source link

Fix remaining Native AOT Linux DWARF errors #90209

Open agocke opened 1 year ago

agocke commented 1 year ago

As noted in https://github.com/dotnet/runtime/pull/89488, the only remaining Native AOT errors are EH around SAMETRY:

error: DIEs have overlapping address ranges:
0x000367a4: DW_TAG_try_block [37]   (0x000366e5)
              DW_AT_low_pc [DW_FORM_addr]       (0x00000000000132f6 "__managedcode")
              DW_AT_high_pc [DW_FORM_data8]     (0x000000000000016a)

0x00036782: DW_TAG_try_block [37]   (0x000366e5)
              DW_AT_low_pc [DW_FORM_addr]       (0x00000000000133ed "__managedcode")
              DW_AT_high_pc [DW_FORM_data8]     (0x0000000000000069)

error: DIEs have overlapping address ranges:
...

The other errors are from clang-compiled files, so there's nothing for us to do there.

Also note: EH info is not produced on Mac, so the errors don't appear there.

ghost commented 1 year ago

Tagging subscribers to this area: @agocke, @MichalStrehovsky, @jkotas See info in area-owners.md if you want to be subscribed.

Issue Details
As noted in https://github.com/dotnet/runtime/pull/89488, the only remaining Native AOT errors are EH around SAMETRY: ``` error: DIEs have overlapping address ranges: 0x000367a4: DW_TAG_try_block [37] (0x000366e5) DW_AT_low_pc [DW_FORM_addr] (0x00000000000132f6 "__managedcode") DW_AT_high_pc [DW_FORM_data8] (0x000000000000016a) 0x00036782: DW_TAG_try_block [37] (0x000366e5) DW_AT_low_pc [DW_FORM_addr] (0x00000000000133ed "__managedcode") DW_AT_high_pc [DW_FORM_data8] (0x0000000000000069) error: DIEs have overlapping address ranges: ... ``` The other errors are from clang-compiled files, so there's nothing for us to do there. Also note: EH info is not produced on Mac, so the errors don't appear there.
Author: agocke
Assignees: -
Labels: `area-NativeAOT-coreclr`
Milestone: 9.0.0
am11 commented 9 months ago

error: DIEs have overlapping address ranges

Related: https://github.com/dotnet/runtime/issues/83233#issuecomment-1551156322. @filipnavara, maybe the CORINFO_EH_CLAUSE_SAMETRY scope vs. variables in .debug_loc (LocationList https://github.com/dotnet/runtime/blob/12db2459c029b4b8ee0335c4d6297d8cb5968f1e/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ObjectWriter/Dwarf/DwarfInfoWriter.cs#L158) can now be handled in managed objwriter bit more conveniently?

https://github.com/dotnet/runtime/blob/12db2459c029b4b8ee0335c4d6297d8cb5968f1e/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs#L880-L905

filipnavara commented 9 months ago

The clauses need to be nested based on the address ranges. It should not be hard to implement.

am11 commented 5 months ago

The code pattern which entails these errors is nested try in try and/or the catch blocks:

using System;

try {
    // error: DIEs have overlapping address ranges:
    // 0x000442d5: DW_TAG_try_block [32]   (0x0004426f)
    //              DW_AT_low_pc [DW_FORM_addr] (0x0000000000063b2c "__managedcode")
    //              DW_AT_high_pc [DW_FORM_data8]   (0x0000000000000048)
    try { Console.WriteLine(1); }
    catch { throw; }

    Console.WriteLine(1.1);
}
catch {
    // error: DIEs have overlapping address ranges:
    // 0x00040e71: DW_TAG_catch_block [33]   (0x00040df8)
    //          DW_AT_low_pc [DW_FORM_addr] (0x0000000000059884 "__managedcode")
    //          DW_AT_high_pc [DW_FORM_data8]   (0x0000000000000018)
    try { Console.WriteLine(2); }
    catch { throw; }
}
filipnavara commented 5 months ago

Yeah, that's the pattern. The tricky part is to figure out what is the correct representation in DWARF. I was convinced that it's fine to just mirror the nesting inside the DWARF structure (as parent-child relationship). Then I couldn't find it in the spec, and I tried to replicate something similar emitted by C++ compiler... and I really couldn't come up with an answer what is the correct way to represent it.

am11 commented 5 months ago

I understood from @jakobbotsch' comment https://github.com/dotnet/runtime/issues/83233#issuecomment-1551172949 that RyuJIT should not be creating separate debug info for these nested try scopes. I assume the debuggers would still hit the breakpoint on nested try and inside the nested try as well without them? I tried to filter out the nested ranges in PublishCode() of CorInfoImpl.cs, but was failing (error: DIEs have overlapping address ranges: continue to persist). 😅

I tried to replicate something similar emitted by C++ compiler.

Same, found out that with clang++ -gdwarf-4 -g3 -O0 -o example example.cpp and this example.cpp:

#include <iostream>

int main() {
    int x = 0;
    std::cout << "Enter a value: ";
    std::cin >> x;
    try {
        if (x > 0) {
            throw x;
        }
    } catch (int e) {
        std::cout << "Caught exception: " << e << std::endl;
    }
    return 0;
}

, clang did produced some info, but that wasn't particularly useful. 🥲