ES /docs

MeshService::run | error: {"stack":"Error: Process killed by signal SIGABRT (code: null)

RCA: MeshService::run | Process killed by signal SIGABRT

Error Log#

Datadog Logs

text
MeshService::run | error: {"stack":"Error: Process killed by signal SIGABRT (code: null)
    at ChildProcess.<anonymous> (/tmp/agent/dist/app.cjs:1510:33)
    at ChildProcess.emit (node:events:524:28)
    at ChildProcess.emit (node:domain:489:12)
    at maybeClose (node:internal/child_process:1104:16)
    at ChildProcess._handle.onexit (node:internal/child_process:304:5)
    at Process.callbackTrampoline (node:internal/async_hooks:130:17)","message":"Process killed by signal SIGABRT (code: null)"}

Impact#

  • Service: cupixworks-any-mesh-agent
  • Team: repsol
  • 발생 횟수: 1 (이 클러스터), 7건 SIGABRT (최근 7일간)
  • 최초 발생: 2026-04-07T13:24:38.965Z
  • 최근 발생: 2026-04-07T13:24:38.965Z

Root Cause Summary#

cupix-tesla-mesh-agent의 child process에서 실행되는 C++ native 모듈 @cupix-compute/forge_bimmodel_extractor(v0.0.148)가 Forge API로부터 WebSocket을 통해 geometry 데이터를 수신하지 못할 때, std::runtime_error("No geometry data received over WebSocket connection.")을 throw하고, 이 exception이 C++ 레벨에서 catch되지 않아 terminate()abort() → SIGABRT 시그널이 발생한다. Node.js child process는 SIGABRT를 핸들링할 수 없으므로 즉시 종료되며, parent process의 ChildProcessManagerclose 이벤트를 통해 에러를 전파한다. 이 incident의 job 1233은 eu-central-1 리전에서 시작 후 약 8초 만에 crash했으며, mesh extraction 단계에 도달하기도 전에 WebSocket 연결 실패로 종료되었다.

Technical Analysis#

Code Path#

Entry Point: MeshService::run — SQS 메시지를 수신하여 BIM mesh extraction을 시작한다.

typescript
// applications/agents/packages/cupix-tesla-mesh-agent/src/mesh-service.ts:101-122
protected run = async (targetId: number): Promise<void> => {
    const cpBim = await this.createCPBimByBimId(targetId);
    if (cpBim) {
        this._modelInProcess = cpBim;
        this._forgeApi.updateRegionFromBim(cpBim.forgeRegion);
        if (cpBim.workspaceDirPath) this.setModelWorkspace(cpBim.workspaceDirPath);
        await this.updateBimMeshState(targetId, TESLA.UpdateBimRequest.MeshStateEnum.Extracting);
        try {
            await this.forgeAuth.authenticate();
            await this.runMeshExtractor(cpBim);  // line 112: child process 생성
            // ... upload steps ...
        } catch (error) {
            // line 118: SIGABRT 에러가 여기서 catch됨
            logger.error('MeshService::run | error: %s', JSON.stringify(error, Object.getOwnPropertyNames(error)));
            await this.updateErrorState(cpBim);
        }
    }
};

Child Process 생성: runMeshExtractorMeshExtractManager.execute()ChildProcessManager.execute()

typescript
// applications/agents/packages/cupix-tesla-mesh-agent/src/mesh-service.ts:184
const meshExtractorResults = await this.meshExtractManager.execute({
    urn: cpBim.forgeUrn,
    path: cpBim.meshDirPath,
    timeOut: Environment.CPX_EXTRACTOR_TIMEOUT,
    formatType: cpBim.forgeFormatType,
    region: cpBim.forgeRegion
});

Failure Point: Child process 내부에서 C++ native 모듈 호출 시 crash 발생.

typescript
// applications/agents/packages/cupix-tesla-mesh-agent/src/process/mesh-extractor.process.ts:138
const extractBIMModel = new BIM_MODEL_EXTRACTOR.extract_bimmodel();
extractBIMModel.setServer(envName);
extractBIMModel.setModelUrn(params.urn);
extractBIMModel.setOutputDirpath(params.path);
const result = extractBIMModel.process();  // C++ native call — 여기서 SIGABRT 발생

C++ 코드에서 std::runtime_error를 throw하면, Node.js의 try/catch로는 잡을 수 없고 terminate()abort()가 호출되어 SIGABRT가 발생한다. Node.js child process에는 SIGABRT 핸들러가 등록되어 있지 않다.

Parent Process 에러 전파: ChildProcessManagerclose 이벤트 핸들러에서 에러를 생성하여 pending Promise를 reject한다.

typescript
// applications/agents/packages/base/src/manager/child-process.manager.ts:107-120
this.process.on('close', (code: number | null, signal: string | null) => {
    const errorMsg = signal
        ? `Process killed by signal ${signal} (code: ${code})`
        : `Process exited with code ${code}`;
    this.rejectAllPending(new Error(errorMsg));  // Promise reject → MeshService::run catch
});

Log Evidence#

사용한 Datadog 쿼리:

text
service:cupixworks-any-mesh-agent status:error @environment:production
text
service:cupixworks-any-mesh-agent status:info @environment:production
text
service:cupixworks-any-mesh-agent status:error (SIGABRT OR SIGSEGV OR signal OR killed)
text
service:cupixworks-any-mesh-agent "No geometry data received"

Crash 시퀀스 (Job 1233, eu-central-1):

text
2026-04-07T13:24:29.810Z [info]  AwsS3Manager::constructor | region: eu-central-1
2026-04-07T13:24:30.060Z [info]  BaseService::runByMessage | id: 1233
2026-04-07T13:24:30.130Z [info]  CupixAuth::setSession | session_id: e9a994e7849031b1a775473a27e0effa19c4fb68
2026-04-07T13:24:32.089Z [error] ChildProcessManager::setupEventHandlers | Child process stderr: (node:49) NOTE: The AWS SDK for JavaScript (v2) will enter maintenance mode...
2026-04-07T13:24:32.112Z [error] ChildProcessManager::setupEventHandlers | Child process stderr: sentry initialization failed.
2026-04-07T13:24:38.366Z [error] ChildProcessManager::setupEventHandlers | Child process stderr: terminate called after throwing an instance of 'std::runtime_error' what(): No geometry data received over WebSocket connection.
2026-04-07T13:24:38.963Z [error] ChildProcessManager::setupEventHandlers | Child process exited
2026-04-07T13:24:38.963Z [error] ChildProcessManager::setupEventHandlers | Child process closed
2026-04-07T13:24:38.964Z [error] Process killed by signal SIGABRT (code: null)
2026-04-07T13:24:38.965Z [error] MeshService::run | error: {"stack":"Error: Process killed by signal SIGABRT (code: null)..."}
2026-04-07T13:24:39.198Z [info]  BaseService::cleanUpAnythingRelatedModel | path: /tmp/workspace/1233

Job 시작(13:24:30)부터 crash(13:24:38)까지 약 8초 소요. CPBim::fromMeshExtractor 로그가 없으므로 mesh extraction 단계에 도달하지 못했다.

최근 7일간 동일 패턴 (SIGABRT + "No geometry data received"):

text
2026-04-01T07:39:49Z  SIGABRT (preceded by "No geometry data received" at 07:39:49.383Z)
2026-04-01T12:38:37Z  SIGABRT (preceded at 12:38:37.357Z)
2026-04-01T19:25:31Z  SIGABRT (preceded at 19:25:30.433Z)
2026-04-01T19:25:42Z  SIGABRT (preceded at 19:25:41.821Z)
2026-04-01T19:25:52Z  SIGABRT (preceded at 19:25:52.397Z)
2026-04-02T11:10:18Z  SIGABRT (preceded at 11:10:18.535Z)
2026-04-07T13:24:38Z  SIGABRT (preceded at 13:24:38.366Z) ← 이 incident

4/1 19:25에 약 22초 간격으로 3회 연속 crash가 발생했으며, 동일 job의 재시도로 추정된다. 별도로 SIGSEGV 2건(4/2, 4/3)이 발생했으나 "No geometry data received" 메시지 없이 다른 원인으로 보인다.

Fix Recommendation#

즉시 조치 (Critical)#

  • @cupix-compute/forge_bimmodel_extractor (v0.0.148) 패키지의 C++ 코드에서 WebSocket 연결 실패 시 abort() 대신 정상적인 에러 코드를 반환하도록 수정해야 한다. std::runtime_error가 throw되었을 때 terminate()로 가지 않도록 top-level try/catch를 추가해야 한다.
  • 수정 대상: @cupix-compute/forge_bimmodel_extractor native 모듈 (외부 패키지)
  • Node.js wrapper 측에서는 child process crash를 감지한 후 구체적인 에러 원인("No geometry data received")을 stderr에서 파싱하여 에러 메시지에 포함시키면 디버깅이 용이해진다.
    • 수정 파일: applications/agents/packages/base/src/manager/child-process.manager.ts:107-120close 이벤트 핸들러에서 직전 stderr 메시지를 에러에 포함

단기 개선 (1주 이내)#

  • mesh-extractor.process.ts:138에서 extractBIMModel.process() 호출 전에 WebSocket 연결 상태를 사전 검증하는 로직 추가 검토. Forge API의 geometry 데이터 가용성을 확인한 후 extraction을 시작하면 불필요한 crash를 방지할 수 있다.
  • 동일 job이 SIGABRT로 실패할 경우 재시도 횟수를 제한하거나, 재시도 간격에 backoff를 적용하여 4/1 19:25처럼 22초 간격 연속 crash를 방지해야 한다.

장기 개선 (재발 방지)#

  • forge_bimmodel_extractor C++ 모듈을 WebAssembly 또는 N-API addon으로 전환하여 crash 격리를 개선하고, 에러를 Node.js exception으로 전파할 수 있도록 아키텍처 변경 검토.
  • Child process crash에 대한 structured error reporting을 도입하여, stderr 파싱에 의존하지 않고 IPC 메시지로 에러 원인을 전달하는 방식으로 개선.

Monitoring#

  • SIGABRT crash 빈도를 추적하는 Datadog 모니터 추가:
text
service:cupixworks-any-mesh-agent status:error "Process killed by signal SIGABRT"
  • "No geometry data received" 에러에 대한 별도 알림 설정:
text
service:cupixworks-any-mesh-agent "No geometry data received over WebSocket connection"
  • 일별/주별 crash 추세를 대시보드로 시각화하여 forge_bimmodel_extractor 업데이트 후 개선 여부 확인.

Risk Assessment#

  • Risk level: medium
  • 예상 복잡도: standard — C++ native 모듈 수정이 필요하므로 forge_bimmodel_extractor 패키지 팀과의 협업이 필요하다. Node.js 측 stderr 파싱 및 에러 메시지 개선은 단독 수행 가능.