ES /docs

Process killed by signal SIGABRT (code: null)

RCA: Process killed by signal SIGABRT (code: null)

Error Log#

Datadog Logs

text
Process killed by signal SIGABRT (code: null)

Impact#

  • Service: cupixworks-capture-preprocessor-agent
  • Team: walmart
  • 발생 횟수: 2
  • 최초 발생: 2026-04-06T22:01:03.182Z
  • 최근 발생: 2026-04-07T06:18:30.139Z

Root Cause Summary#

capture-preprocessor-agent의 child process에서 실행되는 네이티브 C++ 라이브러리(scenemapperutils / PreprocessorApi)가 특정 비디오 파일(.insv 등)을 처리하는 과정에서 내부적으로 abort()를 호출하여 SIGABRT 신호로 child process가 종료됩니다. 두 번째 발생 사례에서는 capture 676143의 video 636431 (636431.insv)에 대해 ffprobe도 실패한 것이 확인되며, 이 비디오 파일이 손상되었거나 네이티브 라이브러리가 처리할 수 없는 형식이었을 가능성이 높습니다. child process가 비정상 종료되면 ChildProcessManager가 pending promise를 reject하고, BaseService에서 "undefined response" 에러로 처리합니다.

Technical Analysis#

Code Path#

  • Entry point: preprocessor-service.ts:93 (run 메서드) — SQS 메시지 수신 후 capture 전처리 시작
  • preprocessor-service.ts:130this.preprocessorManager.initialize()로 child process 시작 및 네이티브 라이브러리 로드
  • preprocessor-service.ts:135setVideoMetaData()에서 ffprobe로 비디오 메타데이터 추출 시도
typescript
// preprocessor-service.ts:605-629
private setVideoMetaData = (cpCapture: CPCapture): Promise<void> => new Promise(resolve => {
    logger.debug('PreprocessorService::setVideoMetaData | begin');
    if (cpCapture.cpVideos == undefined || cpCapture.cpVideos.length < 1) {
        logger.warn('PreprocessorService::setVideoMetaData | end - not found video');
        return resolve();
    }

    let completeCount = 0;
    for (let index = 0; index < cpCapture.cpVideos.length; index++) {
        const cpVideo = cpCapture.cpVideos[index];
        if (cpVideo.path == undefined) continue;

        FFMPEG.ffprobe(cpVideo.path, (err, data) => {
            if (err) {
                logger.warn('PreprocessorService::setVideoMetaData | failed to ffprobe - video id: %d, path: %s', cpVideo.id, cpVideo.path);
            } else {
                cpVideo.setMetaOriginalData(data);
            }
            // ...
        });
    }
});
  • preprocessor-service.ts:145checkSupportedVideo()에서 네이티브 라이브러리의 is_supported_video() 호출
  • preprocessor-service.ts:149runPreprocessor()에서 네이티브 라이브러리의 process() 호출
typescript
// preprocessor.process.ts:255-289
private async execute(params: any): Promise<any> {
    // ...
    const PreprocessorApi = require(this.libPath);
    const Preprocessor = new PreprocessorApi.scenemapperutils();
    // ...
    videoInputs.forEach(it => {
        Preprocessor.append_timelapse_video_filepath(it.inputFile, it.name, it.outputDir);
    });
    // ...
    Preprocessor.process();  // 네이티브 C++ 코드 실행 — 여기서 SIGABRT 발생 가능
    // ...
}
  • Failure point: child-process.manager.ts:107-119 — child process가 SIGABRT로 종료되면 close 이벤트 발생
typescript
// child-process.manager.ts:107-119
this.process.on('close', (code: number | null, signal: string | null) => {
    logger.error('ChildProcessManager::setupEventHandlers | Child process closed', {
        code,
        signal
    });

    const errorMsg = signal
        ? `Process killed by signal ${signal} (code: ${code})`
        : `Process exited with code ${code}`;

    this.rejectAllPending(new Error(errorMsg));
    this.process = undefined;
    this.emit('close', code, signal);
});
  • 에러 전파: base-service.ts:250-252getApiErrorToDeleteMessage에서 response가 없으므로 "undefined response" 반환
typescript
// base-service.ts:250-252
if (response == undefined) {
    logger.warn('BaseService::getApiErrorToDeleteMessage | undefined response', error);
    return 'undefined response';
}

기대 동작: 네이티브 라이브러리가 비디오 파일 처리 중 에러를 발견하면 예외를 throw하여 Node.js 측에서 graceful하게 처리. 실제 동작: 네이티브 라이브러리가 abort()를 호출하여 child process 자체가 SIGABRT로 비정상 종료. Node.js 에러 핸들링 우회됨.

Log Evidence#

사용한 Datadog 쿼리:

text
service:cupixworks-capture-preprocessor-agent status:error
text
service:cupixworks-capture-preprocessor-agent (676143 OR "SIGABRT" OR "checkSupportedVideo" OR "runPreprocessor" OR "setVideoMetaData" OR "ffprobe")

두 번째 발생 사례 (2026-04-07 15:18:30 KST) 타임라인:

