ES /docs

libbimmodel.so null pointer in mergingByExternalId — TBB worker thread

RCA: SIGSEGV in BimModel::mergingByExternalId

Error Log#

Datadog Logs

text
[120987.90] | Received fatal signal: SIGSEGV(11)	PID: 64

***** SIGNAL SIGSEGV(11)

*******	STACKDUMP *******
	stack dump [1]  libg3log.so+0x15d0b
	stack dump [2]  libc.so.6+0x42520
	stack dump [3]  libbimmodel.so : cupix::bim_model::v3::BimModel::mergingByExternalId(...)+0x1cf
	stack dump [4]  libbimmodel.so : cupix::bim_model::v3::BimModel::load(...)+0xbd3
	stack dump [5]  libbimmodel.so : cupix::bim_model::BimModelFactory::createFromBimModelJson(...)+0x87e
	stack dump [6]  libbimdeviationmodel.so+0x11ac14
	stack dump [7]  libbimdeviationmodel.so+0x11b83d
	stack dump [8]  libtbb.so.12+0x303c3
	stack dump [9]  libtbb.so.12+0x2abf7
	stack dump [10] libc.so.6+0x94ac3
	stack dump [11] libc.so.6 clone+0x44

Exiting after fatal event  (FATAL_SIGNAL). Fatal type:  SIGSEGV

Impact#

  • Service: cupixworks-sitetrack-instance
  • Team: tpc
  • 발생 횟수: 1
  • 최초 발생: 2026-04-16T06:33:09.976Z
  • 최근 발생: 2026-04-16T06:33:09.976Z

Root Cause Summary#

@cupix-compute/site-track 네이티브 C++ 라이브러리(libbimmodel.so)의 BimModel::mergingByExternalId() 메서드에서 SIGSEGV(segmentation fault)가 발생했습니다. 이 크래시는 TBB(Threading Building Blocks) worker thread에서 발생했으며, BimModelFactory::createFromBimModelJson()을 통해 BIM 모델 JSON을 로드하고 external ID 기반으로 BIM 요소를 병합하는 과정에서 null pointer dereference 또는 잘못된 메모리 접근이 일어난 것으로 판단됩니다. Sitetrack 16458 (team: tpc, job: 1017917)의 BIM validation 처리 중 발생했으며, 메인 thread(121660)에서 processSiteInsight()loadBimProgress()가 정상적으로 338개의 progress 항목을 로드한 직후 TBB worker thread(120987)에서 크래시가 발생했습니다. 크래시 지점이 사전 컴파일된 네이티브 .so 라이브러리 내부이므로, JavaScript 레이어에서의 직접적인 코드 수정은 불가능합니다.

Technical Analysis#

Code Path#

  • Entry point: sitetrack-service.ts:87run() 메서드에서 sitetrack 처리 시작
  • sitetrack-service.ts:101executeBimValidator(cpSitetrack) 호출
  • sitetrack-service.ts:201-227executeBimValidator()에서 child process 관리자를 통해 네이티브 모듈 실행
  • sitetrack.process.ts:37-42 — child process에서 SiteTrack 네이티브 모듈 인스턴스 생성 및 validator.process() 호출
  • Failure point: libbimmodel.soBimModel::mergingByExternalId()에서 SIGSEGV

실행 흐름 (sitetrack-service.ts:201-227):

typescript
// packages/cupix-sitetrack-master-agent/src/sitetrack-service.ts:201-227
private executeBimValidator = async (cpSitetrack: CPSitetrack): Promise<void> => {
    logger.info('Sitetrack::executeBimPointsValidator | begin - sitetrack.id: %d', cpSitetrack.id);
    this.logManager.watchLogFile(Constants.DefaultWorkspacePath);

    await this.bimProcessManager.initialize();

    const params: ProcessParams = {
        options_filepath: cpSitetrack.pointsValidatorOptionsFilePath,
        request_file_path: cpSitetrack.pointsValidatorRequestFilePath,
        result_dir_path: cpSitetrack.bimValidatorResultDirPath,
        // ... environment params
    };

    await this.bimProcessManager.execute(params);
    await this.bimProcessManager.stop();
};

Child process에서 네이티브 모듈 호출 (sitetrack.process.ts:28-57):

typescript
// packages/cupix-sitetrack-master-agent/src/process/sitetrack.process.ts:35-42
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++ 네이티브 코드 진입, 이후 SIGSEGV 발생
    } catch (error) {
        // SIGSEGV는 try-catch로 잡히지 않음 — 프로세스 자체가 종료됨
    }
});

네이티브 라이브러리 내부 크래시 경로:

validator.process() 호출 후 C++ 네이티브 코드가 실행되며, 내부적으로 다음 호출 스택을 거칩니다:

  1. libbimdeviationmodel.so — BIM deviation 모델 로딩 시작 (TBB parallel task로 dispatch)
  2. BimModelFactory::createFromBimModelJson() — JSON 파일에서 BIM 모델 데이터 파싱
  3. BimModel::load() — BIM 모델을 메모리에 로드
  4. BimModel::mergingByExternalId(const std::set<std::string>&) — external ID 집합을 기반으로 BIM 요소를 병합하는 중 SIGSEGV 발생

스택 프레임 [8-9]에 libtbb.so.12가 있으므로, 이 작업은 TBB worker thread에서 병렬 처리 중이었습니다. Thread ID 120987(크래시 thread)과 121660(메인 processing thread)이 동시에 실행 중이었습니다.

child process 에러 처리 (child-process.manager.ts:107-120):

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

SIGSEGV 발생 시 child process가 exit code 11로 종료되고, ChildProcessManager가 이를 감지하여 "Process exited with code 11" 에러를 전파합니다. 그러나 SIGSEGV 자체가 네이티브 코드 내부의 메모리 접근 위반이므로 JavaScript 레이어에서는 사전에 방어할 수 없습니다.

