SIGSEGV из spawn child_process в функции AWS Lambda

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

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

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

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

Обновление от 25.04.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  

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

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

7 голосов | спросил Chris Paton 20 PMpWed, 20 Apr 2016 19:35:33 +030035Wednesday 2016, 19:35:33

3 ответа


0

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

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

ответил Chris Paton 30 PMpSat, 30 Apr 2016 21:41:26 +030041Saturday 2016, 21:41:26
0

Prolegomenom:

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

Ответ

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

Заключение

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

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

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

ответил Héctor Valverde Pareja 25 PMpMon, 25 Apr 2016 16:56:23 +030056Monday 2016, 16:56:23
0

Попробуй это. Пусть ваша функция 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» для интерпретации.]

ответил Jeff Learman 28 PMpThu, 28 Apr 2016 21:51:43 +030051Thursday 2016, 21:51:43

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132