2010-12-30

Old New Thing: エスパーデバッグ:ファイルをクリップボードにコピーしてペーストしたら、昔のファイルが現れた

Psychic debugging: When I copy a file to the clipboard and then paste it, I get an old version of the file - The Old New Thing - Site Home - MSDN Blogs

ある顧客が、以下のような不思議な質問をしてきた。

あるコンピューターから別のコンピューターに、ネットワーク越しにテキストファイルをコピーしたんだけどさ、コピーが終わってネットワークディレクトリーをみてみたら、まあ、たしかに同じ名前のファイルはあるんだけどさ、タイムスタンプがまるで違っているわけよ。不思議に思ってファイルを開いてみると、コピーしたファイルとは違うんだ。何故か、昨日のファイルなんだな、これが。今日の変更が含まれていないんだよ。俺はまだ、画面上にコピー元とコピー先のフォルダを開いてるし、もちろん、コピーしたファイルは、ちゃんと変更したものであって、バックアップディレクトリのヤツじゃない。

も一度やってみたんだけどさ、やっぱ古いファイルがコピーされる。よく分からんけど、ドラッグ&ドロップを使ったら、問題はない。Ctrl+CとCtrl+Vを使った時だけ問題が起こる。何とかしてくれ。

これは実に訳の分からない問題だ。ひとつの可能性としては、顧客は間違って以前のバージョンのフォルダー(訳注:Volume Shadow Copyによるもの)からコピーしているのかもしれない。さらに別の仮説を立てる前に、顧客が追加情報を送ってきた。

何か問題を絞り込めた気がする。俺のインストールしてるクリップボードツールとなにか関係があるんだ。ツール使ってなければ、問題はないみたい。なんでツールを使ってたら、エクスプローラーはがタイムマシーンみたいな事をしてくれるんだ? この古いファイルは、パソコンの中にないんだけど、エクスプローラーはどっから取ってきてんだ?

他のMS社員は、I/Oトレースログを取るなどして、問題を調査した。興味深いことに、I/Oトレースでは、エクスプローラーはコピー元とコピー先のファイルを開いて、コピー先に対してWriteFile呼び出しを多数発行しているのに対し、コピー元に対して、ReadFileを一切呼び出していないのであった。「以前のバージョン」も確認してみたが、「以前のバージョン」のファイルは存在しなかった。まるで、無からファイル内容を生成しているようであった。

他のMS社員が次第に調査を諦める中、突然、僕の頭は震え、トランス状態に陥った。僕のエスパー能力が、勝手に喉から声を発した。それは一瞬の出来事で、僕は眼を閉じて、すぐさま現実世界に戻ってきた。さて、僕はぶっきらぼうに、以下のようにタイプした。未だに返事を覚えているのだ。

私のエスパー能力によると、このクリップボードプログラムは、クリップボードの中身を仮想化している。つまり、クリップボードの中身を勝手に書き換えている。そして、ファイルに対するクリップボードのペースト操作に対し、元の中身に差し戻そうとして、失敗している。

クリップボード拡張ユーティリティを調べると、古いクリップボードの中身を記録する機能を提供している。MS Officeクリップボードに似た機能だ。I/O操作の中に、最終アクセス日時へのクエリーが含まれていた。

問題はこれだ。

Windows Vistaからは、最終アクセス日時はデフォルトでアップデートされなくなった。どうやらプログラムは、ファイルがアクセスされていないという情報から、ファイルが更新されていないと判断し、ファイルの中身を、内部のキャッシュから作り出しているのだ。この問題を手っ取り早く解決するには、最終アクセス日時のかわりに、最終更新日時を使うとよい。

やれやれ、私のエスパー能力が正しいということを、またもや証明してしまった。ところで、エスパー能力が正しいということは、代償であるということに気がついた。以前より、さらに大勢の人々が、不思議な問題をデバッグしてくれと頼み込んでくるようになったのだ。

ちなみに、最終アクセス日時がデフォルトでアップデートされなくなった理由は、NTFSのパフォーマンス向上のためである。そもそも、最終アクセス日時の精度は、一時間らしい。

No comments: