Skip to content
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

System.Drawing on CentOS: Unable to load DLL 'libdl' #24070

Closed
qmfrederik opened this issue Nov 7, 2017 · 33 comments
Closed

System.Drawing on CentOS: Unable to load DLL 'libdl' #24070

qmfrederik opened this issue Nov 7, 2017 · 33 comments
Assignees
Labels
area-System.Drawing bug os-linux Linux OS (any supported distro)
Milestone

Comments

@qmfrederik
Copy link
Contributor

Any code which uses System.Drawing fails on CentOS 7.4 with the following exception:

Unhandled Exception: System.TypeInitializationException: The type initializer for 'Gdip' threw an exception. ---> System.DllNotFoundException: Unable to load DLL 'libdl': The specified module or one of its dependencies could not be found.
 (Exception from HRESULT: 0x8007007E)
   at Interop.Libdl.dlopen(String fileName, Int32 flag)
   at System.Drawing.SafeNativeMethods.Gdip.LoadNativeLibrary()
   at System.Drawing.SafeNativeMethods.Gdip..cctor()
   --- End of inner exception stack trace ---
   at System.Drawing.SafeNativeMethods.Gdip.GdipCreateBitmapFromFile(String filename, IntPtr& bitmap)
   at System.Drawing.Bitmap..ctor(String filename, Boolean useIcm)
   at gdiplus.Program.Main(String[] args) in /root/gdiplus/Program.cs:line 12

This is because by default libdl.so doesn't exist on CentOS whereas libdl.so.2 does exist.

As a workaround you can symlink /lib64/libdl.so.2 to /lib64/libdl.so.

ln -s /lib64/libdl.so.2 /lib64/libdl.so

Program.cs:

using System;
using System.Drawing;

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

            var bitmap = new Bitmap("test.bmp");
        }
    }
}

Project file:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp2.0</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="System.Drawing.Common" Version="4.5.0-preview1-25718-03"/>
  </ItemGroup>
</Project>
@qmfrederik
Copy link
Contributor Author

/cc @safern
Related to #23786

@danmoseley
Copy link
Member

The interop code tries various variations but .so.2 is not one of them. Perhaps it should be @stephentoub ?

@qmfrederik
Copy link
Contributor Author

One way to fix this could be to add dlopen and dlsym to System.Native, so that resolving dlopen and dlsym becomes a native code problem instead of a managed code problem.

It would fix the libdl.so vs libdl.so.2 problem, as well as the FreeBSD problem where dlopen lives in another library alltogether.

I could probably create a PR for that, let me know if this is the way you want to go.

@henkmollema
Copy link
Contributor

This problem seems to reproduce on Debian as well. However linking libdl.so to libdl.so.2 doesn't work.

@danmoseley
Copy link
Member

@henkmollema what version of .NET Core are you using? @qmfrederik 's change above would be in master, not released yet.

@henkmollema
Copy link
Contributor

@danmosemsft .NET Core 2.0.

@danmoseley
Copy link
Member

@qmfrederik any thoughts?

@qmfrederik
Copy link
Contributor Author

I submitted PR dotnet/corefx#25134 but this was rejected in favor or a more generic API.
That API is being discussed in #20635 and is ready for review.
Once that API is approved we can implement it and consume it from System.Drawing.Common to properly fix this issue.

@qmfrederik
Copy link
Contributor Author

@henkmollema In the meanwhile, if you're on Ubuntu or Debian, you can try to install the libc6-dev package to get libdl.so.

@henkmollema
Copy link
Contributor

For now I fall back to using CoreCompat.System.Drawing.V2 and running apt-get install -y libgdiplus in my Docker file. Might try installing libc6-dev some time.

@PeterHagen
Copy link

Unfortunately System.Drawing.Common 4.5.0-preview1 is used in a referenced package. In this case iTextSharp.LGPLv2.Core 1.4.2, which I accidentally updated. I run the code in Docker with the microsoft/aspnetcore:2.0.5 image. This results in the same message:

