[diag] macOS PNG render 33분 hang 원인 검증 — 한글 폰트 부재 가설#20
Open
DanMeon wants to merge 11 commits into
Open
Conversation
test-other-os (macos-latest / py3.12) 잡이 단일 테스트 test_returns_png_magic 에서 33분 hang 하는 반면 로컬 ARM64 macOS 에선 동일 호출이 53.5 ms 로 끝남. 한글 폰트 fallback chain 부재가 원인이라는 가설을 검증하려고 brew 로 NanumGothic 설치 + pytest-timeout/faulthandler 로 thread dump 를 받도록 macOS 한정 step 분기. 검증 후 close 예정인 임시 브랜치. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1차 진단에서 NanumGothic 설치에도 동일 hang → 폰트 부재 가설 기각. Python faulthandler 는 _inner.render_png (PyO3 진입) 직전에서 멈춰 Rust 측 hang 위치를 못 보여줌. macOS sample 명령으로 90 초 wait 후 hung process 의 native frame (Rust + Skia + system call 까지) 을 20 초 sampling. 폰트 인식 확인 (fc-list / system_profiler) 도 함께. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
이전 진단에서 sample 출력에 tail -400 을 걸어 자식 PID 의 Call graph 가 잘려 Binary Images 만 남았음. sample 의 -file 옵션으로 파일에 저장 → Call graph 부분만 awk 로 추출해 stdout 에 노출 + 전체 sample 파일은 actions/upload-artifact 로 업로드해 다운로드 후 분석 가능하게 함. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
3차 진단에서 PID 8552 (Python) call graph 가 CoreText TDownloadableFontManager::Download → libFontRegistryUI → CFMessagePortSendRequest → mach_msg2_trap 으로 IPC 무한 대기 임을 확인. 원인은 macOS CoreText 의 downloadable-font auto-activation: 시스템에 없는 폰트가 요청되면 FontRegistryUI daemon 에 IPC 로 다운로드 가능성을 물어보고 응답 대기 — Actions runner 환경에서 daemon 이 응답 못 함. NanumGothic 만으로 효과 없었던 이유는 상류 fallback chain 의 앞쪽 폰트 (Noto Sans KR 등) 가 없어서 거기서부터 다운로드 lookup 발동. chain 전체 (Noto Sans KR / Noto Serif KR / Noto CJK / Nanum Gothic) 를 설치해 첫 매치에서 lookup 이 끝나도록 함. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
진단 PR 의 macOS 잡 끝에 상류 rhwp 자체 CLI (export-svg) 실행 step 추가. 상류 CLI 도 SkiaRenderer::new 의 FontMgr::default() 진입점을 공유하므로 같은 hang 이 재현되는지 확인. timeout 90s, exit 124 면 hang 으로 판정. PNG path 특이성 vs 상류 전반 영향 구분. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
이전 시도는 working-directory: external/rhwp 에서 target/release/rhwp 를 찾았으나 rhwp-python 의 Cargo.toml 이 workspace 를 정의하고 external/rhwp 를 path dependency 로 포함하므로 cargo build 산출물이 repo root 의 target/ 에 떨어짐. working-directory 제거 + sample 경로를 external/rhwp/samples/aift.hwp 로 보정. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
workspace root 에서 --bin rhwp 빌드 시도가 default-run packages 에서 타깃을 못 찾아 실패함. working-directory: external/rhwp 로 돌려서 cargo 가 그 디렉토리의 [[bin]] 정의를 인식하게 함. 빌드 산출물은 workspace 멤버 발견 결과에 따라 ../../target/release/rhwp 또는 ./target/release/rhwp 둘 중 하나로 떨어지므로 양쪽 다 시도. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
이전 시도가 timeout 명령으로 exit 127 (command not found) 종료됨. GNU coreutils 미포함이라 macOS runner 에 timeout 도 gtimeout 도 없음. background 실행 + sleep 5s 폴링 + 경과 90s 시 kill -9 패턴으로 직접 구현. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
CTFontManagerSetAutoActivationSetting(null, 1) 호출을 SkiaLayerRenderer::new() 진입 직후에 삽입하는 patch 를 ci/patches/ 에 추가. macOS 잡에서 maturin develop --release 직전에 git apply 로 working tree 에만 반영 (external/rhwp 자체 commit 없음). PNG hang 이 사라지면 후보 B 확정, 그대로면 후보 A 또는 다른 방향 탐색 필요. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
후보 B (CTFontManagerSetAutoActivationSetting) 가 효과 없음을 확인. 검증 에이전트의 회의 — 해당 API 가 타사 font manager activation 알림 용일 뿐 libFontRegistryUI downloadable lookup 은 안 끔 — 이 직접 검증됨. 후보 A 로 교체. font_mgr.family_names() 로 시스템 폰트 family set 을 SkiaLayerRenderer 생성 시 캐시하고, match_family_style 호출 전 에 멤버십 체크해 missing family 는 skip. CoreText 의 downloadable lookup path 자체에 진입하지 않게 함. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
후보 A patch v2 의 family.as_str() 가 macOS runner 의 Rust 1.95.0 에서 unstable str_as_str feature 로 에러. AsRef::<str>::as_ref(family) 로 변경해 stable 한 표현으로 교정. 로컬 cargo check release OK 확인. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
24648ea to
be473ff
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
test (macos-latest / py3.12)잡의 단일 테스트tests/test_render_png.py::TestRenderPng::test_returns_png_magic가 33분 hang. 로컬 ARM64 macOS 에선 동일 호출이 53.5 ms. 한글 폰트 fallback chain 부재 가설 검증용 임시 PR.Why
external/rhwp/src/renderer/skia/renderer.rs의 한글 폰트 fallback chain (Noto Sans KR → ... → Apple SD Gothic Neo → Arial) 에서 시스템 폰트 부재 시 char-by-char fallback 비용이 누적될 가능성Test plan
test (macos-latest / py3.12)잡이 10분 이내 통과 → 폰트 부재 가설 확정주의
merge 하지 말 것 — 진단/검증 전용. 진단 commit 은 맨 위 한 개 (
32eabb3).parent 브랜치
ci/schema-publish-skia-deps(0e16f70) 의 publish-schema 변경도 함께 포함됨.🤖 Generated with Claude Code