Skip to content

fix(deps): kiwi-rs libkiwi 0.23 ABI 불일치로 인한 sync 세그폴트 수정 - #143

Merged
hang-in merged 1 commit into
hang-in:mainfrom
yeonsh:fix/kiwi-rs-abi-segfault
Jul 6, 2026
Merged

fix(deps): kiwi-rs libkiwi 0.23 ABI 불일치로 인한 sync 세그폴트 수정#143
hang-in merged 1 commit into
hang-in:mainfrom
yeonsh:fix/kiwi-rs-abi-segfault

Conversation

@yeonsh

@yeonsh yeonsh commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

문제

secall sync가 "Ingesting local sessions..." 단계에서 매번 SIGSEGV로 죽음 (2026-07-03, 07-06 크래시 리포트 동일 시그니처 — kiwi_analyzesplitByTrieUsingTypoPreparedTypoTransformer::generateGraph, KERN_INVALID_ADDRESS at 0x8).

근본 원인

kiwi-rs 0.1.4의 #[repr(C)] KiwiAnalyzeOption(5필드 32바이트)은 Kiwi 0.22.xkiwi_analyze_option_t 레이아웃. Kiwi 0.23.0부터 이 C 구조체 끝에 kiwi_prepared_typo_h typo_transformer + float typo_threshold가 추가되어 48바이트가 됐고, 값(by value)으로 전달되기 때문에 libkiwi 0.23.x의 toAnalyzeOption()이 Rust가 초기화하지 않은 +32..+48 스택 쓰레기를 typo 필드로 읽음 → 쓰레기 값이 오타 교정 경로를 켜면 무효한 PreparedTypoTransformer로 분석을 시도하다 널/쓰레기 포인터 역참조.

로컬에 수동 설치된 libkiwi가 0.23.2라 즉시 노출됐지만, kiwi-rs의 자동 다운로드 기본값도 latest(현재 0.23.2)라서 크레이트 자체 결함임.

수정

kiwi-rs 포크에 두 필드를 추가하고 모든 생성 지점(6곳)에서 null/2.5(헤더 문서화 기본값)로 초기화 — 구조체가 커지는 방향은 0.22.x에도 안전(callee가 아는 prefix만 읽음). seCall은 업스트림 수정 릴리스 전까지 [patch.crates-io]로 이 포크를 참조:

검증

  • kiwi-rs 포크: libkiwi 0.23.2 상대로 패치 전 통합 테스트 SIGSEGV → 패치 후 전부 그린 (61 unit + 통합 + doc). RED→GREEN 직접 증거.
  • seCall: cargo build --release 성공, cargo test 746 passed / 0 failed.
  • e2e 재현: 크래시가 났던 secall sync 경로가 exit 0으로 완주 — 밀려 있던 249개 세션 ingest, 그래프 1,278노드/1,039엣지 갱신, 한국어 recall 검색 정상.

Fast-follow 제안 (이번 PR 범위 밖)

CI cargo 스텝에 --locked 추가 — 현재 CI가 lockfile을 강제하지 않아 cargo update 시 git 의존성이 이동할 수 있음 (rev 고정으로 이번 건은 방어됨).

🤖 Generated with Claude Code

kiwi-rs 0.1.4의 KiwiAnalyzeOption(Kiwi 0.22.x 5필드 레이아웃)이
libkiwi >= 0.23.0의 kiwi_analyze_option_t(typo_transformer/typo_threshold
추가, 값 전달 48바이트)와 불일치. kiwi_analyze가 구조체 뒤 16바이트의
초기화되지 않은 스택을 typo 필드로 읽어 sync ingest 중 SIGSEGV.

업스트림(JAICHANGPARK/kiwi-rs) 수정 릴리스 전까지 포크 브랜치
yeonsh/kiwi-rs#fix/analyze-option-abi-kiwi-0.23 으로 패치.
@coderabbitai

coderabbitai Bot commented Jul 6, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Cargo.toml에 [patch.crates-io] 섹션이 추가되어 kiwi-rs 의존성을 crates.io 버전 대신 지정된 rev의 Git 저장소로 재지정합니다. ABI 비호환 문제로 인한 임시 조치임을 설명하는 주석이 포함되어 있습니다.

Changes

의존성 패치 설정

Layer / File(s) Summary
kiwi-rs Git 패치 추가
Cargo.toml
kiwi-rs 0.1.4의 ABI 비호환 문제를 우회하기 위해 crates.io 버전 대신 특정 rev의 Git 저장소를 사용하도록 patch.crates-io 섹션과 사유 주석을 추가함.

Estimated code review effort: 1 (Trivial) | ~3 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 제목이 kiwi-rs/libkiwi 0.23 ABI 불일치로 인한 sync 세그폴트 수정이라는 핵심 변경을 정확히 요약합니다.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
Cargo.toml (1)

62-67: 🔒 Security & Privacy | 🔵 Trivial | 💤 Low value