Exception: System.TypeInitializationException: The type initializer for 'Gdip' threw an exception. ---> System.DllNotFoundException: Unable to load DLL 'libdl': The specified module or one of its dependencies could not be found.
 (Exception from HRESULT: 0x8007007E)
   at Interop.Libdl.dlopen(String fileName, Int32 flag)
   at System.Drawing.SafeNativeMethods.Gdip.LoadNativeLibrary()
   at System.Drawing.SafeNativeMethods.Gdip..cctor()
   --- End of inner exception stack trace ---
   at System.Drawing.SafeNativeMethods.Gdip.GdipCreateBitmapFromScan0(Int32 width, Int32 height, Int32 stride, PixelFormat format, IntPtr scan0, IntPtr& bmp)
   at System.Drawing.Bitmap..ctor(Int32 width, Int32 height, PixelFormat format)
   at WillowMedia.Common.Pdf.Barcode.BarcodeStamper.CreateCode(MemoryStream ms, Object model)
  ...

@qmfrederik
Copy link
Contributor Author

@PeterHagen Did you install libgdiplus and libc6-dev in your container?

@PeterHagen
Copy link

@qmfrederik yes, both of them

@qmfrederik
Copy link
Contributor Author

Can you check whether the file /usr/lib/x86_64-linux-gnu/libdl.so exists inside your container? If it still fails, you can try setting LD_LIBRARY_PATH to $LD_LIBRARY_PATH:/usr/lib/x86_64-linux-gnu but that should be included already.

If that still fails, can you set the LD_DEBUG environment variable to libs in your Dockerfile, restart your container, and share the output?

@PeterHagen
Copy link

I'm sorry, with the libc6-dev added, it does work now. Pushing the correct Dockerfile seems to be an issue on a day like this. Thanks for the comment. I tested it on a local and the production Docker environment

@safern
Copy link
Member

safern commented Mar 16, 2018

Moving to future since it depends on API: https://github.com/dotnet/corefx/issues/17135 being added.

@ghost
Copy link

ghost commented Mar 17, 2018

On debian i did ln -s /lib/x86_64-linux-gnu/libdl.so.2 /lib/x86_64-linux-gnu/libdl.so.
Should we add various common names using the current technique https://github.com/dotnet/corefx/pull/27208/files#diff-557c4f4a6ff1d5ead7c96e76cf005001R46 for libdl? In post 2.1, once #20635 is landed we can update this pattern for all dependency libs.

@qmfrederik
Copy link
Contributor Author

The problem with that technique is that it uses dlopen to probe for different filenames for libssl. Here, you're probing for dlopen itself so that doesn't work.

@emeryao
Copy link

emeryao commented May 7, 2018

in my case of Docker container with base image microsoft/aspnetcore:2.0.5
after running these commands the error disappear

$ ln -s /lib/x86_64-linux-gnu/libdl.so.2 /lib/x86_64-linux-gnu/libdl.so
$ apt update
$ apt install libgdiplus
$ ln -s /usr/lib/libgdiplus.so /lib/x86_64-linux-gnu/libgdiplus.so

@sherlock1982
Copy link

It looks like 4.5.0 can't be used out of the box because of this.
Installing libc6-dev is an ugly workaround. Making symbolic links will conflict when libc6-dev is installed.

@qmfrederik
Copy link
Contributor Author

@sherlock1982 You are right, it's a bit of an ugly workaround. The structural fix is in https://github.com/dotnet/corefx/issues/17135. You can perhaps help accelerate a fix for that by upvoting the issue 😄 .

@rezvanf
Copy link

rezvanf commented Jul 24, 2018

I am seeing this issue in running in OpenShift Containers... I have followed the instructions in this issue, my docker file now looks like this

RUN yum -y install
..
libc6-dev
libgdiplus
..

&& yum clean all

RUN ln -s /usr/lib64/libdl.so.2 /usr/lib64/libdl.so

RUN ln -s /usr/lib64/libgdiplus.so.0.0.0 /usr/lib64/libgdiplus.so

The original error of "Unable to load DLL 'libdl…" disappears but now when I attempt to run my code I get

/docker-entrypoint.sh: line 3: 7 segmentation fault (core dumped) dotnet apihost.dll

The underlying OSis RHEL 7.4 (maipo) and using ASP .NET Core 2.1

Note this error happens in 1 in every 100 attempts to execute the offending code.

Any advice please

@safern
Copy link
Member

safern commented Jul 24, 2018

/docker-entrypoint.sh: line 3: 7 segmentation fault (core dumped) dotnet apihost.dll

