Skip to content

Commit 97563a2

Browse files
authored
Merge pull request #5 from joemphilips/unwind
7章 unwinding.md を翻訳
2 parents 8096b9a + b8b9f09 commit 97563a2

File tree

1 file changed

+63
-0
lines changed

1 file changed

+63
-0
lines changed

src/unwinding.md

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,77 @@
11
# Unwinding
22

3+
<!--
34
Rust has a *tiered* error-handling scheme:
5+
-->
6+
Rustのエラーハンドリングには**階層的な**スキームが存在します。
47

8+
<!--
59
* If something might reasonably be absent, Option is used.
610
* If something goes wrong and can reasonably be handled, Result is used.
711
* If something goes wrong and cannot reasonably be handled, the thread panics.
812
* If something catastrophic happens, the program aborts.
13+
-->
14+
* もし何かが、明確な理由があって欠如しうる場合、Optionが使われます
15+
* もし何かおかしなことが起こった際に合理的な対処方法がある場合、Resultが使われます
16+
* もし何かおかしなことが起こった際に合理的な対処方法がない場合、そのスレッドはpanicします
17+
* もし何か破滅的な出来事が起こった場合、プログラムはabortします
918

19+
<!--
1020
Option and Result are overwhelmingly preferred in most situations, especially
1121
since they can be promoted into a panic or abort at the API user's discretion.
1222
Panics cause the thread to halt normal execution and unwind its stack, calling
1323
destructors as if every function instantly returned.
24+
-->
25+
大抵の状況では圧倒的にOptionとResultが好まれます。というのもAPIのユーザーの
26+
裁量次第でpanicやabortさせることも可能だからです。panicはスレッドの正常処理を
27+
停止し、stackをunwind、全ての関数が即座にreturnしたかのようにデストラクタ
28+
を呼び出します。
1429

30+
<!--
1531
As of 1.0, Rust is of two minds when it comes to panics. In the long-long-ago,
1632
Rust was much more like Erlang. Like Erlang, Rust had lightweight tasks,
1733
and tasks were intended to kill themselves with a panic when they reached an
1834
untenable state. Unlike an exception in Java or C++, a panic could not be
1935
caught at any time. Panics could only be caught by the owner of the task, at which
2036
point they had to be handled or *that* task would itself panic.
37+
-->
38+
バージョン1.0以降のRustはpanic時に2種類の対処法を用いるようになりました。
39+
大昔、Rustは今よりもErlangによく似ていました。Erlangと同様、Rustには軽量のタスク
40+
が存在し、タスクが続行不可能な状態に陥った際にはタスクが自分自身をpanicによって
41+
killすることを意図して設計されていました。JavaやC++の例外と違い、panicはいかなる
42+
場合においてもcatchすることはできませんでした。panicをcatchできるのはタスクの
43+
オーナーのみであり、その時点で適切にハンドリングされるか、**その**タスク
44+
(訳注: オーナーとなるタスク)自体がpanicするかのどちらかでした。
2145

46+
<!--
2247
Unwinding was important to this story because if a task's
2348
destructors weren't called, it would cause memory and other system resources to
2449
leak. Since tasks were expected to die during normal execution, this would make
2550
Rust very poor for long-running systems!
51+
-->
52+
この一連の流れの中では、タスクのデスクトラクタが呼ばれなかった場合にメモリー及び
53+
その他のシステムリソースがリークを起こす可能性があったため、unwindingが重要でした。
54+
タスクは通常の実行中にも死ぬ可能性があると想定されていたため、Rustのこういった
55+
特徴は長期間実行されるシステムを作る上でとても不適切でした。
2656

57+
<!--
2758
As the Rust we know today came to be, this style of programming grew out of
2859
fashion in the push for less-and-less abstraction. Light-weight tasks were
2960
killed in the name of heavy-weight OS threads. Still, on stable Rust as of 1.0
3061
panics can only be caught by the parent thread. This means catching a panic
3162
requires spinning up an entire OS thread! This unfortunately stands in conflict
3263
to Rust's philosophy of zero-cost abstractions.
64+
-->
65+
Rustが現在の形に近づく過程で、より抽象化を少なくしたいという時流に押された
66+
スタイルのプログラミングが確立していき、その過程で軽量のタスクは重量級の
67+
OSスレッドに駆逐・統一されました
68+
(訳注: いわゆるグリーンスレッドとネイティブスレッドの話)。しかしながら
69+
Rust1.0の時点ではpanicはその親スレッドによってのみ補足が可能という仕様であった
70+
ため、 panicの補足時にOSのスレッドを丸ごとunwindしてしまう必要
71+
があったのです!不幸なことにこれはゼロコスト抽象化というRustの思想と
72+
真っ向からぶつかってしまいました。
3373

74+
<!--
3475
There is an unstable API called `catch_panic` that enables catching a panic
3576
without spawning a thread. Still, we would encourage you to only do this
3677
sparingly. In particular, Rust's current unwinding implementation is heavily
@@ -39,11 +80,33 @@ should be no runtime cost for the program being *ready* to unwind. As a
3980
consequence, actually unwinding will be more expensive than in e.g. Java.
4081
Don't build your programs to unwind under normal circumstances. Ideally, you
4182
should only panic for programming errors or *extreme* problems.
83+
-->
84+
一応 `catch_panic` というunstableなAPIが存在し、これによってスレッドをspawn
85+
することなくpanicを補足することはできます。
4286

87+
> 訳注: その後 `recover` -> `catch_unwind` と変更され、Rust1.9でstableになりました。
88+
89+
とはいえあくまでこれは代替手段として用いることを推奨します。現在のRustのunwind
90+
は「unwindしない」ケースに偏った最適化をしています。unwindが発生しないとわかって
91+
いれば、プログラムがunwindの**準備**をするためのランタイムコストも無くなるためです。
92+
結果として、実際にはJavaのような言語よりもunwindのコストは高くなっています。
93+
したがって通常の状況ではunwindしないようなプログラムの作成を心がけるべきです。
94+
**非常に大きな**問題の発生時やプログラミングエラーに対してのみpanicすべきです。
95+
96+
<!--
4397
Rust's unwinding strategy is not specified to be fundamentally compatible
4498
with any other language's unwinding. As such, unwinding into Rust from another
4599
language, or unwinding into another language from Rust is Undefined Behavior.
46100
You must *absolutely* catch any panics at the FFI boundary! What you do at that
47101
point is up to you, but *something* must be done. If you fail to do this,
48102
at best, your application will crash and burn. At worst, your application *won't*
49103
crash and burn, and will proceed with completely clobbered state.
104+
-->
105+
Rustのunwindの取り扱い方針は、他の言語のそれと根本から同等になるように設計されて
106+
はいません。したがって他の言語で発生したunwindががRustに波及したり、逆にRustから
107+
多言語に波及したりといった動作は未定義となっています。
108+
FFIの構築時には**絶対に**全てのpanicを境界部でキャッチしなくてはなりません。
109+
キャッチの結果どのように対処するかはプログラマ次第ですが、とにかく**何か**
110+
しなくてはなりません。そうしなければ、良くてアプリケーションがクラッシュ・炎上します。
111+
最悪のケースではアプリケーションがクラッシュ・炎上**しません**。完全にボロボロの状態
112+
のまま走り続けます。

0 commit comments

Comments
 (0)