Skip to content

[2026-09-19-exception-reports-instead-of-aborting-p0] fix(jvm): 보고자의 부재는 «생성 시점»에 이름을 들어 실패한다 - #80

Merged
Jun025 merged 2 commits into
mainfrom
feat/rustjava-bound-fallback-recursion
Sep 19, 2026
Merged

Jun025 merged 2 commits into
mainfrom
feat/rustjava-bound-fallback-recursion

Conversation

@Jun025

@Jun025 Jun025 commented Sep 18, 2026

Copy link
Copy Markdown
Owner

채택 제안 2026-09-19-exception-reports-instead-of-aborting#p0 — "Bound the exception-construction recursion when the fallback class itself is unloadable."

★제안은 옳았고, 이 회차가 그 순환을 «처음 실측»했다

제안한 회차는 자기 worklog 에 이렇게 적었다: 「read off the call graph, NOT measured — 커스텀 로더 하네스가 필요해 범위 밖」.
그 하네스(test_jvm_hiding)를 만들어 쟀다:

숨김 로더 상한 결과
5 / 20 / 60 / 120 6 / 21 / 61 / 121 왕복 후 완료
160 / 200 ★**fatal runtime error: stack overflow, aborting** · SIGABRT

⇒ ★바닥이 없고, 121~160 사이에서 프로세스가 죽는다.

★★측정이 설계를 «두 번» 기각했다(둘 다 종이 위에서는 옳았다)

⑴**Jvm::new 의 bootstrap_classes 에 추가** → ★6 테스트 즉사. 패닉 줄이 threads.get_mut(&thread_id).unwrap() 로 매핑된다
⇒ 클래스 해석은 «초기화»를 돌리고, 그 목록 «아래»에서 붙는 스레드가 필요하다.
⑵시스템 클래스로더 뒤 resolve_class → 정상 기동 6/6 통과이고, 제공 가능한 로더에겐 순환이 도달 불가가 된다.
★그러나 숨김 로더에선 여전히 스택 오버플로였다 — 시점만 «생성 중»으로 옮겼을 뿐.
⇒ ★근인은 배치가 아니라 «형태»다: 보고 경로는 «보고자의 부재»를 보고할 수 없다.

지은 것

예외 기구를 우회해 로더에 직접 묻고, 없으면 그 자리에서 이름을 들어 실패한다. 그 뒤 resolve_class 로 등재해 이후 로더를 다시 묻지 않게 한다.

the class set has no java/lang/NoClassDefFoundError, which is the class this runtime reports
every other missing class with. … that recursion has no floor (measured: 121 round trips, then
the process aborts on a stack overflow). Add it to the class set.

3파일(jvm/src/jvm.rs 30/0 · test-utils/src/lib.rs 48/0 · 신규 테스트 17/0) · 테스트 +1.

축 — 양방향 · 제품 경로

Jvm::new 형상 보고자 없는 클래스 집합
전 ★SIGABRT 스택 오버플로 — 테스트 «바이너리째» 죽는다
후 생성 시점에 그 메시지로 패닉 · should_panic 통과

★되돌리면 «실패»가 아니라 바이너리가 내려간다 — 그것이 호스트가 겪던 실패다. 정상 기동 test_string 6/6 전후 불변.

★대가(숨기지 않는다)

⒜★★패닉이고 AGENTS.md 는 라이브러리 패닉을 금한다 — 실제 충돌이라 그대로 적는다.
Err 반환은 불가능(JavaError 가 ClassInstance 를 품는데, 그 인스턴스를 만들 클래스가 바로 없는 것이다) ·
비-예외 variant 는 460 let…else 자리를 조용히 바꾼다며 Jvm::exception 회차가 이미 기각했다 ·
★Jvm::new 는 기존 6클래스에 이미 .unwrap() 한다(같은 계급의 실패) ⇒ 이 파일의 기존 답에 «메시지»를 붙인 것이다.
⒝기동마다 클래스 1개를 더 해석한다(완전한 집합은 영원히 안 밟을 조건을 위해).
⒞★필요보다 일찍 실패한다 — 에러 경로를 안 밟던 호스트는 이제 JVM 을 못 만든다(의도한 교환 · 대안은 «에러 경로에서 죽을 때까지 돈다»).
⒟★이 순환만 막는다 — exception() 이 메시지 문자열을 먼저 만들므로 java/lang/String 이 다음 후보다. ★재지 않았고 주장하지 않는다(후속 카드).

노력도

제안 추정 M 이 맞았다 — 단 이유가 다르다. 하네스는 쉬웠고(~48줄), 비용은 ★앞의 두 설계를 «재서» 기각해야 했다는 것이다.

