AWS Lambda函数中spawn child_process的SIGSEGV

我试图在AWS Lambda函数中产生一个同步subprocess(用于运行ffprobe),但它几乎立即(200毫秒)通过SIGSEGV信号死亡。

我对分段错误的理解是,它是一个尝试访问不允许访问的内存的进程。 我试图增加内存到1024MB(我使用128MB,因为每个执行只使用约56MB),但这并没有改变任何东西。

我知道我不是唯一有此问题的人: https : //forums.aws.amazon.com/thread.jspa?threadID=229397

任何人都知道如何解决此问题?

更新25/4/2016

为了清楚起见,我正在运行的代码是:

import { spawnSync } from 'child_process'; exports.handler = (event, context) => { process.env.PATH = `${process.env.PATH}:${process.env.LAMBDA_TASK_ROOT}`; const ffprobe = './ffprobe'; const bucket = event.Records[0].s3.bucket.name; const key = event.Records[0].s3.object.key; console.log(`bucket: ${bucket}`); console.log(`key: ${key}`); const url = 'http://my-clip-url.com'; // An s3 presigned url. if (!url) { throw new Error('Clip does not exist.'); } const command = `-show_format -show_streams -print_format json ${url}`; try { const child = spawnSync(ffprobe, command.split(' ')); console.log(`stdout: ${child.stdout.toString()}`) console.log(`stderr: ${child.stderr.toString()}`) console.log(`status: ${child.status.toString()}`) console.log(`signal: ${child.signal.toString()}`) } catch (exception) { console.log(`Process crashed! Error: ${exception}`); } }; 

其输出是:

 START RequestId: 6d72847 Version: $LATEST 2016-04-25T19:32:26.154Z 6d72847 stdout: 2016-04-25T19:32:26.155Z 6d72847 stderr: 2016-04-25T19:32:26.155Z 6d72847 status: 0 2016-04-25T19:32:26.155Z 6d72847 signal: SIGSEGV END RequestId: 6d72847 REPORT RequestId: 6d72847 Duration: 4151.10 ms Billed Duration: 4200 ms Memory Size: 256 MB Max Memory Used: 84 MB 

我正在使用无服务器框架babelify和部署我的代码。

注意:我已经尝试在EC2上的ami-bff32ccc实例上运行这个二进制文件( http://docs.aws.amazon.com/lambda/latest/dg/current-supported-versions.html ),它工作。 所以它一定是我在做什么(我如何执行ffprobe)。

       

网上收集的解决方案 "AWS Lambda函数中spawn child_process的SIGSEGV"

Prolegomenom:

我想知道是否应该发表以下评论或作为答案。 我想知道这是因为我对你实际要求的东西有点困惑。 在第一次阅读时,显然你想要克服这个错误,但是你并没有帮助我们通过例如向你展示你的代码来描述它。 此外,在你发布的post中讨论的问题是相关的,但作者正在问一个更普遍的问题:“ 如何debugging问题 ”,我有一个答案:

Lambda日志在CloudWatch中可用。 当你尝试访问你不允许的东西时(正如你所指出的),SIGSEGV是由于内存被另一个进程locking,有时是因为你没有权限访问你所访问的东西,访问的东西,所以设置为零,以后用作内存地址,等等。您可以添加日志语句到您的代码,以调查您的函数中实际发生的事情,并使用CloudWatch阅读这些日志后缀: http:// docs .aws.amazon.com /λ/最新/ DG /监视function,logs.html

结论

你的问题不能解决,因为你没有完全解释这个问题,但至less我指着你如何去调查它:

  1. 将debugging日志添加到您的代码
  2. 使用CloudWatch跟踪日志

如果你需要更多的帮助,你可以发布你的代码。

尝试这个。 让你的Lambda函数产生一个bash shell来完成这个工作:

ulimit -c unlimited cd /tmp $LAMBDA_TASK_ROOT/ffprobe ...

然后检查名为“/ tmp / core”的文件,如果存在,将其复制到S3存储桶(或其他),然后使用gdb在开发系统或EC2主机上进行分析。 我自己没有validation过,但我知道,默认情况下,ulimit将为零,核心文件将转储到当前目录。 请注意,这些细节如有更改,恕不另行通知(如果内存服务于我,最近已更改。)

当然,“cd”可能发生在lambda函数中。 如果nodejs提供了设置ulimit的方法,那么也可能发生在那里。

[编辑:正确的模式是/tmp/core.%e.%p,请参阅“man core”来解释。]

我使用的ffprobe版本来自John Van Sickle的网站 ,当我在Amazon Linux EC2实例上运行它时,它的工作原理就不适用于AWS Lambda。

按照Jeff Learman的build议,我在这里描述的AWS Lambda使用的当前版本的环境中使用这个美妙的脚本构build了自己的版本。 然后我用Lambda函数部署它,它第一次工作! 🙂