首页 > 技术文章 > System.DllNotFoundException: Unable to load shared library 'libdl' or one of its dependencies

lihan829 2019-07-09 23:00 原文

centos docker .net core 2.2报错:

[2019-07-09 14:11:21 Error] Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware
An unhandled exception has occurred while executing the request.
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 variable: liblibdl: cannot open shared object file: No such file or directory
   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, Int32 format, HandleRef scan0, IntPtr& bitmap)
   at System.Drawing.Bitmap..ctor(Int32 width, Int32 height, PixelFormat format)
   at Oshop.Services.Util.CaptchaUtil.GetCaptcha(String code) in /app/Oshop.Services/Util/CaptchaUtil.cs:line 32
   at curseIS.STS.Identity.Quickstart.Account.AccountController.GetCaptcha() in /app/base/curseIS.STS.Identity/Quickstart/Account/AccountController.cs:line 118
   at lambda_method(Closure , Object )
   at Microsoft.Extensions.Internal.ObjectMethodExecutorAwaitable.Awaiter.GetResult()
   at Microsoft.AspNetCore.Mvc.Internal.ActionMethodExecutor.TaskOfActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
   at System.Threading.Tasks.ValueTask`1.get_Result()
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeActionMethodAsync()
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeNextActionFilterAsync()
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Rethrow(ActionExecutedContext context)
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeInnerFilterAsync()
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeNextResourceFilter()
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Rethrow(ResourceExecutedContext context)
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeFilterPipelineAsync()
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeAsync()
   at Microsoft.AspNetCore.Routing.EndpointMiddleware.Invoke(HttpContext httpContext)
   at Microsoft.AspNetCore.Routing.EndpointRoutingMiddleware.Invoke(HttpContext httpContext)
   at Microsoft.AspNetCore.Localization.RequestLocalizationMiddleware.Invoke(HttpContext context)
   at IdentityServer4.Hosting.IdentityServerMiddleware.Invoke(HttpContext context, IEndpointRouter router, IUserSession session, IEventService events)
   at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
   at IdentityServer4.Hosting.BaseUrlMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.Invoke(HttpContext context)

项目使用了.net core下的Bitmap, 用来生成用户注册验证码, 使用的是如下dll:

using System.Drawing;
using System.Drawing.Imaging;

在win10上确实正常使用没有问题, 在centos上用linux部署之后, 就一直报上面的错误.

有参考这些资料:

https://www.cnblogs.com/stulzq/p/10172550.html

https://www.cnblogs.com/stulzq/p/9339250.html

按步骤改了apt-get的源:

但是这样改后会报别的错:

The repository 'http://mirrors.163.com/debian jessie-backports Release' does not have a Release file

然后才在这发现:

debian 8.几才用 jessie, 而.net core 2.2(我使用的版本), 使用的docker image是debian 9.9, 这样查看:

radhat或centos存在:/etc/redhat-release 这个文件
debian或ubuntu 存在 /etc/debian_version 这个文件
Slackware存在 /etc/slackware_version 这个文件
ubuntu存在 /etc/lsb-release 这个文件

所以应该用stretch这块的源:

deb http://mirrors.aliyun.com/debian/ stretch main non-free contrib
deb-src http://mirrors.aliyun.com/debian/ stretch main non-free contrib
deb http://mirrors.aliyun.com/debian-security stretch/updates main
deb-src http://mirrors.aliyun.com/debian-security stretch/updates main
deb http://mirrors.aliyun.com/debian/ stretch-updates main non-free contrib
deb-src http://mirrors.aliyun.com/debian/ stretch-updates main non-free contrib
deb http://mirrors.aliyun.com/debian/ stretch-backports main non-free contrib
deb-src http://mirrors.aliyun.com/debian/ stretch-backports main non-free contrib

不管怎样, 改成这个源之后, 确实就可以了, 正常build 镜像, 正常run起来, 正常的生成了验证码图片, 惟一的别的事, 就是, 同一份代码, 跑在win10上和linux docker里, 生成的图片字体风格有差异:

centos docker:

win10:     

可以看出字母 y 还是有些不一样, 不过, 这些小细节就不管那么多了.

 

推荐阅读