ES /docs

[77502.92] | Received fatal signal: SIGABRT(6) PID: 70

RCA: SIGABRT in SiteInsights::removeOutBoundPointCloud()

Overview#

What Happened#

2026-04-22 03:02:27 UTC에 cupixworks-sitetrack-instance 서비스에서 BIM Validator 처리 중 네이티브 C++ 라이브러리(libbimalgorithm.so)가 SiteInsights::removeOutBoundPointCloud() 함수 실행 직후 SIGABRT 시그널로 크래시했다. ellisdon 팀의 sitetrack job 1028208(sitetrack ID 16744)이 240,446개의 bimProgress 객체를 처리하던 중 발생한 단일 건의 인시던트이다.

Quick Facts#

Field Value
exception.class SIGABRT(6)
exception.message Received fatal signal: SIGABRT(6) PID: 70
top_frame libbimalgorithm.so:SiteInsights::removeOutBoundPointCloud()
runtime Node.js + native C++ addon (@cupix-compute/site-track v1.6.12)
deploy 7c39cb64e31161e86f3dca596aae6bfe2b9ffe83 (built 20260408_025319)
env production, us-west-2

Affected Teams#

Team / Domain Error Count Impact
ellisdon (ID: 268) 1 sitetrack job 1028208 실패, BIM validation 미완료

Timeline#

  1. 02:59:52 UTC -- sitetrack instance 시작, job 1028208 로드 (sitetrack 16744)
  2. 03:00:34 UTC -- BimValidator::process() 시작, processSiteInsight() 진입
  3. 03:00:36 UTC -- 240,446개 bimProgress 객체 로드
  4. 03:00:38 UTC -- Invalid Geometry/OTG header 경고 다수 발생 (Forge URN 데이터 손상)
  5. 03:01:58 UTC -- runPointValidator() 시작, point cloud 정제 작업 수행
  6. 03:02:27.151 UTC -- prepareBimMeshAndPointCloud() 시작 (220,106 BIM request objects)
  7. 03:02:27.331 UTC -- filterBimMeshesByDistanceFromPano() 0ms 만에 완료 (빈 결과 가능성)
  8. 03:02:27.332 UTC -- removeOutBoundPointCloud() 시작
  9. 03:02:27.333 UTC -- SIGABRT 크래시 (시작 1ms 이내)
  10. 03:06:42 UTC -- Node.js parent process가 child process 종료 감지

Error Log#

Datadog Logs

text
[77502.92] | Received fatal signal: SIGABRT(6)	PID: 70

***** SIGNAL SIGABRT(6)

*******	STACKDUMP *******
	stack dump [1]  /tmp/agent/dist/node_modules/@cupix-compute/site-track/libg3log.so+0x15d0b
	stack dump [2]  /usr/lib/x86_64-linux-gnu/libc.so.6+0x42520
	stack dump [3]  /usr/lib/x86_64-linux-gnu/libc.so.6pthread_kill+0x12c
	stack dump [4]  /usr/lib/x86_64-linux-gnu/libc.so.6raise+0x16
	stack dump [5]  /usr/lib/x86_64-linux-gnu/libc.so.6abort+0xd3
	stack dump [6]  /usr/lib/x86_64-linux-gnu/libstdc++.so.6+0xa2b9e
	stack dump [7]  /usr/lib/x86_64-linux-gnu/libstdc++.so.6+0xae20c
	stack dump [8]  /usr/lib/x86_64-linux-gnu/libstdc++.so.6+0xae277
	stack dump [9]  /usr/lib/x86_64-linux-gnu/libstdc++.so.6+0xae1fe
	stack dump [10]  /tmp/agent/dist/node_modules/@cupix-compute/site-track/libtbb.so.12+0x291c8
	stack dump [11]  libtbb.so.12 : tbb::detail::r1::execute_and_wait(...)
	stack dump [12]  libbimalgorithm.so : SiteInsights::removeOutBoundPointCloud()
	stack dump [13]  libbimalgorithm.so : SiteInsights::prepareBimMeshAndPointCloud(IProgress)
	stack dump [14]  libbimalgorithm.so : BimPointsValidatorBase::runValidation(bool, IProgress)
	stack dump [15]  libbimalgorithm.so : BimValidator::runPointValidator(...)
	stack dump [16]  libbimalgorithm.so : BimValidator::processSiteInsight()
	stack dump [17]  libbimalgorithm.so : BimValidator::process(IProgress)
	stack dump [18]  sitetrack_api.node : SiteTrack::Impl::process()

