← 목록
기타 2026-07-12 5KB 읽기 5분

벡터직결 P0-2b/3b ObjC 재수정 — 크래시-재기동 이벤트유실·selftest 고아 리크

개요

2026-07-12-P0독립검증-앱상주서버-벡터직결.md가 적발한 잔여 결함 2건(P2 #2, #3)을 native/crowny-browser.m 단독 소유 범위에서 수정·검증했다. 대상 파일 외 어떤 파일도 건드리지 않았고, 사장님 실행 인스턴스(CrownyAI.app)는 이번 세션 내내 미기동 상태(무접촉 확인)였다.

무엇을 했는지

(a) 크래시-재기동 트리거 이벤트 1개 유실 → 1회 재전송으로 해소

sendVectorEvent:arg:에서 gAppSrvPort<=0이라 appSrvRestartIfDown()을 호출해 재기동이 이번 호출 안에서 성공한 경우(justRestarted), 원래 요청을 그대로 버리지 않고 usleep(20000)(20ms) 한 번 대기 후 딱 1회만 재전송한다. 무한 재시도 금지 — 그래도 실패하면 기존 스폰 경로로 폴백. VEC_MISMATCH 게이트는 코드 변경 없이 그대로 유지.

  • 즉시(지연 0) 재시도만으로는 불충분함을 실측으로 확인: 새로 스폰된 crownyc 자식이 실제로 TCP listen 상태가 되기까지 1~17ms 걸림(파이썬 폴링 5회 실측) — connect 거부는 그보다 훨씬 빨리 반환되므로 지연 없는 즉시 재시도는 레이스를 벗어나지 못한다. appSrvStop()의 기존 20ms 폴링 관용구와 동일 스케일로 20ms 단 한 번의 대기를 추가.

(b) --selftest-inputv2 매 실행 crownyc 고아 1개 → appSrvStop() 추가

근본원인 확인: 테스트케이스 #6(termSelectLineIndex:extend:renderAndReload)이 서비스="터미널"(벡터지원)이라 sendVectorEvent:@"렌더"를 실제로 태우고, gAppSrvPort<=0(최초 미기동)이라 appSrvRestartIfDown()진짜 crownyc NSTask를 스폰한다. 이 셀프테스트는 main()에서 NSApplication 이벤트루프를 안 타고 직접 return하므로 applicationWillTerminate/dealloc(정상 종료 시 appSrvStop()을 부르는 두 경로)이 전혀 실행되지 않아 자식이 매 실행마다 고아로 남았다. 테스트 종료부("── 복원 ──" 직전)에 appSrvStop() 직접 호출을 추가(nil 가드라 §6을 안 태운 경로에서도 무해).

검증 (실측)

  1. 컴파일 exit0·경고0: 두 빌드구성(①web/hybrid -DCROWNY_VM_WEBKIT -DCROWNY_HYBRID ②crownyonly -DCROWNY_PRODUCT_CROWNY, WebKit 0) 모두 exit0. 신규 경고 0 — 두 구성 모두 기존 unused-function 경고(crownyButlerRoot 등, 우리 수정 라인과 무관한 기존 코드)만 그대로.
  2. 크래시-재기동 시나리오: 계산기 벡터탭에서 crownyc 자식을 최초 렌더 직후(AUTOSEQ 클릭 시작 전, 가장 타이트한 레이스)에 SIGKILL하는 시나리오로 3회 반복(8클릭 시퀀스 hit:숫자:7;8;9;4;5;1;2;3). 3/3 전부 8/8 event=액션 완전 수신, 0 유실. 크래시를 발견한 바로 그 요청(첫 클릭)은 매번 지연 ~25~26ms(20ms 재시도 대기+왕복)로 성공 확인(정상 클릭은 ~2~3ms). VEC_MISMATCH 로그는 3회 다 뜨지만 전부 실측이 기대보다 +1 많은 쪽(캐럿블링크류 500ms 주기 배경 렌더 — AUTOSEQ 유무·크래시 유무와 무관하게 항상 발생, 계약이 명시적으로 허용한 기지 오탐)이지 결손이 아님을 event=액션 개수로 직접 확인. 스크린샷(/tmp/*_shot_seq.png)에서도 디스플레이에 78945123이 정확한 순서·무결로 누적되는 것을 시각 확인(3회 반복 실행이 겹쳐 789451237894512378945123 패턴으로 나타남 — 자릿수 누락/뒤섞임 없음).
  3. --selftest-inputv2 3회 연속: 매회 19/19 PASS, exit0. lsof -nP -iTCP -sTCP:LISTEN로 9801-9820 포트 pid 집합을 실행 전/후 diff — 3회 전부 신규 고아 0(기존 미상 프로세스 5개는 diff에서 변화 없음, 무관 세션 소유라 손대지 않음).
  4. 실좌표 클릭 회귀 1회: CROWNY_AUTOCLICK으로 실제 mouseDown 합성 → windowPointForTopDownX:y: → 히트테스트 → sendVectorEvent 경로 정상 동작 확인(event=액션 로그 + 스크린샷에서 디스플레이가 07로 상태전이). 회귀 없음 — P0-4(실좌표 변환)는 우리 수정과 무관한 코드 경로라 애초에 영향 범위 밖.

관련 파일

  • /Users/ef/CrownyBrowser/native/crowny-browser.m (수정 — sendVectorEvent:arg: 1회 재전송 + appRunSelfTestInputV2 종료부 appSrvStop())
  • 선행 문서: 2026-07-12-P0독립검증-앱상주서버-벡터직결.md(결함 적발), 2026-07-12-벡터직결-P0-2-3-4-ObjC.md(1차 P0-2/3/4)
  • 검증 스크립트(임시, 세션 종료 시 정리됨): /private/tmp/claude-501/-Users-ef/2e95e8b6-e663-4b81-9734-9ded4339b18d/scratchpad/crash_restart_test2.sh

잔여 이슈

  • 계약 부록2의 P0-1(스크롤백 렌더 지연시간, 담당A/한선 소유)과 P0-4 실측치(p50 57ms) 개선은 이 세션 범위 밖 — 그대로 다음 세션 인계.
  • 500ms 주기 배경 "렌더"(캐럿블링크류) 이벤트의 정확한 트리거 소스는 특정하지 않음(계약이 이미 "+1 기지 오탐 허용"으로 처리하도록 명시했으므로 이번 수정 범위에서 추적하지 않았음).