runtime: System.IO.Ports.SerialPort not working on Linux arm64
Description
'Unable to load shared library ‘libSystem.IO.Ports.Native’ or one of its dependencies
Similar to issue #63187 though Linux versions differ. Presumably the same root issue.
Reproduction Steps
Create new console app (.net 6.0)
Add System.IO.Ports NuGet.
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<PlatformTarget>AnyCPU</PlatformTarget>
<RuntimeIdentifier>linux-arm</RuntimeIdentifier>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="System.IO.Ports" Version="6.0.0" />
</ItemGroup>
</Project>
using System.IO.Ports;
namespace RaspberryPiIoTTestApp02
{
internal class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello, World!");
string[] ports = SerialPort.GetPortNames();
// Display each port name to the console.
foreach (string p in ports)
{
Console.WriteLine($"GetSerialPorts(): {p}");
}
string _portName = "/dev/ttyAMA1";
SerialPort port = new SerialPort(_portName);
port.BaudRate = 19200;
port.DataBits = 8;
port.Parity = Parity.Even;
port.StopBits = StopBits.One;
port.Open();
}
}
}
Expected behavior
Program runs.
Prints out available serial ports, (in my case)
GetSerialPorts(): /dev/ttyAMA1
GetSerialPorts(): /dev/ttyAMA2
GetSerialPorts(): /dev/ttyAMA0
Opens port /dev/ttyAMA1
Actual behavior
Program runs.
Prints out available serial ports, (in my case)
GetSerialPorts(): /dev/ttyAMA1
GetSerialPorts(): /dev/ttyAMA2
GetSerialPorts(): /dev/ttyAMA0
Exception at port.Open();
Exception thrown: 'System.DllNotFoundException' in System.IO.Ports.dll
An unhandled exception of type 'System.DllNotFoundException' occurred in System.IO.Ports.dll: 'Unable to load shared library 'libSystem.IO.Ports.Native' or one of its dependencies. In order to help diagnose loading problems, consider setting the LD_DEBUG environment variable: liblibSystem.IO.Ports.Native: cannot open shared object file: No such file or directory'
Stack trace:
> at Interop.Serial.SerialPortOpen(String name)
> at System.IO.Ports.SafeSerialDeviceHandle.Open(String portName)
> at System.IO.Ports.SerialStream..ctor(String portName, Int32 baudRate, Parity parity, Int32 dataBits, StopBits stopBits, Int32 readTimeout, Int32 writeTimeout, Handshake handshake, Boolean dtrEnable, Boolean rtsEnable, Boolean discardNull, Byte parityReplace)
> at System.IO.Ports.SerialPort.Open()
> at RaspberryPiIoTTestApp02.Program.Main(String[] args) in C:\Users\georg\OneDrive\Documents\Visual Studio\2022 - vs22\RaspberryPiIoTTestApp02\RaspberryPiIoTTestApp02\Program.cs:line 17
Setting LD_DEBUG=all gives some info though unfortunately its all a bit beyond me!
5612:
5612: file=/home/pi/vsdbg/RaspberryPiIoTTestApp02/libSystem.IO.Ports.Native.so [0]; dynamically loaded by /usr/lib/dotnet/shared/Microsoft.NETCore.App/6.0.8/libcoreclr.so [0]
5612:
5612: file=/usr/lib/dotnet/shared/Microsoft.NETCore.App/6.0.8/libSystem.IO.Ports.Native.so [0]; dynamically loaded by /usr/lib/dotnet/shared/Microsoft.NETCore.App/6.0.8/libcoreclr.so [0]
5612:
5612: file=/home/pi/vsdbg/RaspberryPiIoTTestApp02/libSystem.IO.Ports.Native.so [0]; dynamically loaded by /usr/lib/dotnet/shared/Microsoft.NETCore.App/6.0.8/libcoreclr.so [0]
5612:
5612: file=libSystem.IO.Ports.Native.so [0]; dynamically loaded by /usr/lib/dotnet/shared/Microsoft.NETCore.App/6.0.8/libcoreclr.so [0]
5612: find library=libSystem.IO.Ports.Native.so [0]; searching
5612: search cache=/etc/ld.so.cache
5612: search path=/lib/aarch64-linux-gnu:/usr/lib/aarch64-linux-gnu:/lib:/usr/lib (system search path)
5612: trying file=/lib/aarch64-linux-gnu/libSystem.IO.Ports.Native.so
5612: trying file=/usr/lib/aarch64-linux-gnu/libSystem.IO.Ports.Native.so
5612: trying file=/lib/libSystem.IO.Ports.Native.so
5612: trying file=/usr/lib/libSystem.IO.Ports.Native.so
5612:
5612:
5612: file=/home/pi/vsdbg/RaspberryPiIoTTestApp02/liblibSystem.IO.Ports.Native.so [0]; dynamically loaded by /usr/lib/dotnet/shared/Microsoft.NETCore.App/6.0.8/libcoreclr.so [0]
5612:
5612: file=/usr/lib/dotnet/shared/Microsoft.NETCore.App/6.0.8/liblibSystem.IO.Ports.Native.so [0]; dynamically loaded by /usr/lib/dotnet/shared/Microsoft.NETCore.App/6.0.8/libcoreclr.so [0]
5612:
5612: file=/home/pi/vsdbg/RaspberryPiIoTTestApp02/liblibSystem.IO.Ports.Native.so [0]; dynamically loaded by /usr/lib/dotnet/shared/Microsoft.NETCore.App/6.0.8/libcoreclr.so [0]
5612:
5612: file=liblibSystem.IO.Ports.Native.so [0]; dynamically loaded by /usr/lib/dotnet/shared/Microsoft.NETCore.App/6.0.8/libcoreclr.so [0]
5612: find library=liblibSystem.IO.Ports.Native.so [0]; searching
5612: search cache=/etc/ld.so.cache
5612: search path=/lib/aarch64-linux-gnu:/usr/lib/aarch64-linux-gnu:/lib:/usr/lib (system search path)
5612: trying file=/lib/aarch64-linux-gnu/liblibSystem.IO.Ports.Native.so
5612: trying file=/usr/lib/aarch64-linux-gnu/liblibSystem.IO.Ports.Native.so
5612: trying file=/lib/liblibSystem.IO.Ports.Native.so
5612: trying file=/usr/lib/liblibSystem.IO.Ports.Native.so
5612:
5612:
5612: file=/home/pi/vsdbg/RaspberryPiIoTTestApp02/libSystem.IO.Ports.Native [0]; dynamically loaded by /usr/lib/dotnet/shared/Microsoft.NETCore.App/6.0.8/libcoreclr.so [0]
5612:
5612: file=/usr/lib/dotnet/shared/Microsoft.NETCore.App/6.0.8/libSystem.IO.Ports.Native [0]; dynamically loaded by /usr/lib/dotnet/shared/Microsoft.NETCore.App/6.0.8/libcoreclr.so [0]
5612:
5612: file=/home/pi/vsdbg/RaspberryPiIoTTestApp02/libSystem.IO.Ports.Native [0]; dynamically loaded by /usr/lib/dotnet/shared/Microsoft.NETCore.App/6.0.8/libcoreclr.so [0]
5612:
5612: file=libSystem.IO.Ports.Native [0]; dynamically loaded by /usr/lib/dotnet/shared/Microsoft.NETCore.App/6.0.8/libcoreclr.so [0]
5612: find library=libSystem.IO.Ports.Native [0]; searching
5612: search cache=/etc/ld.so.cache
5612: search path=/lib/aarch64-linux-gnu:/usr/lib/aarch64-linux-gnu:/lib:/usr/lib (system search path)
5612: trying file=/lib/aarch64-linux-gnu/libSystem.IO.Ports.Native
5612: trying file=/usr/lib/aarch64-linux-gnu/libSystem.IO.Ports.Native
5612: trying file=/lib/libSystem.IO.Ports.Native
5612: trying file=/usr/lib/libSystem.IO.Ports.Native
5612:
5612:
5612: file=/home/pi/vsdbg/RaspberryPiIoTTestApp02/liblibSystem.IO.Ports.Native [0]; dynamically loaded by /usr/lib/dotnet/shared/Microsoft.NETCore.App/6.0.8/libcoreclr.so [0]
5612:
5612: file=/usr/lib/dotnet/shared/Microsoft.NETCore.App/6.0.8/liblibSystem.IO.Ports.Native [0]; dynamically loaded by /usr/lib/dotnet/shared/Microsoft.NETCore.App/6.0.8/libcoreclr.so [0]
5612:
5612: file=/home/pi/vsdbg/RaspberryPiIoTTestApp02/liblibSystem.IO.Ports.Native [0]; dynamically loaded by /usr/lib/dotnet/shared/Microsoft.NETCore.App/6.0.8/libcoreclr.so [0]
5612:
5612: file=liblibSystem.IO.Ports.Native [0]; dynamically loaded by /usr/lib/dotnet/shared/Microsoft.NETCore.App/6.0.8/libcoreclr.so [0]
5612: find library=liblibSystem.IO.Ports.Native [0]; searching
5612: search cache=/etc/ld.so.cache
5612: search path=/lib/aarch64-linux-gnu:/usr/lib/aarch64-linux-gnu:/lib:/usr/lib (system search path)
5612: trying file=/lib/aarch64-linux-gnu/liblibSystem.IO.Ports.Native
5612: trying file=/usr/lib/aarch64-linux-gnu/liblibSystem.IO.Ports.Native
5612: trying file=/lib/liblibSystem.IO.Ports.Native
5612: trying file=/usr/lib/liblibSystem.IO.Ports.Native
5612:
Note that the exception appears on port.Open(); not when an instance of SerialPort is created or when we’re getting all available serial ports.
Regression?
Unknown though though the notnet/iot team have example code for Controlling Arduino with .NET using Raspberry Pi via serial port here using System.IO.Ports -v 4.6.0-preview.18571.3. It may be that they are using ARM (32-bit) that is unaffected by this or it is a regression.
Known Workarounds
Unknown though some people have reported work arounds in issue #63187.
Configuration
Which version of .NET is the code running on? .NET 6.0 What OS and version, and what distro if applicable? Raspberry Pi OS - 64-bit - Lite What is the architecture (x64, x86, ARM, ARM64)? ARM64 Do you know whether it is specific to that configuration? It appears to be affecting other versions of linux through similar issues #63187
Other information
No response
About this issue
- Original URL
- State: closed
- Created 2 years ago
- Reactions: 2
- Comments: 21 (15 by maintainers)
I find using the CLI dotnet with command line switches eg [
dotnet publish -c Debug -r linux-musl-arm64 --sc] is often better than using latest upgrade of VS2022 IDE as it tends to lack new configuration features. Although since they swapped to new Project Properties config menu it is getting closer.Yes sounds like it. Or something is happening in the source build pipeline for that combination of runtime & architecture, the switching combinations during build can get complex to follow. I’ve gone over the dotnet runtime Repo several times to look at how the native libs are built but starting to wonder if it’s actually a problem in the SDK, and that repo I am not familiar with.
I know people use it, but is Raspbian officially supported by .dot net 7? What is the --runtime your targeting during build? And you’re building on the device using an installed SDK or PC and building for Alpine or something and ARM64 ? What’s the error your getting, same as above missing libSystem.IO.Ports.Native ?
What happens when you CD into the project folder (bin) and run
lddon the library?ldd libSystem.IO.Ports.Native.soAs below? https://github.com/dotnet/runtime/issues/74332#issuecomment-1288010254Are you building a Self-Contained app or runtime dependant, tried both? Out of pure curiosity can you run this & send back just the relevant-interesting OS/bitlevel/etc Environment fields? https://github.com/PRIMETSS/DotNetCoreOpenWRTLinux32
This issue has been automatically marked
no-recent-activitybecause it has not had any activity for 14 days. It will be closed if no further activity occurs within 14 more days. Any new comment (by anyone, not necessarily the author) will removeno-recent-activity.