Impact#

  • Service: cupixworks-sitetrack-instance
  • Team: ellisdon
  • 발생 횟수: 1
  • 최초 발생: 2026-04-22T03:02:27.333Z
  • 최근 발생: 2026-04-22T03:02:27.333Z

Root Cause Summary#

SiteInsights::removeOutBoundPointCloud() 함수가 Intel TBB(Threading Building Blocks) 병렬 실행 중 처리되지 않은 C++ 예외를 발생시켜 std::terminate -> abort() 호출로 프로세스가 SIGABRT로 종료되었다. 스택 트레이스의 libstdc++ 프레임(frames 6-9)은 C++ exception handling -> abort() 경로를 나타내며, 이는 TBB parallel task 내에서 잡히지 않은 예외(likely std::bad_alloc 또는 out-of-range access)가 발생했음을 의미한다. 직전에 filterBimMeshesByDistanceFromPano()가 0ms 만에 완료된 점과 220,106개의 대규모 BIM request objects가 처리 대상이었던 점을 고려하면, 필터링 결과가 비정상(빈 집합 또는 degenerate 데이터)인 상태에서 removeOutBoundPointCloud()가 이를 검증 없이 병렬 처리에 진입한 것이 근본 원인으로 판단된다.

Technical Analysis#

Code Path#

Entry point: sitetrack_api.node -> SiteTrack::Impl::process()

TypeScript 레이어에서 네이티브 모듈이 호출되는 경로:

applications/agents/packages/cupix-sitetrack-master-agent/src/process/sitetrack.process.ts:35-57typescript
return new Promise((resolve, reject) => {
  try {
    const validator = new SiteTrack();
    validator.set_options_filepath(params.options_filepath!);
    validator.set_request_filepath(params.request_file_path!);
    validator.set_output_dirpath(params.result_dir_path!);

    validator.process();  // 네이티브 C++ 호출 — SIGABRT 발생 시 JavaScript catch로 잡히지 않음

    this.log('SitetrackProcess::execute | Sitetrack processing completed successfully');
    resolve({ success: true });
  } catch (error) {
    const errorMessage = error instanceof Error ? error.message : String(error);
    this.log(`SitetrackProcess::execute | error: ${errorMessage}`);
    reject(error);
  }
});

validator.process() 호출은 try-catch 안에 있지만, 네이티브 C++ 크래시(SIGABRT)는 JavaScript 예외 처리를 우회하여 프로세스를 직접 종료시킨다.

Child process 종료 감지:

applications/agents/packages/base/src/manager/child-process.manager.ts:107-120typescript
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);
});

Parent process는 child의 SIGABRT 종료를 감지하여 "Process killed by signal SIGABRT (code: null)" 에러 로그를 기록한다.

네이티브 C++ 크래시 경로 (pre-compiled libbimalgorithm.so — 소스 코드는 cupix-algorithm/skat 리포지토리):

  1. BimValidator::process() -> processSiteInsight() -> runPointValidator()
  2. BimPointsValidatorBase::runValidation() -> SiteInsights::prepareBimMeshAndPointCloud()
  3. prepareBimMeshAndPointCloud()에서 220,106개 BIM request objects 처리 시작
  4. filterBimMeshesByDistanceFromPano() 0ms 완료 (빈 결과 또는 trivial 결과)
  5. SiteInsights::removeOutBoundPointCloud() 진입 직후 TBB parallel execution에서 예외 발생
  6. libstdc++ exception handling이 abort() 호출 -> SIGABRT

Failure point: libbimalgorithm.so : SiteInsights::removeOutBoundPointCloud() 내 TBB parallel task

크래시가 함수 진입 후 1ms 이내에 발생한 점은 병렬 작업 초기화 단계 또는 첫 데이터 접근 시점에서 문제가 발생했음을 시사한다. filterBimMeshesByDistanceFromPano()의 0ms 완료는 필터 결과가 빈 집합일 가능성을 나타내며, 이 빈 결과가 removeOutBoundPointCloud()에 전달되어 빈 컨테이너에 대한 잘못된 접근이나 메모리 할당 실패를 유발했을 수 있다.

Log Evidence#

Datadog 쿼리 1: 에러 로그 검색

text
service:cupixworks-sitetrack-instance status:error @environment:production

