runtime: Linux arm 5.0 launch fails with CORDBG_E_MISSING_DEBUGGER_EXPORTS

This issue is from https://github.com/OmniSharp/omnisharp-vscode/issues/4210. Bug report is from @profix898

Issue Description

After deploying a .NET 5 linux-arm app to a Raspberry Pi 4, debugging fails with CORDBG_E_MISSING_DEBUGGER_EXPORTS (0x80131c4f). This doesn’t happen with 3.1.

Steps to Reproduce

  1. I have created a minimal console project with the following content:

RPiDemo.csproj

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net5.0</TargetFramework>
  </PropertyGroup>
</Project>

Program.cs

using System;

namespace RPiDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello RPi!");
        }
    }
}

The project is successfully compiled in VS Code on Win 10 x64 using the locally installed .NET 5 SDK. The project is published for ‘linux-arm’ and copied to the Raspberry Pi 4 (with Raspian 10, latest version as of today) with the following command:

dotnet publish -c Release -r linux-arm -o ./publish/linux-arm ${workspaceFolder} ; scp -rp -P 2222 ./publish/linux-arm/ root@192.168.81.129:/opt/RPiDemo

I’m essentially following the instructions at https://github.com/OmniSharp/omnisharp-vscode/wiki/Remote-Debugging-On-Linux-Arm (or similar tutorials on the internet).

The project is then launched on the RPi with the ‘vsdbg’ remote debugger. My launch.json looks like this:

{
    "configurations": [        
        {
            "name": "Launch LOCAL",
            "type": "coreclr",
            "request": "launch",
            "preLaunchTask": "build",
            "program": "${workspaceFolder}/bin/Debug/net5.0/RPiDemo.dll",
            "args": [],
            "cwd": "${workspaceFolder}",
            "stopAtEntry": false,
            "console": "internalConsole"
        }, 
        {
            "name": "Launch REMOTE",
            "type": "coreclr",
            "request": "launch",
            "preLaunchTask": "BuildPublishCopyLinuxARM",
            "program": "/usr/bin/dotnet",
            "args": [
                "/opt/RPiDemo/RPiDemo.dll"
            ],
            "cwd": "/opt/RPiDemo",
            "stopAtEntry": false,
            "console": "internalConsole",
            "pipeTransport": {
                "pipeCwd": "${workspaceRoot}",
                "pipeProgram": "ssh",
                "pipeArgs": [
                    "-T",
                    "-p", "2222",
                    "root@192.168.81.129"
                ],
                "quoteArgs": true,
                "debuggerPath": "/usr/bin/vsdbg/vsdbg"
            },
            "logging": {
                "engineLogging": true,
                "programOutput": true,
                "exceptions": true
            }
        },
    ]
}

Expected Behavior

Debugger should launch and attach to the process on the RPi and provide debug information to VS Code.

Actual Behavior

Debugger prints the following error message: Unable to attach to CoreCLR. Unknown Error: 0x80131c4f. I have then enabled logging via "engineLogging": true, to obtain more details (as shown in the log below).

I’d like to note, that the console project works perfectly both locally on the Win 10 x64 host and also when being launched manually on the RPi via the dotnet RPiDemo.dll command (directly in the published directory ‘/opt/RPiDemo’).

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Reactions: 3
  • Comments: 44 (29 by maintainers)

Most upvoted comments

Sorry, but there’s no work around. This is a compile time issue. It’s been there for years. The problem is we added a new code path and it hits it very easily on such systems. The change is simple but I’ve had trouble testing this. I’ve prepared the PR and the port to 5.0 so I can expedite the process.

@hoyosjs it’s working!

image

I put the --no-self-contained on my build command and now it’s using the shared framework. Thanks!

There’s this https://dotnetcli.blob.core.windows.net/dotnet/Runtime/5.0.2-servicing.20611.21/dotnet-runtime-5.0.2-linux-arm.tar.gz. You can extract it and you’ll have a shared framework. On the debugger side, you can set the environment variable DOTNET_ROOT pointing to that folder and use that dotnet executable to ensure you use it. Given that the extracted folder will be called 5.0.2, be really careful to delete it and actually install the release once it actually comes out. This is not a complete release - it’s a nightly build and you should use it with caution, there might be bugs as it hasn’t gone through all the exit validation processes. It should at least unblock you on debugging as it has the bits that fixed the issue.

Let me ask if I can share a nightly build of the rolling release and answer tomorrow.

I was helping @hoyosjs to investigate it yesterday and we have found that it is a bug in our code that occurs only when debugger attempts to get certain data structures from the target process at addresses >= 2GB. For some reason lost in the past even before .NET Core was ported to Linux, we were undefining the _FILE_OFFSET_BITS in the file where the method to read from the remote process is located. That causes the pread function to have 32 bit signed integer as the offset argument (the address is passed in there). So addresses above 2GB were passed in as negative values. Internally, the pread function converts that value to signed 64 bit value that is further passed to the actual pread syscall. So instead of e.g. 0xf75c7000 that our function was passing to pread function, the actual pread syscall was getting 0xfffffffff75c7000, which is a nonsense. I believe that just keeping the _FILE_OFFSET_BITS defined to 64 as we do for all other parts of our PAL should fix the problem. But @hoyosjs is currently verifying that everything works with that setting.

From my experience, it is just Linux ARM. Even Linux ARM64 works fine. I switched to the beta version of Raspian 64-bit (and tried Ubuntu 64-bit for Raspberry Pi), on both platforms the debugger works as expected. Note, however, that the 32-bit version is the default/stable branch for RPi.

+1, would be great to see it fixed, debugging is one of the key value of .NET on devices like Raspberry Pi running Linux arm based OS.

should this be considered for servicing fix? I’m hearing users not wanting to move to 5.0 because of this