2009/04/24
ソース幻想
中国政府によるセキュリティ関連製品のソース開示義務が話題になってて、 それじゃ難読化すればいいじゃん、というネタも出ているが、 わざわざ難読化などしなくても例えばStalinの出力のCコードを提出されたら 誰にも読めまい。言語処理系の立場からは、出力がネイティブコードだろうと バイトコードだろうと他言語だろうとやってることは根本的に大した違いは無く、 生成されたコードがCコンパイラの入力になるからといってそれをソースと呼ぶことには 違和感がある。
では実際に人間が書いたもののみをソースと認めるということにすれば良さそうだが、 それが本当に製品のバイナリのソースかどうかということは、処理系を手に入れて コンパイルしてみないとわからない。
ところが世の中には標準の処理系に不満があってマイ言語を作っちゃう人も多く、 DSLまで含めれば「標準の処理系のみ」で完結するものって意外に少ないのではなかろうか。 少なくとも私が今まで仕事で関わったプロジェクトの大半は、標準の言語処理系以外に 何らかの「言語処理系」を必要とする。(例えばautoconfはシェルスクリプトをターゲット とする言語処理系であって、その核はm4だけれど付属するpredefined macroが無いと autoconf処理系としては成立しない)。
そういう周辺処理系も含めて全部提出させればOKかっていうとそうは問屋が下ろさない。 言語処理系そのものはバイナリを許すの? ソース上無害なコードなのにコンパイル時に 怪しいコードが挿入されないという保証は?
よろしい、では言語処理系自体のソースコードも提出させることとしよう。 その全てを精査すれば怪しいコードは検出できるはずだ----ホントに?
言語処理系の多くは、「その言語自身」を使って書いてある。CコンパイラがCで かかれていたり、Scheme処理系がSchemeで書かれていたり。つまり、提出された 言語処理系のソースが本当にその言語処理系のバイナリを生成するかどうかを 確かめるには、その言語処理系のバイナリを使ってソースをコンパイルしてみるしかない。 でも、そのために渡されたバイナリ自体に細工がしてあったら、 ソースが全てを記述しているとは限らない。細工されたコンパイラのバイナリが、 無害なコンパイラのソースからコンパイラを生成する際に細工を忍び込ませることができるからだ (Ken Thompson, Reflections on Trusting Trust)。 「現在のバージョンの」ソースを一式持っている だけでは不十分なのだ。
ではどこまでのソースを持っていれば、確実に検証できるだろうか。 とりあえずCコンパイラとアセンブラくらいは全部自前で作った安心できるものがあるとして。
Gaucheのソースを一式持っているとして、そのGaucheをコンパイルするには 「その時点での最新リリース」のGaucheバイナリが必要だ。 それより古いGaucheバイナリでは、必要な機能が足りずにコンパイルできない 可能性がある。従って、
- 現在のGaucheのコンパイルには0.8.14のバイナリが必要
- 0.8.14のソースからのビルドには0.8.13のバイナリが必要…
という具合にどんどんリビジョンを遡ったソースが必要になってくる。 で、これが最初のリビジョンまで遡れば何とかなるかというとさにあらず。 初期のGaucheのビルドにはSTkのバイナリが必要なのだ。 STk自身のビルドにSTkが必要だったかどうかはもう覚えていないが、 もしそうだとすると、今度はSTkのリビジョンを同じように遡ってゆく 必要がある。
この信頼性検証の鎖は案外脆い。Gaucheの開発中に、うっかり一度でも
- 手元にチェックアウトしたGaucheのソースに新機能を追加し、ビルド/インストール。
- Gaucheのソースをその新機能を利用して書き換え、それをチェックイン
とやってしまうと、新しくチェックインされたソースをコンパイル出来るのは 私のローカルマシン中のGaucheバイナリだけということになる。 そのまま開発を続けて、新たなバージョンとしてリリースしてしまったら、 検証の鎖はそのリリースで切れてしまう。 実のところ、今までにこのミスをやらなかったという自信が無い。 一人で開発してたら気がつかないからね。
あるいは、こうやって検証の鎖をたどっていったら、今はもう手に入らない ハードウェア上で動作するソフトにつながっちゃった、っていうこともあるかもしれない。
というわけで、ソースがあれば全てわかる、っていうのはまあ間違いじゃないんだけれど、 ソフトウェアの側面だけ見ても、その命題は過去から連綿と積み上げられてきた歴史の 上に載っかってどうにか成立している、案外頼りないものなのだ。
Tags: Programming, Gauche
2009/04/21
『おくりびと』
こっちのレンタル屋にも来てたので観た。 そんで、テーマがはっきりしてきれいに様式にはまった良い脚本で、 演技も演出も基本的にはちゃんとそれに沿って作ってて完成度高いなと 思ったのだけれど、批評や感想を観ていたらそのテーマについて全然触れられて いないのであれれと思った。もちろん解釈は色々有り得るし、 私が感じた見方が特殊なのかもしれないけど、 この映画、Actingのクラスでストーリー分析したら綺麗に分析できる部類の 脚本じゃないかなあ。音楽でいえば古典派ソナタ形式、みたいな。
以下、内容に触れるので未見の方は目を細めてスクロールダウン。
-*-*-
この映画を一言でいえば、「主人公が父親を取り戻す」という話。
主人公(大悟)は幼い頃父親に捨てられ、心の底で痛切に父親を求めながら、 全力でそれを否定して生きている。大悟にその自覚はないけれど。 この引き裂かれる思いが物語を引っ張る力。 この二重性のため大悟はいわゆる「父性」--- と言ってしまうとジェンダー的にpolitically incorrectかもしれないけれど--- 自ら決断し周囲を引っ張ってゆき責任を取ること、ができずにいる。 チェロの借金を妻にも黙っていたことや、新しい仕事のことが言い出せないという 大悟の行動はそこから導かれる。この時点での大悟はなりはでかくても中身は 父親を求める子供なので、頼りなく、幼く見える演技は適切。 そういう大悟にくっついてくる妻も自らに母性を 見出せない存在。したがって映画前半で二人がちゃらちゃらしててままごとの恋愛のように 見えるのは、まったく正しい描写である。
NKエージェンシーの社長は大悟にとって父親の役割を果たす存在。 大悟が納棺師という仕事に真剣に向き合うようになったのは、表面的には 社長の厳かな儀式を観て感銘を受けたということだけれど、底に流れているのは 自分の役割を責任を持って果たすという行動を父親から教わっているわけ。 初仕事で社長が怒鳴るでしょう。社長が声を荒げるのはあそこだけだけど、 あれは父親の一喝。
で、妻が妊娠して生物的に大悟は父親になることになる。この時点で大悟の 表層意識はまだ「父親を求める自分」も「それを否定する自分」も認めてない けれど、納棺師の仕事を果たすことでより深いところで責任を取れるまでに 成長している。あるいは成長しつつある。鶴の湯のおばさんの納棺で妻が観るのは、 儀式の荘厳さ(表面)だけじゃなく、大悟の父性。
大悟のarcを考えると、大悟は納棺師の仕事をやればやるほど、 自分の中の二重性に向き合わざるを得なくなる。木下順二は「劇的」とは 「求めれば求めるほど、求めるものから離れて行ってしまう」ということだと したが、やればやるほど見たくないものに近づいてしまう大悟のarcはこの劇的な構造を 綺麗になぞっている。もっとも演出上、クライマックスまでの緊張の高まりは あまり明示的には描かれないけれど。
父の訃報により大悟の引き裂かれる自己の張力は頂点に達し、大悟は 「父親を否定する自己」を捨て「父親を求める自己」を受け入れる。 この受容に納棺の儀式が大きな役割を果たす。それまでのすべての納棺の シーンは大悟が父親を受容する儀式のための前フリである。 そして大悟が父親を受容し、石文を受け取ることで、それまでの納棺の儀式が 「送る者が死を受容し語られぬメッセージを受け取ること」という軸で 貫かれることになる。本木の演技はこの点でも一貫していたと思う。
「父親とのストーリーは余分」という評さえあったが、父親のストーリーがなければ そもそもこの映画は存在しないし、納棺の儀式を厳かに映した意味もなくなる。
ところでこういう解釈で観たとき、ふたつ不満がある。
ひとつは妻役の広末の演技の目的が少し曖昧なこと。 妻は役割上第一のAntagonistだ。AntagonistにはProtagonistと同じ問題を 持つ者と対照的な問題を持つ者が有り得るが、どちらもProtagonistの持つ問題を 別の側面から見せることで物語を明確に語る役割がある。 この脚本の場合、妻は大悟と同じ問題、つまり大人になれないという問題を抱えていて、 それを克服して母親になるという、主人公と同じ形のarcを一足先に描くと考えるのが自然だろう。 脚本上、このarcを際立たせる選択はいくつかあり得ると思うんだけど、どうやっても 実家に帰るあたりまで妻は「子供の顔」をしていて、鶴の湯の葬式のあとあたりでは 「母親の顔」へと変貌していて欲しいはず。監督もそう撮ろうとしているように見えたが、役者が そう思ってやってたかどうかよくわからなかった。
もうひとつは最後のシーンで、大悟が父の化粧を終え、振り向いて石を受け取る時に、 大悟自身の「父親の顔」をきちんと観たいな、と感じた。 もしかすると父親というテーマがくどくなりすぎると思って監督はわざと抑えたのかもしれない けれど、こういう脚本なんだから思い切っていっちゃっても良かったんじゃないかと思う。
-*-*-
以上でネタバレ終わり。
Tag: 映画
2009/04/13
デバッガが使えないパターン
少し前にprintfデバッグかデバッガ使うかっていう話がちょっと 盛り上がっていた (わたしがprintf()デバッグをしない理由から)。 まあ結局は適材適所ということになるのだけれど、どういうケースでは デバッガが(使えない|使いにくい)かっていうケースを集めとくと建設的かも。
shinhさんが ひとつケースをあげていて、これはコンパイラ1が生成したコンパイラ2が生成した コードに出てくる問題を追いかける、というもの。コンパイラ1はしっかりした 処理系でコンパイルされるのでデバッグ情報がついているけれど、コンパイラ2の デバッガ情報を出すべきコンパイラ1はそんなにしっかりしてないので、コンパイラ2中の どこがおかしなコードを出しているかはデバッガじゃ追えない、という話。
以前ここでも書いた、VMへコンパイルする処理系のデバッグにもちょっと似ている。 デバッガで追えるのはVMの動作なんだけれど、それは同じ所をぐるぐる回ってるだけに 見える(レイヤが違う)。まあshinhさんのtccのケースの方は「ぐるぐる回っているVM」 自体が無くなっちゃうのでもっと大変だけど。
あと、私自身がよく当たるケースは、外部コンポーネントと実時間で協調してないと 再現しないようなバグ。ネットワークパケット送ったら一定時間内に返事が来てそれに 返信しなくちゃだめ、とか。パケット送ったあとブレークポイントで止めてると タイムリーに返事が返せないので状況が再現できない。相手も自分の制御下にあれば 多少はなんとかしようがあるんだけど、まったく制御できない第三者の作ったやつと 通信しなくちゃならないことも多いんで困りもの。(吉岡さんもカーネルハックしてたら そういうケースに当たることはあるんじゃないかと思うんだけれど、 デバッガで何とかするうまいテクニックがあるのかなあ。Debug Hacksに書いてあるかな?)
明らかな症状が出る時点では既に痕跡が消えているケース、というのもある。 センサ入力を1/30秒ごとに取って行列演算に使ってるんだけれど、どっかで 演算結果がおかしくなる。本当の原因は数フレーム前のセンサ入力なんだけれど、 はっきりとおかしい結果が出る時には数フレーム前の状態は上書きされちゃってる、とか。 異常が「画面を目で見ればわかる」けれども、数値的にどういう条件でそうなるのか わからないっていうのもよくあるな。1フレームだけポリゴンがパカッとするんで、 目で見てておかしいと思ってすかさず止めても、その時にはメモリは更新されてる。 本当の原因となる条件がわかれば条件付きブレークポイントをしかけられるけど、 そもそもそれがわからない段階でどうするかっていうと、いろんな状態をダンプして にらめっこするしかない。
デバッガにも簡単な条件の元で状態を出力する機能はあるけれど、だいたい こういう厄介なケースってかなり複雑な条件で出力を絞らないと ダンプ量が多くなりすぎて役に立たないことが多い。
外部コンポーネントが関わるケースについては、最終的には外部コンポーネントを エミュレートするプログラムを作っちゃうしかない。 わりとそういうケースが多いんで、私自身の印象として、デバッグというのは 単にprintfやらデバッガを使って潜んでいるバグを探すのではなく、 むしろシステムをうまく作り替えて特定の場所にバグを追い込むようにして、 そこに罠を張って待ち構えているという感覚がある。 デバッガ専門家の方の意見も聞きたいところ。
状態が上書きされちゃうケースについては、理想的には メモリを仮想化してブレーク時から時間を遡れるようになってるのが良いと思う。 言語的には上書きしてるんだけれど、実は別の場所に書いていて 元の内容も保存されてる、という感じ。
逆にprintfが使えないパターンとして私が体験したのは、 ビルドに5分かかるプロジェクト (CPUプールを使ってビルド自体は並列に 進むようになってたんだけど、最後のリンクのところで4分くらいかかっちゃうので あまり効果が無かった)。ところがこいつが、「問題の所在が多数フレームに またがった値の変遷を調べないとわからない」というパターンのやつで、 デバッガも使いづらい。結局、問題が出るコンポーネントだけを 別プロセスで回して、本体からソケット経由でデータを流して処理して 本体に返すという仕組みを作った。当該コンポーネントのビルドは 容易なのでデバッグサイクルを速く回すことができた。
(追記 2009/04/14 12:01:38 PDT): おお、shinhさんから反応が。 Window Managerのデバッグが難しいというのは、 「デバッガが実行時にデバッギの提供する機能を使う場合」と言えるかも。 なんかコンソールゲーム機いじってた時にこのパターンに時々当たったような 気がする。詳しいことは忘れちゃったけど。
Tag: Programming
2009/03/24
コードと別にドキュメントを書く意味
昨日の続き。
異なる意味や構造を持つ2つの言語で同じことを書くと相補的に文章の正確さを高めることができるということだ。ソフトウェア開発の各段階で、コーディング言語以外にいろいろな言語を使うことの意義はそこにある。
私がコードと同時にドキュメントを重視するもうひとつの理由がこれだ。
コードは動かなければ意味が無い。動かすには、実装の詳細に気を配らないとならない。 設計上は「どちらでも良い」選択肢があったとしても、動くコードにするためには どちらかを選ばないとならない。そうやってとにかく具体的に、末端まで目を配っていると、 大局的、抽象的な視点を忘れがちになる。 そこで、実装の詳細の迷路に足を取られて大局的な方向があやふやになってきた あたりでドキュメントを書いてみると、ふっと全体の見通しが良くなったり、 実装の抜けを発見できたりする。あるいはそもそも「ドキュメントがうまく書けない」 ことから、自分が問題をちゃんと理解していないことに気づいたりする。
あるいはこういう考え方もできる。実現したい「何か」は空間上の一点だ。 それを通る直線が無数にあるように、実装も無数にあり得る。たまたま ある実装を選んだとする。ところが、後からその実装を見た人には、 どこが本当に通りたかった点なのかがわからない。ここでドキュメントという もう一本別の直線があれば、その交点として、設計者の意図を明確に 示すことができる。
(ソースコード内にドキュメントを埋め込むのを私が好まないのは、 ひとつにはこれが理由だ。 コードを書くモードと同じモードでドキュメントを書くと、 直線はほとんど重なってしまい、交点を明確に示せない。 プトロコルとか暗号アルゴリズムの仕様を詰めるときに、その仕様に 基づいた複数の実装を独立して開発してみるように、 コードとドキュメントは別の出発点から書いた方が、 より相補的に価値を高めることができると思う。)
Tag: Programming
2009/03/23
国語を「文系」に入れるのやめにしない?
「わたしの持論ですが、国語ができる(=日本語できちんとした文章が書ける)人じゃないとプログラムは書けない。これは非常に重要です」
基本的には同意、というより当然すぎて言うまでもないことじゃないかとさえ 思うのだけれど、これをわざわざ言わなくちゃならないのって、国語教育の問題 なんじゃないかという気がした。
「自然言語を使って、自分の言いたいことを一貫性を持って記述・発表できる、 またそうやって記述された文章や語られた言葉をきちんと理解できる」っていう能力は、 どの方面に進むにせよ、現代社会の中で生きてゆくには重要な能力だ。 それに対して、文学小説や古典の読解(より一般的には文脈を重視したテキスト解釈) というのはもっと特殊で、社会的な話(文学史、思想史、哲学史etc)との関わりが 深くなったり、情緒的な「読み」を要求されたりする。
今の国語はこの両方がいっしょくたにひとつの教科に放り込まれている。 これが不幸の元ではなかろうか。
文系理系という分類は嫌なのだが、性向として「人の営みにより興味を惹かれるタイプ」 と「自然の営みにより興味を惹かれるタイプ」というのはあると思う。私は高校くらいまで あまり人に興味が無くて、だから人の営みを主に扱う社会という教科はずっと苦手だった。
で、「人の営み」に興味を持てない学生からすると、上に挙げた国語の二つの要素のうち 後者の話は全然面白くないんだよね。でもそれが出来ないと国語という教科が苦手に なって、前者もやろうと思わなくなる。あるいは前者にも苦手意識を持ってしまう。 それは非常にまずいんじゃないか。
もし、前者の「自然言語による表現とその理解」が、「基礎語学」とか「語学表現」 みたいな教科で、後者のテキスト解釈その他が「文学」という別の教科になってたら、 学生の受け取り方はかなり違ってくるのではなかろうか。「国語」のサブカテゴリとして 分かれるのではなく、「社会」と「英語」が別教科であるのと同じレベルで別教科。 文系って言いたい人は「文学」の方をやればいい。 一方「語学表現」は全員必修で、論説文の読解や作文以外に、 口頭発表や議論のテクニックも含める。 というか極端な話、簡単な英語によるディスカッションという題材もこっちに 放り込んじゃったっていいくらい。 あるいは、「言葉の通じない環境に一人とり残された。あなたのミッションは○○である。 どうにかして周囲とコミュニケーションを取ってそのミッションを実行するには、 何を伝えることが必要か考えよ」みたいな課題を入れるとか。
教育現場のことを何も知らんので、実はこういう話は前からあるんだけど 実現できない理由があるのかもしれない。
だけれども。
学生の頃、バイトや研究で色々なソフトウェアを使いながら感じたのは、 英語と日本語の情報量の圧倒的な差だった。英語圏発のソフトウェアだから 英語の情報が多い、という話ではない。ソフトウェアと、それに関する良質なドキュメントの 量の比率である。とにかく英語圏のプログラマってのはドキュメントをもりもり書くんだなあ、 すげえなあ、という印象だった。しかもそれがテクニカルな意味でわかりやすい。 学生が実験的に作ったようなソフトであってもカッコいいマニュアルが揃っていたりする。 そして、ドキュメントがちゃんとしていないソフトウェアは広く使われるように なりにくいし、また忘れ去られるのも速いような印象がある。
語学表現に苦手意識を持ったままのプログラマは、プログラムという作品を産み出すに あたって大きなハンディキャップを背負ってしまっているようなものではないだろうか。
Tag: Career

Comment (1)