2025/10/19 03:39 Progress on defeating lifetime-end pointer zapping

ロボ子、今日はちょっと込み入った話をするのじゃ。C++とCの仕様変更に関わる、「lifetime-end-pointer-zapping problem」についてじゃ。

lifetime-end-pointer-zapping problem、ですか。初めて聞く言葉です。具体的にはどのような問題なのでしょうか?

簡単に言うと、マルチスレッドのコードで、アトミックなLIFOスタックを使う時に、メモリの再利用が原因で、ポインタの出所情報(provenance)がおかしくなることがあるのじゃ。その結果、未定義の動作を引き起こす可能性がある、というわけじゃ。

アトミックなLIFOスタックで、メモリ再利用が原因でポインタのprovenanceが問題になる、と。少し難しいですが、理解しようと努めます。

例えば、linked listとして実装されたLIFOスタックで、メモリが再利用されると、異なるprovenanceを持つポインタが、ビット単位で同じアドレスを持つことがあるのじゃ。これはマズいぞ。

異なるprovenanceのポインタが同じアドレスを持つ、ですか。それが未定義の動作に繋がるのですね。

そう。コンパイラはまだこの未定義の動作を利用していないけど、将来的に問題になる可能性があるから、今のうちに解決策を考えておこう、というのが今回の話じゃ。

なるほど。それで、具体的な提案としてはどのようなものがあるのでしょうか?

Davis Herringさんの「angelic provenance」という提案があってな。これは、コンパイラが未定義の動作を回避できる場合、そのポインタprovenanceを選択することを義務付けるというものじゃ。

コンパイラが未定義の動作を回避できる場合に、適切なprovenanceを選択する、ですか。なんだか魔法みたいですね。

さらにMcKenneyさんが、アトミック型からのロードを整数からの変換として扱い、angelic provenanceルールを適用して、LIFOスタックが定義された動作となるようにするという提案もしているのじゃ。

アトミック型からのロードを整数からの変換として扱う、ですか。それによってLIFOスタックの動作が定義されるようになるのですね。

あと、無効なポインタの書き込み時に、provenance情報が利用できなくても、ポインタの実際のビットが書き込まれることを要求するという提案もあるぞ。

無効なポインタの書き込み時に、ポインタのビットが書き込まれることを保証する、と。それも重要なポイントですね。

この問題はRustにも関連があるのじゃ。Rustで同様の提案を実装する際に、angelic choiceとdemonic choiceのリオーダリングが問題になる可能性があると指摘されているぞ。

Rustでも同様の問題が起こりうるのですね。angelic choiceとdemonic choiceのリオーダリング、ですか。最適化に関わる部分でしょうか?

そう。リオーダリングを禁止すると、最適化が妨げられる可能性があるのじゃ。C++がポインタ演算のルールを緩和した場合、Rustと同様の問題に直面する可能性もあるぞ。

最適化と未定義動作の回避、両方のバランスを取るのが難しいのですね。

まさにそうじゃ。今後の課題は山積みじゃな。しかし、こういった地道な努力が、より安全で効率的なソフトウェア開発に繋がるのじゃ。

はい、博士。私も微力ながら、貢献できるよう頑張ります。

ところでロボ子、ポインタのprovenanceって、なんだかお菓子の出所みたいじゃな。どこのお店で買ったか、みたいな…って、全然違うか!

博士、それはちょっと無理がありますよ!(笑)
⚠️この記事は生成AIによるコンテンツを含み、ハルシネーションの可能性があります。