Nim

Activity, over time

Daily observations from the public event archive.

Attention

Daily stars & forks

Loading attention chart

Star accumulation

Cumulative stars

Loading star accumulation chart

Pull requests

Daily opens & merges

Loading pull requests chart

Conversations

Daily issues & comments

Loading conversations chart

Community

Daily accounts & reviews

Loading community chart

Releases

Daily releases

Loading releases chart

Mentions

1post · 30d
Nov 50 posts
  1. Zenn · · @jasagiri

    Nim の Boehm GC で、落ちるはずのプログラムが 90 分固まっていた --mm:boehm でビルドした Nim のプログラムは、Boehm GC の中で致命的なシグナルが起きると、終わらずに固まっていました。この問題を直した PR(#26515)が、10 月 22 日に Nim の devel にマージされました。今は、メッセージを出してすぐに終わります。この記事では、なぜ固まっていたのか、何を変えたのか、何と引き換えにしたのかを書きます。 CI が 90 分止まった きっかけは CI です。tests/gc/gctest.nim を --gc:boehm で走らせるジョブが、3 回続けて 90 分の上限まで止まったままになりました。原因の一つは二重解放で、それは別の PR(#26506)で直っています。ただ、二重解放ならすぐに落ちるはずです。90 分も固まったのは、別の問題でした。 シグナルハンドラが、自分の持つロックを待っていた 固まった実行に gdb を当てると、シグナルハンドラの中で止まっていました(devel 9f769b15、Debian 12 arm64、libgc 8.2.2)。 #1 pthread_mutex_lock #2 GC_disable (libgc) #3 GC_disable_u0__system #4 signalHandler #5 <signal handler called> #7 raise #8 abort #9 ?? (libgc) #10 GC_free (libgc) 流れは次のとおりです。 Boehm の GC_free が不正な解放(Duplicate large block deallocation)に気づき、アロケータのロックを持ったまま abort を呼ぶ。 Nim の signalHandler が動き、スタックトレースを書く前に GC_disable と newStringOfCap を呼ぶ。 どちらも同じロックを取りにいくが、そのロックは同じスレッドが持ったままなので、永遠に待つ。 signalHandler の上には、もともと「アロケーションの最中にシグナルが来るとここで壊れうる」というコメントがありました。Boehm の場合、その壊れ方が「落ちる」ではなく「固まる」だったわけです。CI にとっては、固まるほうがずっと困ります。ジョブが時間切れになるまで、何も分からないからです。 何を変えたか Boehm のときは、signalHandler がスタックトレースを書かず、メッセージだけを書いて終わるようにしました。 新しい経路は足していません。signalHandler には、スタックトレースを持たないビルドのための「メッセージだけを書く」分岐が既にあります。Boehm のときもそちらを通るように、when の条件を 1 つ変えただけです。Boehm を使わないビルドでは、生成されるコードは前と同じです。 PR のときに Debian 12 arm64(libgc 8.2.2)で確かめた結果は次のとおりです。大きなブロックを 2 回解放するテスト(tests/gc/tboehm_signal.nim)で比べました。 結果 修正前 何も出力せずに固まる。テストに仕込んだ alarm(30) で 32 秒後に打ち切られた 修正後 1 秒で SIGABRT: Abnormal termination. を出して終わる testament cat gc は 79/79 で、gctest の Boehm の 2 つの実行も通りました。 引き換えにしたもの Boehm でビルドしたプログラムは、シグナルを受けたときにスタックトレースを出さなくなりました。Boehm の中のシグナルだけでなく、nil の参照外しのような普通のシグナルでも同じです。ほかのメモリ管理(ORC、ARC、refc)は変わりません。 この修正は devel に入りました。リリースされている版(2.2 系)への backport は、今のところ決まっていません。 テストに仕込んだ alarm と、testament のもう一つの問題 上の表の「alarm(30) で打ち切られた」には理由があります。Nim のテストランナー(testament)は、テストの spec に上限時間(timeout)を書いても、プロセスが終わった後に経過時間を比べるだけです。止まったテストを打ち切りません。そのため、固まるテストを testament に普通に渡すと、それ自体が CI を上限まで止めてしまいます。テストの中で alarm を仕込んだのは、そのためです。 今回 90 分待たされたのは、これも理由の一つです。テストが固まっても、どのテストが固まったのかは、ジョブの上限が来るまで分かりませんでした。同じ問題の issue は、2021 年(#17407)と 2024 年(#24278)に出ていて、どちらも開いたままです。 上限時間を過ぎたテストのプロセスを打ち切り、reTimeout として報告する修正を手元で作りました。macOS arm64 と、Linux の arm64(glibc)と amd64(musl)で、止まるテストが数秒で打ち切られることを確かめてあります。今出している PR の結果を見てから、出す予定です。

Latest stargazers

The last 10 distinct accounts we observed this year.

Most active participants

PR, issue, comment & review events in the past year.

Packages

Scan pending.

Live mentions badge

Show how many posts mention your project in the last 30 days.

Live mentions · last 30 days
nim-lang/Nim mentions in the last 30 days