Log Evidence#

사용한 Datadog 쿼리:

text
service:cupixworks-sitetrack-instance @agent.hostname:ac93446767ec
Time range: 2026-04-16T06:33:00Z to 2026-04-16T06:34:00Z

이벤트 타임라인 (container: ac93446767ec, sitetrack 16458):

시간 (KST) Thread 이벤트
15:33:08 main `Sitetrack::validateForgeUrns
15:33:08 main `ForgeUrnValidator::validateForgeUrns
15:33:08 main `Sitetrack::executeBimPointsValidator
15:33:09 121660 cupix::bim_algorithm::BimValidator::processSiteInsight() start.
15:33:09 121660 cupix::bim_deviation_model::model_loader::loadBimProgress() start.
15:33:09 121660 loadBimProgress() end. elapsed: 0.002, # of bimProgress: 338
15:33:09 120987 Received fatal signal: SIGSEGV(11) PID: 64
15:33:09 main `ChildProcessManager::setupEventHandlers
15:33:09 main `ChildProcessManager::setupEventHandlers
15:33:09 main Process exited with code 11 (x2)
15:33:10 main `Sitetrack::terminateService

핵심 관찰:

  • 메인 C++ thread(121660)에서 loadBimProgress()는 338개 항목을 성공적으로 로드 완료 (elapsed: 0.002s)
  • TBB worker thread(120987)에서 BimModel::mergingByExternalId() 실행 중 거의 동시에 SIGSEGV 발생
  • 두 thread가 동시에 BIM 모델 데이터에 접근하고 있었으며, TBB 병렬 처리가 크래시의 컨텍스트

14일 내 동일 크래시 검색:

text
service:cupixworks-sitetrack-instance status:error "SIGSEGV"
Time range: 2026-04-02T00:00:00Z to 2026-04-16T23:59:59Z

결과: 1건만 발견 — 이번 건이 유일한 발생입니다.

동일 시간대 다른 sitetrack instance (container: 663dd3f41e93, sitetrack 16459):

text
service:cupixworks-sitetrack-instance "16459"
Time range: 2026-04-16T06:30:00Z to 2026-04-16T06:35:00Z

Sitetrack 16459는 별도 컨테이너에서 정상 완료됨 (executeBimPointsValidator | end - sitetrack.id: 16459 at 15:34:04). 크래시는 sitetrack 16458의 컨테이너에 격리됨.

Fix Recommendation#

즉시 조치 (Critical)#

이 크래시는 사전 컴파일된 네이티브 라이브러리(libbimmodel.so) 내부에서 발생하므로, JavaScript 레이어에서 직접 수정할 수 없습니다. @cupix-compute/site-track 패키지를 관리하는 C++ 개발팀(TPC 팀)에 다음 정보와 함께 이슈를 전달해야 합니다:

  • 크래시 스택: BimModel::mergingByExternalId() at offset +0x1cf
  • TBB worker thread(120987)에서 발생, 메인 thread(121660)는 loadBimProgress() 완료 직후
  • Sitetrack 16458, Job 1017917, team tpc, user ehenry@wdfinc.net
  • BIM progress 항목 수: 338개

단기 개선 (1주 이내)#

  1. @cupix-compute/site-track 네이티브 라이브러리 디버그 빌드: C++ 팀이 libbimmodel.somergingByExternalId() 메서드에서 external ID 집합을 순회하며 BIM 요소를 조회할 때, 해당 요소가 없는(null pointer) 경우에 대한 방어 코드를 추가해야 합니다. std::set<std::string> 인자의 각 external ID가 BIM 모델 내 유효한 요소에 매핑되는지 검증 필요.

  2. 입력 데이터 보존: sitetrack-service.tsexecuteBimValidator() 호출 전에 bim_validator_request.jsonbim_progress.json 파일을 별도 디렉토리에 백업하여, 크래시 재현 시 동일 입력 데이터로 테스트할 수 있도록 합니다.

  3. Child process exit code 11 전용 에러 처리: child-process.manager.ts:107-120에서 exit code 11(SIGSEGV)를 별도로 처리하여, 의미 있는 에러 메시지와 함께 크래시 덤프 수집을 트리거할 수 있도록 개선합니다.

장기 개선 (재발 방지)#

  1. TBB thread safety 검토: BimModel::load()mergingByExternalId() 경로에서 TBB 병렬 처리 시 shared data structure에 대한 동시 접근이 안전한지 검토. TBB가 여러 BIM 모델을 병렬 로드할 때 공유 상태에 대한 race condition 가능성.

  2. Core dump 수집 자동화: ECS task 정의에서 core dump 생성을 활성화하고, S3에 자동 업로드하여 네이티브 크래시 디버깅을 지원합니다.

  3. 네이티브 모듈 AddressSanitizer 빌드: 개발/QA 환경에서 ASan이 활성화된 빌드를 사용하여, 메모리 접근 위반을 사전에 탐지합니다.

Monitoring#

  • SIGSEGV 재발 감시:
text
service:cupixworks-sitetrack-instance status:error "SIGSEGV"
  • Child process 비정상 종료 감시 (exit code != 0):
text
service:cupixworks-sitetrack-instance status:error "Process exited with code"
  • BIM validation 실패율 추적:
text
service:cupixworks-sitetrack-instance "executeBimPointsValidator" ("error" OR "failed")

Risk Assessment#

  • Risk level: medium
  • 예상 복잡도: critical — 네이티브 C++ 라이브러리 내부 버그이며, JavaScript 레이어에서는 직접 수정 불가. C++ 팀의 libbimmodel.so 디버깅 및 수정이 필요함. 다만 14일 내 1건 발생으로 빈도는 낮음.