Time range: 2026-04-22 02:02 ~ 03:32 UTC

7개의 에러 로그 반환. SIGABRT 크래시 1건 + child process 종료 감지 로그 2건 + 별도 인스턴스 크래시 로그 포함.

Datadog 쿼리 2: 크래시 직전 컨텍스트

text
service:cupixworks-sitetrack-instance (status:warn OR status:info)

Time range: 2026-04-22 02:50 ~ 03:05 UTC

129개의 로그 반환. 주요 항목:

text
[03:00:36.777] BIM progress loaded: 240,446 bimProgress objects
[03:00:38.394] Invalid Geometry(0): Failed to decode geometry buffer
[03:00:38.394] Invalid OTG header - Unexpected zero length CDN resource received
[03:02:27.151] SiteInsights::prepareBimMeshAndPointCloud() starts. 220,106 BIM request objects
[03:02:27.331] filterBimMeshesByDistanceFromPano() starts and ends in 0ms
[03:02:27.332] SiteInsights::removeOutBoundPointCloud() starts
[03:02:27.333] Received fatal signal: SIGABRT(6) PID: 70

Datadog 쿼리 3: SIGABRT 재발 패턴 (14일)

text
service:cupixworks-sitetrack-instance "Received fatal signal"

Time range: last 14 days

9건의 fatal signal 크래시:

  • SIGABRT in removeOutBoundPointCloud(): 1건 (이번 인시던트)
  • SIGSEGV in BimModel::mergingByExternalId(): 6건 (별도 fingerprint f46b1af4)

Datadog 쿼리 4: child process 종료 로그

text
service:cupixworks-sitetrack-instance "Process killed by signal SIGABRT"

Time range: 2026-04-22 03:05 ~ 03:15 UTC

text
[03:06:42.666] ChildProcessManager::setupEventHandlers | Child process exited
[03:06:42.667] ChildProcessManager::setupEventHandlers | Child process closed
[03:06:42.668] Process killed by signal SIGABRT (code: null)

Datadog 쿼리 5: Invalid Geometry 경고

text
service:cupixworks-sitetrack-instance ("Invalid Geometry" OR "Invalid OTG header")

Forge/APS에서 가져온 BIM 모델 데이터 중 일부가 손상되었거나 불완전한 상태:

text
[03:00:38] Invalid Geometry(0): Failed to decode geometry buffer
[03:00:38] Invalid OTG header - Unexpected zero length CDN resource received

이러한 경고는 ARCH L2, MECH-MP, ELEC MAIN-MODEL 등 여러 Forge URN에서 발생. 손상된 geometry 데이터가 후속 point cloud 처리에 영향을 미쳤을 가능성이 있다.

성공적 실행 비교: 동일 서비스의 다른 인스턴스에서 03:08~03:31 UTC 사이에 removeOutBoundPointCloud()가 정상 완료된 로그 확인:

text
[03:10:xx] removeOutBoundPointCloud() elapsed: 0.02, # of pc: 5->5

이는 정상적인 데이터셋에서는 함수가 문제없이 동작함을 보여주며, 이번 크래시가 특정 데이터 조건(대규모 데이터셋 + 손상된 geometry)에 의해 트리거되었음을 시사한다.

Hypotheses Considered#

