Process killed by signal SIGABRT (code: null)
RCA: Process killed by signal SIGABRT (code: null)
Error Log#
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:130—this.preprocessorManager.initialize()로 child process 시작 및 네이티브 라이브러리 로드preprocessor-service.ts:135—setVideoMetaData()에서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:145—checkSupportedVideo()에서 네이티브 라이브러리의is_supported_video()호출preprocessor-service.ts:149—runPreprocessor()에서 네이티브 라이브러리의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-252—getApiErrorToDeleteMessage에서 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