text
15:18:24 [warn]  PreprocessorService::setVideoMetaData | failed to ffprobe - video id: 636431, path: /tmp/workspace/676143/videos/636431/original/636431.insv
15:18:24 [info]  PreprocessorService::setVideoImageMatchData | begin - capture_id: 676143
15:18:30 [error] ChildProcessManager::setupEventHandlers | Child process exited
15:18:30 [error] ChildProcessManager::setupEventHandlers | Child process closed
15:18:30 [error] Process killed by signal SIGABRT (code: null)
15:18:30 [warn]  Process killed by signal SIGABRT (code: null)
15:18:30 [info]  AwsQueueManager::deleteMessage | begin - queue url: ...cupix-capture-preprocessor-agent-production
15:18:31 [error] BaseService::handlingMessageErrors | Error and message object - {"error":"undefined response","sqsMessage":{"MessageId":"cb91873b-c37d-4be0-b65d-e54e9636229b","Attributes":{"ApproximateReceiveCount":"1"}}}

첫 번째 발생 사례 (2026-04-07 07:01:03 KST):

text
07:01:03 [error] ChildProcessManager::setupEventHandlers | Child process exited
07:01:03 [error] ChildProcessManager::setupEventHandlers | Child process closed
07:01:03 [error] Process killed by signal SIGABRT (code: null)
07:01:04 [error] BaseService::handlingMessageErrors | Error and message object - {"error":"undefined response","sqsMessage":{"MessageId":"70561a9b-9b24-4ecc-8e47-18b64f1a78bc","Attributes":{"ApproximateReceiveCount":"1"}}}

주요 패턴:

  • 두 번째 발생에서 ffprobe.insv 파일(Insta360 비디오 포맷)에 대해 실패 — 비디오 파일 자체에 문제가 있음을 시사
  • SIGABRT 직전에 별도의 네이티브 라이브러리 에러 로그가 없음 — 네이티브 코드가 에러를 Node.js로 전파하지 않고 즉시 abort
  • ApproximateReceiveCount: 1 — 재시도 없이 첫 시도에서 실패

7일간 동일 패턴의 추가 발생 확인 (2026-04-04):

text
2026-04-04 08:55:22 [error] Process killed by signal SIGABRT (code: null)
2026-04-04 08:55:22 [error] ChildProcessManager::setupEventHandlers | Child process closed
2026-04-04 08:55:22 [error] ChildProcessManager::setupEventHandlers | Child process exited
2026-04-04 08:55:24 [error] BaseService::handlingMessageErrors | Error and message object - {"error":"undefined response",...}

Fix Recommendation#

즉시 조치 (Critical)#

  • preprocessor.process.ts — 네이티브 라이브러리 호출(PreprocessorApi.extract_video_meta(), PreprocessorApi.process() 등) 전에 비디오 파일 유효성 사전 검증 추가. ffprobe 실패한 비디오는 네이티브 라이브러리에 전달하지 않고 에러로 처리하는 가드 로직 필요.
  • preprocessor-service.ts:605-629 (setVideoMetaData) — ffprobe 실패 시 해당 비디오를 이후 checkSupportedVideo/runPreprocessor 단계에서 제외하거나, 에러 상태를 설정하여 네이티브 라이브러리가 손상된 파일을 처리하지 않도록 차단.

단기 개선 (1주 이내)#

  • ChildProcessManager에 SIGABRT로 인한 child process 종료 시 특화된 에러 코드 설정 로직 추가. 현재 "undefined response"라는 generic 에러로 처리되어 원인 파악이 어려움. ErrorCode.ScenemapperUtils.NativeCrash 같은 전용 에러 코드를 도입하여 job 상태에 명확한 실패 원인 기록.
  • child process의 stdioMode'pipe'로 설정하여 네이티브 라이브러리의 stderr 출력을 캡처. SIGABRT 직전 네이티브 코드가 출력하는 에러 메시지(assertion failure 등)를 로그에 기록하면 디버깅에 도움.

장기 개선 (재발 방지)#

  • 네이티브 scenemapperutils 라이브러리 팀과 협력하여, abort() 대신 예외를 throw하거나 에러 코드를 반환하도록 수정. 네이티브 라이브러리가 비정상 입력에 대해 graceful하게 실패하는 것이 근본적 해결.
  • child process에 executeTimeoutMs 설정을 적용하여, 네이티브 코드가 무한 루프에 빠지거나 응답 없이 멈추는 경우에도 타임아웃으로 복구 가능하도록 보장.

Monitoring#

  • 추가할 메트릭: child process의 exit signal별 카운트 (SIGABRT, SIGKILL, SIGSEGV 등)
  • Datadog 알림 쿼리:
text
service:cupixworks-capture-preprocessor-agent status:error "Process killed by signal SIGABRT"
  • ffprobe 실패 빈도를 추적하는 메트릭 추가:
text
service:cupixworks-capture-preprocessor-agent "failed to ffprobe"

Risk Assessment#

  • Risk level: medium
  • 예상 복잡도: standard