# Hypothesis Evidence for Evidence against Verdict
H1 removeOutBoundPointCloud() 내 TBB parallel task에서 빈/비정상 입력 데이터에 대한 unhandled exception 발생 filterBimMeshesByDistanceFromPano() 0ms 완료 (빈 결과 가능), 크래시가 함수 진입 1ms 이내, libstdc++ exception -> abort() 스택 트레이스 다른 인스턴스에서 동일 함수 정상 완료 (# of pc: 5->5) Confirmed
H2 대규모 데이터셋(220,106 objects)에 의한 메모리 부족(std::bad_alloc) 240,446 bimProgress + 220,106 request objects는 매우 큰 워크로드, TBB 병렬 처리 시 메모리 압력 증가 이전 단계(loadBimPointCloudsSI 27.8s)는 성공적으로 완료, 크래시가 함수 초입에서 발생하여 메모리 소진보다 데이터 접근 문제에 가까움 Inconclusive
H3 Forge/APS의 손상된 geometry 데이터("Invalid Geometry", "Invalid OTG header")가 후속 처리에 전파 크래시 전 다수의 Invalid Geometry/OTG 경고 발생, 손상된 데이터가 point cloud에 포함되어 removeOutBoundPointCloud()에서 잘못된 메모리 접근 유발 가능 경고는 03:00:38에 발생했고 이후 27분간의 처리는 성공, 직접적 인과 관계 불명확 Inconclusive
H4 Node.js/JavaScript 레이어의 에러 핸들링 미비로 인한 문제 sitetrack.process.ts:42의 try-catch는 네이티브 SIGABRT를 잡지 못함 SIGABRT는 C++ 내부에서 발생하며 JavaScript 레이어와 무관, parent process는 정상적으로 종료 감지 Rejected (원인이 아닌 결과)

Fix Recommendation#

즉시 조치 (Critical)#

입력 데이터 보존 (crash reproduction):

  • sitetrack.process.ts 또는 sitetrack-service.ts에서 validator.process() 호출 전에 입력 파일(bim_validator_request.json, options, progress files)을 S3에 백업하는 로직 추가
  • 크래시 재현을 위해 C++ 팀에 전달할 수 있는 입력 데이터 확보가 최우선
  • 이 권장사항은 이전 SIGSEGV RCA(f46b1af4)에서도 동일하게 제시되었으나 아직 미구현 상태

네이티브 크래시 전용 에러 코드:

  • child-process.manager.ts의 close handler에서 signal이 SIGABRT 또는 SIGSEGV인 경우 별도 에러 코드(AGT_NATIVE_CRASH)를 설정하여 일반 프로세스 종료와 구분

단기 개선 (1주 이내)#

C++ 레이어 방어 코드 (cupix-algorithm/skat repository):

  • SiteInsights::removeOutBoundPointCloud()에서 TBB parallel task 진입 전 입력 데이터 유효성 검증 추가 (빈 컨테이너, null pointer 체크)
  • filterBimMeshesByDistanceFromPano() 결과가 빈 경우 early return 처리
  • TBB parallel task 내부에 try-catch 추가하여 예외를 graceful하게 처리 (TBB task 내 unhandled exception은 std::terminate 호출)

Execution timeout 설정:

  • SitetrackProcessManager 생성자에서 executeTimeoutMs 옵션 설정 — 현재 timeout이 미설정되어 네이티브 크래시 시 parent process가 무한 대기할 수 있음
  • child-process.manager.ts:31에 이미 timeout 인프라 존재하나 sitetrack에서 미사용

장기 개선 (재발 방지)#

네이티브 라이브러리 안정성 강화:

  • libbimalgorithm.so의 모든 TBB parallel task 내부에 exception safety 보장 (try-catch 또는 tbb::task_group_context 활용)
  • 대규모 데이터셋(200K+ objects)에 대한 스트레스 테스트 추가
  • Forge/APS에서 가져온 geometry 데이터의 무결성 검증을 processing pipeline 초기에 수행하여 손상된 데이터가 deep processing 단계로 전파되지 않도록 방지

크래시 진단 인프라:

  • core dump 수집 설정 (컨테이너 환경에서 /tmp/core 등)으로 C++ 팀이 상세 디버깅 가능하도록 지원
  • g3log crash handler의 스택 덤프를 structured log로 변환하여 Datadog에서 분석 용이하게 개선

Monitoring#

  • 네이티브 크래시 전용 메트릭 추가:
text
service:cupixworks-sitetrack-instance "Received fatal signal"
  • BIM Validator 대규모 데이터셋 모니터링:
text
service:cupixworks-sitetrack-instance "bimProgress objects" @environment:production
  • Invalid Geometry 경고 빈도 추적 (데이터 품질 지표):
text
service:cupixworks-sitetrack-instance ("Invalid Geometry" OR "Invalid OTG header") @environment:production

Risk Assessment#

  • Risk level: medium — 단일 건 발생이나 네이티브 크래시 패턴이 반복적이며(14일간 SIGSEGV 6건 + SIGABRT 1건), C++ 라이브러리 수준의 수정이 필요하여 대응 리드타임이 길다.
  • 예상 복잡도: critical — root cause가 pre-compiled 네이티브 라이브러리(libbimalgorithm.so) 내부에 있어 TypeScript 레이어만으로는 근본 해결 불가. cupix-algorithm/skat C++ 리포지토리 수정 + 라이브러리 재빌드/배포 필요. 방어적 조치(입력 보존, timeout, 에러 코드 분류)는 TypeScript 레이어에서 구현 가능.