This doesn't seem like an error in System.Drawing.Common itself. Could you please confirm if this happens in a single Console App, or if you could share a stack trace from the dump that would be super useful as well.

@rezvanf
Copy link

rezvanf commented Jul 24, 2018

what is the recommended way to get a copy of the dump, I am not sure how I can get this because the container keeps crashing.

Just to also confirm the same code works on a windows running with IIS,

@fasmat
Copy link

fasmat commented Jul 30, 2018

I have the same issue, with the docker image provided by microsoft I'm getting exceptions in my code:

System.DllNotFoundException : Unable to load shared library 'libdl' or one of its dependencies. In order to help diagnose loading problems, consider setting the LD_DEBUG environment variable: liblibdl: cannot open shared object file: No such file or directory

So far the only workaround I've found is to extend from the provided docker-file and add libc6-dev with apt-get:

FROM microsoft/dotnet:2.1-sdk

# Dependencies for libraries
RUN apt-get update \
    && apt-get install -y --no-install-recommends libc6-dev

If I run my code in a container build from this dockerfile the exception is not thrown.

Alex2357 referenced this issue in Alex2357/una-ui-tests Feb 26, 2019
Error during fail reporting: System.TypeInitializationException: The type initializer for 'Gdip' threw an exception. ---> System.DllNotFoundException: Unable to load shared library 'libdl' or one of its dependencies. In order to help diagnose loading problems, consider setting the LD_DEBUG environment

problem as described here https://github.com/dotnet/corefx/issues/25102
av2012 referenced this issue in av2012/una-ui-tests Feb 26, 2019
Error during fail reporting: System.TypeInitializationException: The type initializer for 'Gdip' threw an exception. ---> System.DllNotFoundException: Unable to load shared library 'libdl' or one of its dependencies. In order to help diagnose loading problems, consider setting the LD_DEBUG environment

problem as described here https://github.com/dotnet/corefx/issues/25102
@joalcava
Copy link

joalcava commented Sep 2, 2019

Still facing this issue using dotnet core 2.2.4, and debian image in Azure App Service

@safern
Copy link
Member

safern commented Sep 3, 2019

I suspect this might be solved when targeting .NET Core 3.0 and using the latest System.Drawing.Common package in NuGet since we're no longer loading libgdiplus directly with dlopen but instead using the new Native Library Loader. Will try it out and close if fixed.

@safern safern self-assigned this Sep 3, 2019
@savanbthakkar
Copy link

@safern , Did you try it out? Did that work with .Net Core 3.0?

@joalcava
Copy link

@savanbthakkar I've migrated my application to .Net Core 3.0 and the problem is solved, but you have to have installed libgdiplus and libc6-dev anyway.

@savanbthakkar
Copy link

@joalcava Have you used System.Drawing in a Lambda function?

@terryfu68
Copy link

@joalcava Have you used System.Drawing in a Lambda function?

I have used in a Lambda function,I have the same errors

@Alword
Copy link

Alword commented Nov 30, 2019

.NET Core 3.0
System.Drawing.Common from NuGet
An error on CentOS 7.
after The type initializer for 'Gdip' threw an exception.

An unhandled exception was thrown by the application.
Message: Parameter is not valid.
Source: System.Drawing.Common
StackTrace:    at System.Drawing.SafeNativeMethods.Gdip.CheckStatus(Int32 status)
   at System.Drawing.Bitmap.SetResolution(Single xDpi, Single yDpi)
   at ImageProcessor.Common.Extensions.ImageExtensions.Copy(Image source, AnimationProcessMode animationProcessMode, PixelFormat format, Boolean preserveExifData)
   at ImageProcessor.ImageFactory.Load(Image image)

UPD This was caused when using an image processor NuGet package from a plug-in with WebP. I think this should not work in .net core. Sorry for the mentions

@msftgits msftgits transferred this issue from dotnet/corefx Jan 31, 2020
@msftgits msftgits added this to the Future milestone Jan 31, 2020
@jkotas
Copy link
Member

jkotas commented Jan 31, 2020

Fixed in .NET Core 3.0

@jkotas jkotas closed this as completed Jan 31, 2020
@ghost ghost locked as resolved and limited conversation to collaborators Dec 19, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-System.Drawing bug os-linux Linux OS (any supported distro)
Projects
None yet
Development

No branches or pull requests