DoD (9명령 전건 rc=0)

fmt 0 · clippy stable 0 · clippy +beta 0 · clippy wasm32 0 · cargo test --all 586 passed / 0 failed / 1 ignored(내 테스트 포함) ·
check-worklog-json 0 · check-dod-ci-parity 0 · check-named-exception-classes-are-loadable 0 · check-merge-dropped-symbols 0
※배경 작업이 두 번 kill 돼 게이트를 나눠 돌렸다 — 전건 실제 실행이고 rc 원본은 evidence/…/dod-rcs.txt 에 있다.

jun0 and others added 2 commits September 19, 2026 08:02
…부재는 «생성 시점»에 이름을 들어 실패한다

채택 제안 2026-09-19-exception-reports-instead-of-aborting#p0.

★제안이 옳았고 이 회차가 그 순환을 «처음 실측»했다 — 제안한 회차는 자기 worklog 에
「호출그래프에서 읽은 것이고 실측이 아니다 · 커스텀 로더 하네스가 필요해 범위 밖」이라 적었다.
그 하네스(test_jvm_hiding)를 만들어 쟀다: java/lang/NoClassDefFoundError 를 숨기면
상한 5/20/60/120 에서 6/21/61/121 왕복 후 완료, 상한 160·200 에서
「fatal runtime error: stack overflow, aborting」(SIGABRT) — 바닥이 없고 121~160 사이에서 죽는다.

★측정이 설계를 «두 번» 기각했다:
  ⑴Jvm::new 의 bootstrap_classes 에 추가 → 6 테스트 즉사.
    패닉 줄이 threads.get_mut(&thread_id).unwrap() 로 매핑된다 —
    클래스 해석은 초기화를 돌리고 그 목록 «아래»에서 붙는 스레드가 필요하다.
  ⑵시스템 클래스로더 뒤 resolve_class → 정상 기동 6/6 인데 숨김 로더에선 여전히 스택 오버플로.
    시점만 «생성 중»으로 옮겼을 뿐 ⇒ 근인은 배치가 아니라 형태다:
    ★보고 경로는 «보고자의 부재»를 보고할 수 없다.

⇒ 예외 기구를 우회해 로더에 직접 묻고, 없으면 그 자리에서 이름을 들어 실패한다.
그 뒤 resolve_class 로 등재해 이후 에러 경로가 로더를 다시 묻지 않게 한다.

축(양방향·제품 경로): 전 SIGABRT(테스트 바이너리째 죽는다) ↔ 후 should_panic 통과.
정상 기동 test_string 6/6 전후 불변.

대가: ★패닉이고 AGENTS.md 와 충돌한다 — Err 반환은 불가능(JavaError 가 ClassInstance 를 품는데
그 인스턴스를 만들 클래스가 없는 것이다) · 비-예외 variant 는 460 let-else 자리를 조용히 바꾼다며
Jvm::exception 회차가 이미 기각했다 · Jvm::new 는 기존 6클래스에 이미 unwrap 한다(같은 계급).
필요보다 일찍 실패한다(에러 경로를 안 밟던 호스트도 이제 JVM 을 못 만든다 — 의도한 교환) ·
이 순환만 막는다(java/lang/String 은 미측정 · 후속 카드).
…in — 승인된 원장 2파일 합집합

게이트③ 충돌 해소. 충돌 집합(측정 시점: 2026-09-19T09:18:58Z 기준) = REPORT.md · STATE.md
— ★둘 다 원장 파일이고 코드 충돌 0건이라 계약 2-c⒜ 승인 범위 안이다.

해소 = 전건 보존·합집합·시간순(최신 우선). 양쪽이 같은 삽입점에 항목을 앞에 붙였다:
REPORT.md 는 `# REPORT` 뒤 · STATE.md 는 `## 완료` 뒤. 커밋 시각으로 갈랐다 —
main 측 ad9eb1a 08:19:15 > PR 측 81f6bc7 08:02:50 ⇒ main 항목을 위에 둔다.

보존 증명(양방향 · 줄 단위): PR 추가줄 11/6 소실 0 · main 추가줄 10/7 소실 0 ·
출처불명 0 · base 줄 소실 0. 계약 12: 승인 형상 기여 ↔ 흡수 후 기여 numstat diff rc=0
(7파일 255+/0−) · 비-원장 5파일 sha256 전건 IDENTICAL.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@Jun025
Jun025 merged commit 64cc4f6 into main Sep 19, 2026
12 checks passed
@Jun025
Jun025 deleted the feat/rustjava-bound-fallback-recursion branch September 19, 2026 09:31
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.

1 participant