개인 포크 의존에 대한 추적 이슈 링크 추가 권장.

개인 GitHub 계정(yeonsh)의 포크 브랜치를 임시로 참조하는 것은 문서화가 잘 되어 있어 심각도는 낮지만, 상류 PR/이슈 링크를 주석에 추가하면 추후 이 패치를 제거해야 할 시점을 추적하기 더 쉬워집니다.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Cargo.toml` around lines 62 - 67, The temporary kiwi-rs patch is fine, but
the comment should also include a traceable upstream link for when to remove it.
Update the [patch.crates-io] note near the kiwi-rs git override to reference the
related upstream PR or issue, alongside the existing branch/rev context, so the
fallback dependency is easier to track and retire later.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@Cargo.toml`:
- Around line 62-67: The temporary kiwi-rs patch is fine, but the comment should
also include a traceable upstream link for when to remove it. Update the
[patch.crates-io] note near the kiwi-rs git override to reference the related
upstream PR or issue, alongside the existing branch/rev context, so the fallback
dependency is easier to track and retire later.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: b7f54e76-6274-4621-b35f-cc108a334168

📥 Commits

Reviewing files that changed from the base of the PR and between feebc31 and 5f14c58.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (1)
  • Cargo.toml

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request patches the kiwi-rs dependency in Cargo.toml and Cargo.lock to use a specific git revision. This temporary patch resolves an ABI-incompatibility issue between kiwi-rs 0.1.4 and libkiwi >= 0.23.0 that causes a segmentation fault in kiwi_analyze. There are no review comments, so I have no feedback to provide.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

@hang-in
hang-in merged commit b63757f into hang-in:main Jul 6, 2026
4 checks passed
@hang-in

hang-in commented Jul 6, 2026

Copy link
Copy Markdown
Owner

@
@yeonsh 님, 정말 감사합니다. 🙏

secall sync가 며칠째 매번 SIGSEGV로 죽던 문제였는데, 단순 회피가 아니라 근본 원인(kiwi-rs 0.1.4의 kiwi_analyze_option_t 레이아웃이 libkiwi 0.23의 by-value ABI와 32B↔48B로 불일치)까지 정확히 짚어 주시고, RED→GREEN 통합 테스트로 직접 증거까지 붙여 주셔서 리뷰가 아주 수월했습니다. 감사 중 발견하신 kiwi_config_t 중간삽입 불일치를 upstream 이슈/PR로 함께 보고해 주신 점도 인상 깊었습니다.

머지 전 검증한 내용

FFI ABI + 개인 포크 의존성이라 신중하게, 세 갈래로 독립 검증했습니다:

  • ABI/메모리 안전: bab2min/Kiwi capi.h를 v0.22.1↔v0.23.0으로 직접 대조 — typo_transformer/typo_threshold가 struct 끝에 추가된 것, 포크의 KiwiAnalyzeOption이 필드/타입/순서 일치, 6개 생성 지점 전부 null/2.5 초기화, 48B 확대가 System V·Windows x64 양쪽 by-value ABI에서 안전함을 확인했습니다. null transformer가 typo 보정을 끄거나 엔진이 자기 valid transformer로 치환한다는 것도 Kiwi.cpp에서 교차 확인했습니다.
  • 공급망/무결성: 포크 668a7c0가 upstream master + 딱 2파일 패치이고 나머지 전 파일이 git blob SHA로 upstream과 동일함(주입 코드·build.rs 없음), rev-pin이 체크섬만큼 불변임을 확인했습니다.
  • 회귀 범위: seCall의 kiwi 사용 표면이 Kiwi::init+tokenize뿐이고 결과 struct들은 0.23과 일치 — 이번 수정으로 blast radius가 완전히 닫힘을 확인했습니다.

조치

main에 squash 머지했습니다 (b63757f). 지적해 주신 fast-follow 두 가지를 저희가 이어서 처리합니다:

  1. 런타임 libkiwi 다운로드 버전 핀Kiwi::init()latest를 받는 구조라, 미래 0.24+에서 동일 크래시가 재발할 수 있어 known-good 태그로 고정합니다.
  2. kiwi FFI 회귀 테스트 — 현재 kiwi 런타임 테스트가 전부 #[ignore]+not(windows)라 CI가 kiwi_analyze를 못 태우고 있어, 다음 ABI drift를 CI에서 잡도록 테스트를 추가합니다.

[patch.crates-io] 블록은 upstream JAICHANGPARK/kiwi-rs#2가 릴리스되는 대로 제거하겠습니다. 좋은 기여 다시 한번 감사드립니다! 🎉
@

hang-in pushed a commit that referenced this pull request Jul 6, 2026
FFI 회귀 테스트가 실제 버그를 잡음: 정품 libkiwi 0.23.2 로는 seCall 바인딩이
Kiwi::new() (builder/init 경로)에서 SEGFAULT. 같은 lib+model 로 번들 kiwi-cli 0.23.2
는 정상 분석 → lib/model 이 아니라 바인딩 문제. #143 은 analyze 경로(KiwiAnalyzeOption)
ABI 를 고쳤으나 init 경로 0.23 비호환은 미해결(상류 kiwi-rs 조사 영역).

