Я пытаюсь создать синхронный дочерний процесс (для запуска ffprobe) в функции AWS Lambda, но он почти мгновенно умирает (200 мс) с сигналом SIGSEGV.

Насколько я понимаю, ошибка сегментации заключается в том, что это процесс, который пытается получить доступ к памяти, к которой он не имеет доступа. Я попытался увеличить объем памяти до 1024 МБ (я использовал 128 МБ, поскольку при каждом выполнении используется только около 56 МБ), но это ничего не изменило.

Мне известно, что я не единственный, у кого возникла эта проблема: https: //forums.aws.amazon.com/thread.jspa?threadID=229397

Кто-нибудь знает, как это решить?

Обновление от 25 апреля 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  

Я использую бессерверную структуру для детализации и развертывания моего кода.

ПРИМЕЧАНИЕ. Я пробовал запустить этот двоичный файл на экземпляре ami-bff32ccc на EC2 (http://docs.aws.amazon.com/lambda/latest/dg/current-supported-versions.html), и это работает. Так что это должно быть то, что я делаю (как я выполняю ffprobe).

9
Chris Paton 20 Апр 2016 в 19:35

3 ответа

Лучший ответ

Версия ffprobe, которую я использовал, я получила с сайта Джона Ван Сикла, а пока он работал, когда я запускал его на инстансах Amazon Linux EC2, он не работал на AWS Lambda.

Следуя совету Джеффа Лирмана, я создал свою собственную версию, используя этот замечательный сценарий на текущем версия среды, используемой AWS Lambda , как описано здесь . Затем я развернул его со своей функцией Lambda, и он сработал в первый раз! :)

3
Chris Paton 30 Апр 2016 в 18:41

Попробуй это. Пусть ваша функция Lambda создаст оболочку bash, которая делает это:

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

Затем проверьте наличие файла с именем «/ tmp / core» и, если он существует, скопируйте его в корзину S3 (или что-то еще) и используйте gdb для его анализа в вашей системе разработки или хосте EC2. Я сам не проверял это, но знаю, что по умолчанию ulimit будет равен нулю, а файлы ядра будут сбрасываться в текущий каталог. Обратите внимание, что эти данные могут быть изменены без предварительного уведомления (и, если мне не изменяет память, недавно изменились).

Конечно, "cd" может произойти в лямбда-функции. Если nodejs предоставляет способ установить ulimit, это может произойти и там.

[Изменить: правильный шаблон - /tmp/core.%e.%p, см. "Man core" для интерпретации.]

3
Jeff Learman 29 Апр 2016 в 01:26

Пролегоменом:

Мне интересно, следует ли мне опубликовать следующее в качестве комментария или в качестве ответа. Причина, по которой я задаюсь вопросом, это потому, что я немного не понимаю, о чем вы на самом деле спрашиваете. При первом чтении становится очевидно, что вы хотите устранить ошибку, но вы не помогаете нам контекстуализировать ее, например, показывая нам свой код. Кроме того, проблема, обсуждаемая в теме, которую вы опубликовали, связана с ней, но автор задает более общий вопрос: « Как отладить проблему », и у меня есть на это ответ:

< Сильный > Ответ :

Журналы Lambda доступны в CloudWatch. SIGSEGV возникает, когда вы пытаетесь получить доступ к тому, что вам не разрешено (как вы указали), это может быть потому, что память заблокирована другим процессом, а иногда потому, что у вас нет разрешений на то, к чему вы получаете доступ, или вы можете получить доступ к чему-либо, чтобы что-то было установлено как nil, которое позже будет использоваться как адрес памяти и т. д. Вы можете добавить операторы журнала в свой код, чтобы исследовать, что на самом деле происходит там, в вашей функции, и читать такие послесловия журналов с помощью CloudWatch: http://docs.aws.amazon.com/lambda/latest/dg/ monitoring-functions-logs.html

Заключение :

Ваш вопрос не может быть решен, поскольку вы не полностью объясняете проблему, но, по крайней мере, я указываю вам, как ее исследовать:

  1. Добавление журналов отладки в ваш код
  2. Отслеживайте журналы с CloudWatch

Если вам нужна дополнительная помощь, вы можете опубликовать свой код.

2
Héctor Valverde Pareja 25 Апр 2016 в 14:23