无法加载DLL' libdl'在AWS Lambda

时间:2018-05-31 02:13:22

标签: c# aws-lambda .net-core-2.0

我们有一个缩略图生成器lambda函数,我试图更新到.NET Core 2.0,但在使用Microsoft的System.Drawing.Common NuGet包时遇到以下错误:

  

TypeInitializationException

     

' Gdip'的类型初始值设定项抛出一个例外。   在System.Drawing.SafeNativeMethods.Gdip.GdipCreateBitmapFromScan0(Int32 width,Int32 height,Int32 stride,Int32 format,HandleRef scan0,IntPtr& bitmap)   在System.Drawing.Bitmap..ctor(Int32宽度,Int32高度,PixelFormat格式)   在TestFailExample.Function.FunctionHandler(String输入,ILambdaContext上下文)中的C:\ work \ graphics \ TestFailExample \ Function.cs:第25行   在lambda_method(Closure,Stream,Stream,LambdaContextInternal)

引起的

  

DllNotFoundException

     

无法加载DLL' libdl':找不到指定的模块或其中一个依赖项。\ n(HRESULT异常:0x8007007E)   在Interop.Libdl.dlopen(String fileName,Int32标志)   在System.Drawing.SafeNativeMethods.Gdip.LoadNativeLibrary()   在System.Drawing.SafeNativeMethods.Gdip..cctor()

我已经看过this个问题,但没有解决方案。

重现问题的最低代码是:

public string FunctionHandler(string input, ILambdaContext context)
{
    using (var bmp = new Bitmap(100, 100))
    {
        return bmp.Width.ToString();
    }
}

只需创建一个.NET Core 2.0 Lambda函数项目,添加对System.Drawing.Common NuGet包的引用,并用上面的代码替换函数处理程序。将其放在AWS上并运行它以获取错误。我已经注意到,在您尝试实际使用它之前,引用该包并不会导致问题,但这可能归结为编译器优化。

我已将MCVE打包到项目中并将其上传到GitHub here,以简化人们重现问题所需的步骤。

我可以看到/lib64/libdl.so.2存在,但/lib64/libdl.so没有。由于符号链接似乎不可能(只读文件系统),我不知道如何解决这个问题。我已经尝试使用LD_LIBRARY_PATH环境变量,在/tmp中创建一个文件夹并将该文件符号化为该函数的第一件事。不幸的是,它似乎在这里寻找所有库,因此该功能根本不运行。我还尝试将LD_LIBRARY_PATH设置为/var/lang/lib:/lib64:/usr/lib64:/var/runtime:/var/runtime/lib:/var/task:/var/task/lib:/tmp,虽然我现在可以再次运行该功能,但这仍然没有帮助,我只是得到相同的Gdip错误。

我注意到/ var / task / lib已经包含在LD_LIBRARY_PATH中了,所以我尝试用我的函数打包libdl.so和libgdiplus.so,但这也失败了,这次说明了入口点GdiplusStartuplibdgiplus.so中找不到。这些文件不是来自Amazon Linux实例,因此我现在尝试安装Mono并从Amazon Linux实例获取它们。这没有帮助。

我已尝试使用CoreCompat drawing library,但这也会报告与libgdiplus.so有关的问题,即使我尝试将其与该函数捆绑在一起。

我已经在我自己的Linux实例上尝试过了,可以确认System.Drawing.Common有效。

是否有一些聪明的解决方案可以让我在AWS Lambda上使用System.Drawing.Common?有没有其他方法可以捏造我的lambda函数以使libdl工作?

4 个答案:

答案 0 :(得分:1)

我找到了一个对我有用的解决方案:

首先,我从项目中删除了System.Drawing.Common库,然后安装了可以找到here的库。它使用相同的类。

using System.Drawing
...
var bmp = new Bitmap(100,100);

最后,我安装了this其他库,其中包含在Linux和Lambda上使用绘图库的所有dll必要条件。通过执行此步骤,可以毫无问题地将代码上传到AWS。

答案 1 :(得分:1)

在运行dotnet core 2.1.500版本的Ubuntu 18服务器上上传应用程序后,我遇到了同样的问题。我使用MichaelSimons的建议,通过此解决方案https://github.com/dotnet/dotnet-docker/issues/618解决了这个问题。

我跑了

#sudo apt-get update
#sudo apt-get install -y --allow-unauthenticated \
        libc6-dev \
        libgdiplus \
        libx11-dev \ 
#sudo rm -rf /var/lib/apt/lists/*

这解决了问题。

答案 2 :(得分:0)

对于.NET Core Lambda中的图像处理,我使用SixLabors.ImageSharp

这是我在最近的AWS re:Invent演讲中使用的代码,它在进行图像处理时记录了日志:

var imageBuffer = new MemoryStream();

var resizeOptions = new ResizeOptions
{
    Size = new SixLabors.Primitives.Size { Width = this.TileSize, Height = this.TileSize},
    Mode = ResizeMode.Stretch
};
image.Mutate(x => x.Resize(resizeOptions));
image.Save(imageBuffer, new SixLabors.ImageSharp.Formats.Jpeg.JpegEncoder());

imageBuffer.Position = 0;

答案 3 :(得分:0)

如果使用centOS,则下面的命令会有所帮助。

  • sudo yum安装libgdiplus