- KIWI_LIBKIWI_TAG: v0.23.2 -> v0.22.2 (실증된 working 버전). 0.22.2 통과, 0.23.2 는
  init crash 를 동일 env 메커니즘·테스트로 확인. 컴파일된 48B KiwiAnalyzeOption 은
  0.22.2 의 32B prefix 만 읽혀 안전.
- ci.yml: 이전 kiwi-ffi 잡은 포크의 깨진 auto-download 에 의존해 CI 에서 실패했음
  (find_asset_url 이 릴리스 JSON 의 중첩 uploader 객체에서 brace 매칭 실패 -> asset
  not found). 이제 인증된 gh release download 로 libkiwi+model 을 직접 provision 하고
  KIWI_LIBRARY_PATH/KIWI_MODEL_PATH 로 넘겨 Kiwi::new() 가 다운로드 없이 로드.

검증: fresh 0.22.2 provision -> env -> FFI 테스트 통과(2.18s). secall-core 485 green,
clippy -Dwarnings 클린, ci.yml YAML valid.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LVEL1SnCQBtUMeWVy99ebj
@hang-in

hang-in commented Jul 6, 2026

Copy link
Copy Markdown
Owner

@
@yeonsh 님, #143 후속(#144: 버전 핀 + FFI 회귀 테스트)을 진행하다 포크 관련 이슈 두 가지를 발견해 공유드립니다. seCall 쪽 트래킹은 #145 에 정리했고, 상류(JAICHANGPARK/kiwi-rs) 대응이 필요한 사안이라 알려드립니다.

1. libkiwi >= 0.23 → Kiwi::new() init 에서 SEGFAULT

fresh 환경에 정품 libkiwi 0.23.2 를 provision 하고 seCall 의 kiwi 경로를 태우니 Kiwi::new()(builder/init)에서 하드 크래시가 납니다. 같은 lib+model 로 번들 kiwi-cli-0.23.2 는 정상 분석(아버지/NNG 가/JKS 방/NNG ...)이라 lib/model 은 무결하고 바인딩 쪽 문제로 보입니다. probe 로 crash 를 analyze 가 아니라 init 단계로 좁혔습니다.

  • seCall 이 쓰는 builder 경로 시그니처(kiwi_builder_init 4-arg, kiwi_builder_build 3-arg, kiwi_builder_add_word 4-arg)는 0.23.2 capi.h 와 일치했습니다. 그럼에도 init 에서 죽어서, 모델 로딩/빌드옵션 레벨의 0.23 대응 문제로 추정합니다.
  • 부수로, 포크의 FnKiwiInit(*const c_char, c_int, c_int) (3-arg)인데 0.23.2 kiwi_init(const char*, int, int, int) (4-arg)입니다. seCall 은 이 심볼을 쓰진 않지만 참고 부탁드립니다.

#143KiwiAnalyzeOption(analyze 경로) 수정은 정확했고, 위는 그와 별개의 init 경로 비호환입니다. 저희는 우선 #144 에서 KIWI_LIBKIWI_TAG = v0.22.2 로 핀해 우회했습니다.

2. bootstrap.rs::find_asset_url — 중첩 객체 brace 매칭 버그

find_asset_url 이 asset 이름 뒤 } 까지를 asset 객체로 잘라 browser_download_url 을 찾는데, GitHub API 의 asset 객체는 namebrowser_download_url 사이에 "uploader": { ... } 중첩 객체가 있어, 잘린 조각에 URL 이 안 들어갑니다 → "release asset not found for current tag". 유닛테스트의 mock JSON 은 uploader 가 없어 통과하지만, 실제 GitHub API 응답(latest/명시 태그 모두)에서는 auto-download 가 실패합니다. 중첩 깊이를 세거나 browser_download_url 기준으로 역탐색하면 해결될 것 같습니다.

두 건 모두 재현/증거가 있으니 필요하시면 상세 로그 드리겠습니다. 좋은 기여 감사드리고, 상류 반영에 도움이 되길 바랍니다. 🙏
@

hang-in added a commit that referenced this pull request Jul 6, 2026
PR #143 후속. 0.23 init 비호환 발견으로 핀을 실증된 v0.22.2 로 정정. FFI 회귀 테스트가 0.23.2 crash 를 잡음. CI 는 인증 provisioning 으로 0.22.2 검증. 후속 트래킹: 이슈 #145.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
hang-in pushed a commit that referenced this pull request Jul 7, 2026
….22.2

#143(kiwi-rs ABI 포크 패치)/#144(버전 핀 + FFI 회귀 테스트 + CI) 머지, libkiwi 0.23
init 비호환 발견(이슈 #145), MCP/컨텍스트 점검 요약.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LVEL1SnCQBtUMeWVy99ebj
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants