AWS Lambda R运行时分段错误

Eri*_*ric 3 r amazon-web-services aws-lambda

我正在尝试创建一个运行时层,以使用其新的运行时API将R用作lambda函数的运行时

为此,我创建了一个包含R所需的所有依赖项的层,然后创建了一个包含R本身的第二层。我使用运行lambda的同一Amazon AMI构建了这些层。我通过压缩各层,创建一个新实例,然后将各层下载并解压缩到该新实例中来测试我的构建(将所有内容放入/ opt,这也恰好是我在构建R及其依赖项时在其中安装的地方) 。我使用了最少资源(2个CPU,4GB RAM)的实例类型。据我了解,这应该非常接近lambda环境。

我有一个小的测试脚本(test.r),它只是将一条消息打印到stdout。这在测试环境中运行良好。这是脚本:

cat("hello from planet lambdar")
Run Code Online (Sandbox Code Playgroud)

这是在我的层的引导脚本中调用它的方式:

SCRIPT=$LAMBDA_TASK_ROOT/$(echo "$_HANDLER" | cut -d. -f1).r
  echo "About to run $SCRIPT"
  /opt/R/bin/Rscript $SCRIPT
Run Code Online (Sandbox Code Playgroud)

从下面的日志记录中可以明显看出,脚本的名称已正确发送和解析。我以前已经确认脚本test.r可以按预期方式放在/ var / task中。但是通过lambda运行此脚本会导致分段错误:

START RequestId: 2c1b8801-f903-11e8-a32d-796c039278f1 Version: $LATEST
About to run /var/task/test.r
/opt/bootstrap: line 18:    18 Segmentation fault      (core dumped) /opt/R/bin/Rscript $SCRIPT
Run Code Online (Sandbox Code Playgroud)

考虑到该过程在运行EC2实例的最小EC2实例上运行正常,该实例运行与lambda所使用的相同的Amazon AMI,并加载了与我为我的lambda函数添加的层创建的相同的工具和依赖项集,我该如何调试此分段错误?

Eri*_*ric 5

在这种情况下,事实证明,我过于积极地将链接到R可执行文件的共享库复制到我的层中。我把列出的所有东西都拿了

ldd /opt/R/lib/libR.so
Run Code Online (Sandbox Code Playgroud)

并将其复制到/ opt / lib

问题在于这些库中有许多已经在AMI中,并且它们在不同位置的存在会引起问题(也许与库缓存有关?)。

通过仅移动不在AMI中的两个库(但在我安装构建工具时添加了这些库,这些库当然不在Lambda环境中),该段错误就消失了。这两个库是:

/usr/lib64/libgfortran.so.3
/usr/lib64/libquadmath.so.0
Run Code Online (Sandbox Code Playgroud)

为了回答更深层的问题,即如何在Lambda环境中调试segfault,我在这里找到了灵感,并在bootstrap脚本中包含了类似的内容以打印核心转储的回溯信息:

gdb -q -n -ex bt -batch /opt/R/bin/Rscript /temp/core.N.XXXX
Run Code Online (Sandbox Code Playgroud)

凡core.N.XXXX是核心转储文件的名称(这可以通过将发现echo $(ls /tmp)在你的bootstrap脚本)。然后,cloudwatch日志将至少包含回溯中的一些提示。