2019/11/18

pkgin full-upgradeは何をしようとしているんだろうか

dynabook SS SX/15AにNetBSD/i386を入れて使用しています。パッケージの2019Q1を入れていましたが、2019Q2が出ているのでpkginで更新しようと考えています。

pkgin full-upgradeで一括して入れ換えてしまおうと思っていますが、ファイル転送でstallしてしまいます。pkginにはオプション「-d」を指定することで、ファイル転送だけをおこなうことができるようです。ところがファイル転送で頻繁にstallするので、なかなかインストールまで辿りつきません。

pkginは、更新を始める前に対象となるファイル名(.tgzファイル) を表示します。その情報を加工して、pkginを使わず、ftpコマンドでファイルをダウンロードしておくことにしました。必要なファイルが/var/db/pkgin/cacheに存在すれば、pkginとしてはインストールしてくれるようです。

それは良いのですが、更新対象となるファイルが異常に多すぎる気がします。例えば、今までTeXはインストールしていなかったのに、更新対象にしています。細かくは確認していませんが、他にも謎の更新対象があるのではないかと思います。

どうしてこういうことになるんでしょう。

NetBSDのpkginでstallする

dynabook SS SX/15AにNetBSD/i386を入れて使用しています。以前は、OS本体もパッケージもcurrentのソースから自前でビルドしていました。しかしビルド時間がかかりすぎる(1週間以上かかります)し、それだけならまだしも、無線LANの接続が切れたり、カーネルパニックが発生したりして、何度もリブートし再開するはめに陥るので、ビルド済みのバイナリを入れるだけに方針を転換しました。

数か月前にpkgを入れた時は2019Q1だったのですが、2019Q2が出ているので、更新することにしました。pkginを使って更新することにしているので「pkgin full-upgrade」 をおこないました。更新対象のパッケージ(.tgzファイル)をダウンロードしてからインストールが始まる筈なのですが、ファイル転送中にstall状態になります。たまに発生するなら我慢もできますが、10分もしないうちに発生するので、とても困ります。

stallしてファイル転送できなかったファイルは、再度pkginを実行すると再転送しようとするのですが、そこでまたstallします。勘弁してくれという気持ちになります。しかしそのファイルを、本家またはミラーサイトからftpでダウンロードする分には、何も問題なく転送できます。うまくいって結構なことなのですが、なぜpkginではstallするのに、ftpなら問題ないのでしょうか。

 ハードウェアが旧いので、あちこちにガタがきている可能性は否定できません。はっきり確認する手段がないので憶測ですが、ハードウェアが旧いことだけが原因ではないような気がします。

2019/11/16

FreeBSD/amd64を12.1-RELEASEに更新した

ThinkPad E530cにFreeBSD/amd64を入れています。先日12.1-RELEASEがアナウンスされたので12.0-RELEASEから更新しました。昔はソースコードを自前でビルドしていましたが、今はfreebsd-updateを使うことにしています。

手順は次の通りです。これらの作業はシングルユーザーでおこないました。リブート前に要した時間が1時間半くらい、リブート後は30分ほどで、合計して2時間くらいかかりました。
  1. freebsd-update -r 12.1-RELEASE upgrade
  2. freebsd-update install
  3. リブート 
  4. freebsd-update install
  5. freebsd-update install

2019/11/14

NetBSDのMATEデスクトップ環境で「シャットダウン」メニューが無くなった気がする

dynabook SS SX/15AのOSをNetBSD/i386に入れ換えて使っています。以前はOSもpkgもカレントのソースコードを取得してきて自前でビルドしていました。しかし今年6月頃にpkgを入れ替えようとして、ハードウェアのディスク不足や不調などの原因により、かなり苦労したため、ビルド済みのバイナリを取得してインストールする方針に転換しました。

さらにOS本体もカレントのソースコードを自前でビルドしていたのを止めようと考えていたので、NetBSD 8.1の公式リリース版を使うことにしました。インストールされていたOSがNetBSD 8.1よりは微妙に新しいカレントだったので、バージョンが戻ることになりまる。トラブルが発生しないか心配だったのですが、無事にNetBSD 8.1になったようです。

普段使っているアプリケーションの動作確認をしてみましたが、問題なさそうです。

ただし1つだけ、これまでとは動きが異なる箇所があります。MATEデスクトップ環境を利用していて、メニューに「シャットダウンする」というのがあったはずなのですが、見当たりません。メニューからシャットダウンできなくても、他に方法はいくらでもあるので実害はないのですが、気になります。

MATEデスクトップ環境に限らず、今どきのデスクトップ環境はDbusやらPolicyKitやらを使っていて、問題解決のために何から手をつけたら良いのか、よく分かりません。

2019/11/13

「初心者マーク」と「高齢者マーク」

「初心者マーク」や「高齢者マーク」が貼られている車を見るのは日常的ですが、先日両方貼られた車を目撃しました。あまり見かけない光景です。

「初心者マーク」は「初心者運転標識」というのが正式名称で、道路交通法第71条の5で次のように定められています。免許取得後1年間は義務ですが、それ以降の規定はないため、掲示できなくなるわけではないようです。
第七十一条の五 第八十四条第三項の準中型自動車免許を受けた者で、当該準中型自動車免許を受けていた期間(当該免許の効力が停止されていた期間を除く。)が通算して一年に達しないもの(当該免許を受けた日前六月以内に準中型自動車免許を受けていたことがある者その他の者で政令で定めるもの及び同項の普通自動車免許を現に受けており、かつ、現に受けている準中型自動車免許を受けた日前に当該普通自動車免許を受けていた期間(当該免許の効力が停止されていた期間を除く。)が通算して二年以上である者を除く。)は、内閣府令で定めるところにより準中型自動車の前面及び後面に内閣府令で定める様式の標識を付けないで準中型自動車を運転してはならない。

さて「高齢者マーク」は「高齢運転者標識」というのが正式名称で、道路交通法附則第22条で次のように定められているため、当面は努力義務ということのようです。もちろん掲示しても良いわけです。
第二十二条 第七十一条の五第三項の規定は、当分の間、適用しない。この場合において、同条第四項中「七十歳以上七十五歳未満」とあるのは、「七十歳以上」とする。
それでは両方とも貼られているというのは、どのような状況なのでしょうか。運転者の年齢が70歳以上(高齢者マーク)であり、かつ免許取得後1年以内(初心者マーク)なら、そうなるのかもしれませんが、あまり現実的な想定ではないでしょう。

可能性の高い想定としては、その車を家族で共用していて、マークを剥がし忘れた場合でしょうか。

正確な答えは、そのような車を運転している本人に尋ねるしかないとは思います。

2019/11/11

「Std Math Keyboard」を使わなくてもよいかもしれない

『いつでも どこでも スマホで数学』を読みながらMoA(Maxima on Android)の使い方に習熟しようと思っています。まずは「Chapter 1 Maximaの概要とインストール」の記述に従ってアプリのインストールしてみました。入力は「Std Math Keyboard」を推奨していますが、気になる点があります。書籍でも次のように書かれており、懸念が示されています。
ONにすると、「すべての入力内容の収集をアプリに許可することになるがかまわないか?」という趣旨の注意書きが表示され、ちょっと同意するのをためらいます。
このような注意書きは気になりますが、はたしてMoAは「Std Math Keyboard」がないと不便なのか、それとも無くても構わないのか、実際に使ってみて判断することにしました。

Android9では「iWnn IME」以外にも「Gboard」が使えます。「Std Math Keyboard」なら数式で用いる記号類や英数字が入力しやすいとは思いますが、「Gboard」で数式を入力するのが使いものにならないという訳でもないような気がします。「Std Math Keyboard」が圧倒的に優位にたっているとも思えません。

今後は「Gboard」を利用することにして、「Std Math Keyboard」はアンインストールしようかと思います。

2019/11/10

「名詞+だ」は良くて、「形容詞+だ」は不可なのはナゼ?

日本語の文末は敬体(です・ます調)と常体(だ・である調)があります。それらは、文の用いられる状況に応じて使い分けられますが、相互に交換できるはずです。例えば、「私は○○××です」でも良いし、「私は○○××だ」でも構わないでしょう。

何かで耳にしたのですが、「楽しい」のような形容詞では「楽しいです」とは言えても、「楽しいだ」とか「楽しいである」とは言わないのですが、これは何故でしょうか?名詞であれば「東京駅です」でも「東京駅だ」でも構わないわけです。「形容詞+だ」が認められないのは、単に聞きなれないというだけ問題なのでしょうか。

 もっとも「形容詞+です」のような表現(「嬉しいです」とか「楽しいです」)は、印象として幼さを感じます。例えば小学生の文章「今日は遠足で楽しかったです」のような印象を受けるので、自分で使うのは避けて、別の表現を探すようにしています。

英語のラストネームの4パターン

the japan times alphaの2019年11月8日号に掲載されている「The history of English last names -- every name tells a story!」(Kip Cates)では、英語のラストネームの由来を4パターンに分類しています。それは次の通りです。
  1. Some are based on occupations.
  2. Some names refer to the places where people lived.
  3. Some names are based on family relationships.
  4. Some last names are based on personal traits.

日本人の名字は膨大だと言われています。30万種とも言われますが異論(【年末緊急発表】日本人の名字30万種は事実か?)もあるようです。実際の数を定義するのは難しいとは思いますが、種類が多いのは間違いないでしょう。日本人の名字の由来を何パターンに分類できるのかわかりませんが、地名由来が多いのではないかと思います。

古代の姓(源平藤橘が有名ですが、4種類だけだった訳ではありません)のままでは他者との区別ができないので、自然に地名で区別するようになっていったと思われます。区別できるなら地名でなくても良いわけで、生業や官職などもあると思いますが、比率で考えれば地名由来が圧倒的ではないかと思います。

Android版Maxima

最近長年使い続けていたガラケーからAndroidのスマホに移行しました。これも時代の流れなのかと思います。人によってはスマホがあればPCは要らないとも言いますが、僕は逆にPCがあるのでスマホの利用は最小限にしておきたいです。

僕が最もスマホの利点を感じるのは、外出先でWebを参照したい場合です。ガラケーでもWebを参照できない訳ではありませんでしたが、あまり使いやすくはありませんでした。さらに最近では無料Wi-Fiの提供場所が増えてきつつあり、ありがたいと思います。スマホが登場する前から、世間ではラップトップPCやらノートPCやらを利用しようとしていましたが、手軽に利用できるとは言い難かったと思います。出先で多量の文書を書いたりするのであれば今でもノートPC以外の選択肢はないと思いますが、Webを見る程度であればスマホで十分ではないかと思います。

スマホでゲームをしたり音楽や動画を視聴したりすることは考えていないのですが、その代わりにスマホで何が出来るのかを探ろうと思っています。すると何とMaximaが使えるという情報を見つけました。

Maxima on Androidというアプリがあるようなのですが、『いつでも・どこでも・スマホで数学』(梅野 善雄)という本が森北出版から出ています。早速買ってみました。Maximaのマニュアル替わりにも使えそうです。

Maxima on Android(MoAと呼ぶらしい) では文字入力に「Std Math Keyboard」というアプリを使うのを推奨しているようです。その方が数式が入力しやすいそうなのですが、書籍の文章中にある画像を見ている限り、それほどでもなさそうな気がします。もっとも先入観では判断を誤るので、使ってみてから判断しようと思います。使いにくければ使わなければ良いだけのことです。

2019/10/28

スマホの連絡先とPC上のGoogleアカウントの連絡先

2019年11月末で利用していたガラケーの一部機能が使えなくなるとの連絡がきたので、スマホに機種変更しました。とにかく初体験なので、慣れない事ばかりです。設定は徐々にやっていけばいいのですが、少なくとも電話の受発信ができるようにしておくのは最優先です。

携帯で使っていた電話帳はmicroSDカード経由でスマホに持ち込みました。携帯の機能が旧いため、電話帳を全件保存することができず、1件ずつエクスポートしなければならなくて面倒でした。 スマホの連絡先に取り込んだ後は、Googleアカウントの連絡先と同期しようと思っています。同期させる設定は簡単ですが、Googleアカウント側で連絡先を編集すると、スマホ側の情報と齟齬が生じます。それは良いのですが、スマホ側の連絡先の表示が乱れてしまうので困ってしまいました。

結局スマホ側の連絡先の情報を全て消して、常にGoogleアカウント側の連絡先が参照されるようにして解決しました。

Googleアカウント側の連絡先をWindows10上で編集していて気付いたのですが、表示される項目(特にラベル)の見え方が、スマホ側と違います。またラベルを設定しても、スマホ側では参照できない箇所もあり、どのように使えばいいのか模索中です。

2019/10/17

キャロル・グラック『戦争の記憶』を読んで

Webで見かけた何かの記事で紹介されていた『戦争の記憶』(キャロル・グラック)を読んでみました。著者のCarol Gluckは日本近現代史などを専門としていますが、米国生まれです。日本近現代史を専門にしている理由は分かりません。

本書は副題に「コロンビア大学特別講義―学生との対話―」とあるように、学生の対話を活字化しているものです。「講義」と言っても、日本の大学のように学生が先生の講義を拝聴している訳ではなく、教師が学生に質問を投げかけると、学生同士が互いに議論を深めていくというスタイルです。

扱う話題は日本近現代史に関わる事柄ですが、学生側が(日本人もいるようですが)米国やアジアなど「世界中」からきています。流石に大学なので、議論で扱う内容について全く無知という事はなく、何らかの素養はあるはずです。しかし知識の深浅や、興味の対象などについて、日本人が日本近現代史について語る場合とは違った切り口からアプローチしているので、興味深いです。

「歴史的事実」という意味の歴史であれば、世界中どこでも同じはずです(とは言え、つい最近の事柄であってさえも「歴史的事実」を明らかにするのは、それほど容易ではありません)。しかし「歴史的事実」の幾つかを拾い出して再構成した「歴史の記憶」という意味の歴史では、そのような記憶が必要とされる事情が背後に潜んでいることが、本書で学べました。

口癖

癖というのは自分では気づき難く、他人が気がつくと言われますが、口癖もそうでしょう。よく知られていることですが、話を「やっぱり、」で始める人がいます。テレビの街頭インタビューでも、何か意見を言うたびに、まず最初の一言が「やっぱり」から始まる人は、少なくありません。

こういう口癖は、気になるかと言えば、気にならなくもないのですが、それほど深刻に不快感がある訳ではありません。

これに比べると、開口一番に「いや、だから、」で始まる口癖は、もう少し強い嫌悪感があります。何かの意見を交わす場合でも、こちらの発言が終わり相手が話し始めるときに、まず「いや、だから、」と言われると、あまり良い気持ちはしません。

相手からすれば、単なる口癖に過ぎず、それほど意味がないのかもしれません。話始めるときに、ちょっと咳ばらいをするとか、(昔の大平首相のように)「えー」とか「あー」とか、何らかの音を出しているだけなのかもしれません。

ともかく、気にならない口癖と、気になる口癖は、あると思います。

2019/10/07

ネットワーク物理層における1500バイトの謎

TCP/IPの勉強をしようと思って『TCP/IP Illustrated, Volume 1』を買いました(古本ですが)。最初から順番に読んでいて、「2 Link Layer」を読み始めました。ここには「Figure 2.1 IEEE 802.2/802.3 encapsulation (RFC 1042) and Ethernet encapsulation (RFC 894)」が掲載されています。この図を見ると、IEEE構造では2バイトのlengthがあり、Ethernet構造には2バイトのtypeがあります。ここについて、本文では次のように書かれています。
Fortunately none of the valid 802 length values is the same as the Ethernet type values, making the two frame formats distinguishable.
これは要するに、Ethernetであればtypeに0x0800(IP datagramの場合)が入りますが、IEEEではlengthとして扱われるものの、0x0800を10進数に換算すると2,048になり最大長の1,500バイトを超えているので、現実的にはあり得ないという事だと思います。従ってtypeとlengthは異なる扱いをするフィールドでありながら、混同されることは無いという、よく考えると不思議な構造になっています。

混同されることがないのは「lengthで表されるデータ部の最大長が1,500である」という事実にかかっています。しかし最大長が1,500になっているのは「決め事」ではないのでしょう。どのような経緯で1,500になっているのか、気になるところです。

OSI参照モデルとリングプロテクション

コンピュータネットワークの勉強をすると「OSI参照モデル」の話が出てきます。物理層からアプリケーション層までの7層構造です。これは物理法則とは違うので、要するに「決め事」だと思います。今日の世界で最も普及していると思われるTCP/IPネットワークは4層で構成されています。それでもインターネットはうまくいっているようなので、7層でなければならない訳ではないと思います。しかし、あえて忠実に7層で実装したネットワークは、何があるのでしょうか。やはり7層でなければならない積極的な理由があるのでしょうか。気になります。

OSIの7層モデルを考えていたら、インテルのCPUは4レベルの「リングプロテクション」 を持っていることを思い出しました。しかし普及しているOSは、ユーザモードとカーネルモードしかないので、2レベルあれば十分な訳です。CPUを作る側として、もしかすると2レベル以上を必要とするOSが存在した場合に「インテルのCPUが選択される候補から落ちる」のを避けたかったのかもしれません。そうならば、4レベルと言わず、8レベルでも16レベルでも、もっとレベル数の多い(バームクーヘンみたいな)設計にすることも(観念的には)可能でしょうが、やたらとリングプロテクションのレベルを増やしても無駄ということでしょう。こちらも「決め事」ということなのだと思います。

2019/10/04

Windows10 1903の不具合

自宅のデスクトップPCではWindows10を使用しています。約半年ごとに現れる更新も適用してきました。今春登場した1903もインストール出来次第インストールしようと思っていましたが、なかなか準備完了の通知が出てきません(これまではインストール準備ができましたというポップアップが出ていたので、それを待っていたのです)。遅いなと思っていたら、Webで「「Windows 10 May 2019 Update(バージョン1903)」がすべてのユーザーに対して解放」という記事を見つけました。そろそろポップアップが出るかと思ったら、一向に現れる気配がないので「設定」を見たところ、「準備が出来ています」というメッセージが出ていました。もうポップアップを出さないようになったのでしょうか?

ともかく1903をインストールできるようなので、空いている時間を見計らってインストールしました。多少時間はかかりましたが、問題なく終わりました。1903にあげてからログインして、普段の操作をしてみましたが、特に問題はなさそうでした。若干消えている設定はありましたが、許容範囲だし、今回の更新は無難に終了したと(当初は) 思いました。

1903が登場してから半年ほど過ぎているので、累積パッチがインストール準備中になっています。これを入れておこうとおもったのですが、どうやら、これをインストールしてから数々の不具合に遭遇する羽目になりました。

よく使うアプリケーションをタスクバーにピン留めしていたのですが、起動しなくなりました。この時点では軽微なトラブルかと思ったので、いったんピン留めを外して、再度ピン留めすれば良いと考えていました。ところが「タスクバーにピン留めする」というメニューは出るのに、タスクバーにアイコンが現れません。再起動しても同様です。ショートカットをドラッグして落としてみても駄目でした。

タスクバーにアプリケーションをピン留めしておかなくても、スタートメニューから起動するとか、デスクトップにショートカットを置いておくなどの対処も出来なくはありません。しかしよく使うアプリケーションだからこそ、素早く起動させようとしてタスクバーにピン留めしていたのです。もしかすると、将来のパッチで直るかもしれませんが、何時になるか分かりませんし、当面の対処方法としてQuick Launchを使うことにしました。これまでと同じように使うことができるので、これで良しとします。

さらに困ったのが「クイックリンク」が動かなくなったことです。スタートメニューにカーソルを持ってきて右クリックするか、WindowsロゴキーとXを同時に押すと、メニューが現れていたのに、これも全く動かなくなりました。これまではコマンドプロンプトを出すのに、この機能を頻繁に使っていたので、動かないとなるとスタートメニューから起動させることになりますが、厄介です。これも将来は修正されるかもしれませんが、何時のことになるでしょう。当面はQuick Launchでしのぐことになります。

気が付いているところでは、他にも妙なエラーダイアログが出てきますが、だからどうしろというんだという感想しかありません。対処法もないので、いつか直るのを待つしかなさそうです。

もしかすると気が付いていない不具合が他にも多々あるんじゃないかという気がしてきました。

2019/10/03

10月からスマホが値上がりした

現在はガラケーを使っていますが、今年(2019年)11月に一部機能が利用できなくなるという連絡が昨年末にありました。機能が全て利用できなくなる訳ではないようですが、問題が起きる可能性が残るので、機種変更してもらいたいようです。

これまでスマホを利用してきませんでしたが、これを機会にスマホにしようかと考えています。

これまでスマホにしてこなかった理由のひとつが、料金が高いことです。ガラケーは殆ど使っておらず、月々の支払いはとても安く済んでいます。一方でスマホにすると、これまでよりは月々の支払額がかなり高くなる恐れがあり、二の足を踏んでいました。ところが今年6月にガラケーからスマホに切り替える利用者向けの新プランが発表され、これまでのガラケーの支払額と同程度になる可能性がでてきました。

料金プランの問題が解決しそうなので、次に考えることは端末に何を選ぶかです。それほどヘビーな使い方はしないと思うので、10万以上もするような端末を選ぶ必要はありません。しかし激安な端末にするのも躊躇するところです。どうしようかと公式サイトを見ていたら、数年前にはフラッグシップモデルだったものが、新製品が出たことにより値段が下がっている端末を見つけました。同メーカのエントリモデルが3万弱なのに比べ、旧いフラッグシップモデルが3万強だったので、これに決めようと考えていました。

総務省の指導なのか、9月には契約の2年縛りがないプランが始まりました。11月までにはガラケーからスマホに切り替える必要があるので、スケジュールに余裕がありそうな10月下旬頃にはスマホに切り替えようと思っていました。

10月になり、回線と端末のセット割引が禁止されたそうで、スマホの値段が変わりました。改めて値段を確認すると、旧いフラッグシップモデルは10万弱に値上がりしていました。エントリモデルの方は相変わらず3万弱でした。ここまで価格差が拡がってしまうと、手を出せないところです。

9月中に機種変更を済ませてしまえば安く買えたのでしょうけれども、過ぎたことを悔やんでも、今更どうすることも出来ません。もしかすると再び値下がりして購入できる価格帯に入ってくるかもしれません。今後に希望をみていきたいと思います。

2019/09/30

プライド≠pride

日本語では外国由来の単語をカタカナで表記しています。しかしその外来語が具体的な事物であるならいざ知らず、抽象的な概念を表している場合にはカタカナで表記される外来語が元々の国での意味と同じかどうかは分かりません。またその外来語を使って発信している側も、その外来語を受け取る側も、はたして意味を同じように認識しているでしょうか。

例えばカタカナで「プライド」と表記するのは、英単語「pride」のことです。この単語は文中で「誰々はプライドが高いから云々」のように使われます。この外来語を使う側も受け取る側も、なんだか文意がわかったような気になりますが、本当にわかっているでしょうか。

外来語「プライド」ではなく日本語で表現するなら「自尊心」という概念があてはまります。ここで「自尊心」という抽象概念が何を指しているのかという問題が派生しますが、それは別途考えることにして、ここでは踏み込まないことにします。

外来語「プライド」の日本語表現はそれだけではありません。英単語「pride」を日本語に直接的に訳語にあてはめただけでなく、外来語「プライド」として意味が派生したものとして「選民意識」という概念もあるのではないかと考えています。

「自尊心」と「選民意識」とでは、受け取る側からすれば相当ニュアンスが異なります。しかし発信側が外来語「プライド」として表現しただけでは、どのような意味で語っているか、実際のところわかりません。

普段の会話では、ここまで厳格に考える必要はないでしょう。でも曖昧さを残す余地がある表現を(もしかすると意図的に)使うのは、コミュニケーションを壊す要因になると思います。

2019/09/29

第243回TOEIC公開テストを受験しました

今日が受験日でした。何かの直接的な目的があるという訳ではなく、英語能力を確認するために10年以上前から毎年この時期にTOEICを受験することにしています。

 TOEICに対する批判があることは承知しています。TOEICで得点がとれても英語ができる訳ではないとか、TOEICは受験テクニックで点数がとれてしまうなどの主張があるようです。それは一理あるのかもしれませんし、そういう側面もあるでしょう。しかし英語能力が無いのに、TOEICテクニックだけで高得点を得るというのは「おとぎ話」だと思います。どんな資格試験でも、同じことでしょう。

TOEICを受験すると、いつも思うことですが、時間が圧倒的に足りません。いつも最後の20問ほどは解答する時間が無くて「塗り絵」になってしまいます。TOEICで高得点を得ることも(ある意味で)目標ではありますが、少なくとも試験時間内に全問を解答できるようになることの方が、切実な目標です。

2019/09/24

.set NHRDRV,0x475 # Number of hard drives

FreeBSDのブートプロセスをみる』(白崎博生、UNIX MAGAZINE COLLECTION、2006年)を追体験しながら、カーネルを勉強しています。カーネルデバッグができる環境をVirtualBoxを使って構築したので、第1回「Boot Manager」から順番に読んでいきます。

大雑把に言うとboot0は、BIOSによってディスクから読み込まれ、boot1を読んで制御を渡すのが、主な役割です。その他にも処理がありますが、歴史的な事情によりINT 13Hの呼び出し方法が違うなどであり(それだけではありませんが)、ざっと眺めておくだけにします。

しかしながら、それほど重要というほどではありませんが、気になったのは、BIOSのデータエリア0x475番地を参照している箇所です。

boot0.Sでは「.set NHRDRV,0x475 # Number of hard drives」のようにシンボルが定義されており、以下のようなコメントも入っています。
    121  * NHRDRV is the address in segment 0 where the BIOS writes the
    122  *      total number of hard disks in the system.

このような情報はWebを検索すると見つかったりします。しかし得てして何かの情報の孫引きだったりするので、最もオリジナルの一次情報を見つけたいところですが、それはなかなか見つかりません。そもそもBIOSにおける非公開(に準じる)情報だったりすると、オリジナルの情報にはアクセスできないことになります。せめて次善の策として、BIOSの内部構造を詳述した定評のある書籍などの記述を参照しておきたいところです。

2019/09/23

FreeBSDのブートプロセスをみる』(白崎博生、UNIX MAGAZINE COLLECTION、2006年)を追体験しながら、カーネルを勉強することにしました。まず最初にカーネルのリモートデバッグができる環境をVirtualBoxを使って準備しました。書籍ではFreeBSD 5.1が使われていますが、今更古いバージョンを用意するのもなんなので、最新のFreeBSD 12.0を使うつもりです。記事の記述とは合わないところが出てくるかもしれませんが、それも含めて勉強です。

まずは第1回「Boot Manager」から始めます。記事ではboot0のソースがboot/i386/boot0/boot0.sと書かれていますが、stand/i386/boot0/boot0.Sに変わっていました。コメントも記事とは変わっているようですが、ロジックは変化していません。

まず最初に「自分自身を00600Hへ移動する」処理があります。レジスタを適切に設定してrepプレフィックスをつけたmovswで転送する訳ですが、ここで疑問が生じました。該当箇所は次のようになっています。
   181  start:          cld                             # String ops inc
   182                  xorw %ax,%ax                    # Zero
   183                  movw %ax,%es                    # Address
   184                  movw %ax,%ds                    #  data
   185                  movw %ax,%ss                    # Set up
   186                  movw $LOAD,%sp                  #  stack
   187 
   188          /*
   189           * Copy this code to the address it was linked for, 0x600 by default.
   190           */
   191                  movw %sp,%si                    # Source
   192                  movw $start,%di                 # Destination

ここでSIレジスタには転送元、DIレジスタには転送先が入っています。$LOADというのは、上述したソースコードのちょっと前で「.set LOAD,0x7c00」のように定義されています。しかし$startというのはラベルとして定義されているだけです。しかもコードの最初にあるので0x0000ではないのでしょうか。どうして0x0600として扱われるのでしょうか。すくなくとも、このファイルには(コメントに0x600と書かれているだけで)なんの定義もありません。これが疑問でした。

Webを検索しても、boot0を解説している情報は幾つか見つかりますが、この疑問に答えてくれる情報がなかなか見つかりませんでした。

Webで検索を続けていると『FreeBSD Architecture Handbook』に次のような記述があることを知りました。
It is worth looking at the Makefile for boot0 (sys/boot/i386/boot0/Makefile ), as it defines some of the runtime behavior of boot0. For instance, if a terminal connected to the serial port (COM1) is used for I/O, the macro SIO must be defined (-DSIO). -DPXE enables boot through PXE by pressing F6. Additionally, the program defines a set of flags that allow further modification of its behavior. All of this is illustrated in the Makefile. For example, look at the linker directives which command the linker to start the text section at address 0x600, and to build the output file “as is” (strip out any file formatting):
そしてMakefileでは以下のように記述されていると書かれています。
BOOT_BOOT0_ORG?=0x600
LDFLAGS=-e start -Ttext ${BOOT_BOOT0_ORG} \
-Wl,-N,-S,--oformat,binary
そういうことなのか、と思いましたが、Makefileには次のような記述があるだけでした。
BOOT_BOOT0_ORG?=        0x600
ORG=${BOOT_BOOT0_ORG}
考え方は変わっていないのだと思いますが、実現方法が変わったのでしょう。今回は、そこまでは追いかけませんでした。しかしともすれば見過ごしてしまう点を追及できました。

2019/09/22

FreeBSDのカーネルのリモートデバッグをおこなう

FreeBSDのブートプロセスをみる』(白崎博生、UNIX MAGAZINE COLLECTION、2006年)を追体験しながら、カーネルを勉強しようと考えています。連載当時はFreeBSD 5.1でしたが、今はFreeBSD 12.0です。細かいところで記述内容と合わない点があります。まずは連載最後の17回を参考に、カーネルデバッグの環境を整えておこうと思います。

カーネルデバッガDDBが起動できるようなカーネルに入れ換える作業は、特に問題ありませんでした。

つぎはリモートデバッグの環境を準備しようと思います。書籍の記述ではVMwareを利用していますが、僕はVirtualBoxを使おうと思います。VMwareだろうが、VirtualBoxだろうが、もしくは仮想環境ではなく実機であろうが、考え方は変わらない筈です。その筈なのですが、当初うまくいかず苦労してしまいました。しかし最終的にリモートデバッグ環境ができたので、結果オーライという感じです。

もし実機を使ってリモートデバッグ環境を整えるなら、2台のマシン間をRS-232Cのヌルモデムケーブルで繋ぐことになるでしょう。仮想環境であれば、2台のゲスト環境のCOM1ポートを「仮想的」に接続されているように見せかける必要があります。それが連載記事でも紹介されている、名前付きパイプを使用する方法です。記事ではVMwareの設定としてシリアルポートを名前付きパイプとして設定しています。VirtualBoxでもシリアルポートを名前付きパイプとして設定できるので、当初この方法で2台のゲスト環境を接続するつもりでした。ところがうまくいきません。どううまくいかないかというと、リモートデバッグ環境からターゲット側への接続ができないというエラーが出てしまうのです。そもそもVirtualBoxでは無理なのかと思いましたが、Webで「Freebsd kernel remote debugging. Part1」という情報を発見しました。バージョンが書かれていませんが、成功した事例と言えるでしょう。

VirtualBoxではなくQEMUを使った事例として「FreeBSDのオンラインカーネルデバッグ with QEMU」という情報も見つけました。こちらはQEMUにしかない機能を利用しているので、同じことをVirtualBoxで実現することはできませんが、参考になります。

最終的にVirtualBoxの設定を次のようにすることでリモートデバッグ環境が出来上がりました。

  1. 使用したVirtualBoxは「バージョン 6.0.12 r133076 (Qt5.6.2)」です。
  2. FreeBSDのカーネルデバッグされる側を「ターゲット」と呼ぶことにします。
  3. GDBでデバッグコマンドを操作する側を「デバッガ」と呼ぶことにします。
  4. 「ターゲット」ではVirtualBoxでシリアルポートを利用できるように設定しておきます。
    1. 「ポートモード」を「TCP」にします。
    2. 「存在するパイプ/ソケットに接続」のチェックを外します。
    3. 「パス/アドレス」を設定します。他のアプリケーションと衝突しなければなんでも良いでしょう。僕は「35790」にしました。
  5. 「デバッガ」ではシリアルポートを使わないので、有効にする必要はありません。

上述した設定をして「ターゲット」と「デバッガ」のゲスト環境を起動します。「ターゲット」でログインプロンプトが出たら、CtrlとPrintScrキーを同時に押してカーネルデバッガに入ります。そして「gdb」コマンドを入力してリモートからの接続を待機させます。
FreeBSD/amd64 (target) (ttyv0)

login: KDB: enter: manual escape to debugger
[ thread pid 12 tid 100006 ]
Stopped at       0xffffffff80bf955b = kdb_enter+0x3b:   moveq   $0,0xffffffff81f7cbe8 = kdb_why
db> gdb
(ctrl-c will return control to ddb)
Switching to gdb back-end
一方「デバッガ」ではgdbを起動し、「ターゲット」に接続します。ここで接続先の指定はTCP/IPアドレスとポート番号を使用します。注意が必要なのは、TCP/IPアドレスは、「ターゲット」のゲスト環境のFreeBSDに割り当てられたアドレスではなく、ホスト環境であるWindows10のアドレスです。
furusawa@debugger:~ % kgdb /boot/kernel/kernel
GNU gdb (GDB) 8.3 [GDB v8.3 for FreeBSD]
Copyright (C) 2019 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-portbld-freebsd12.0".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from /boot/kernel/kernel...
Reading symbols from /boot/kernel/kernel.debug...
(kgdb) target remote 192.168.1.14:35790
Remote debugging using 192.168.1.14:35790
warning: remote target does not support file transfer, attempting to access files from local filesystem.
Reading symbols from /boot/kernel/intpm.ko...
warning: the debug information found in "/usr/lib/debug//boot/kernel/intpm.ko.debug" does not match "/boot/kernel/intpm.ko" (CRC mismatch).

(No debugging symbols found in /boot/kernel/intpm.ko)
Reading symbols from /boot/kernel/smbus.ko...
warning: the debug information found in "/usr/lib/debug//boot/kernel/smbus.ko.debug" does not match "/boot/kernel/smbus.ko" (CRC mismatch).

(No debugging symbols found in /boot/kernel/smbus.ko)
kdb_enter (why=0xffffffff812fae28 "break", msg=<optimized out>)
    at /usr/src/sys/kern/subr_kdb.c:479
479                     kdb_why = KDB_WHY_UNSET;
(kgdb)
このように「ターゲット」と「デバッガ」の接続が確立されました。これでリモートデバッグ環境が出来たことになります。

試しにシステムコール「sys_mkdir」にブレークポイントを仕掛けてみます。そして「ターゲット」のコマンドラインでコマンド「mkdir」を実行しようとすると、ブレークポイントで停止してくれました。成功です。
(kgdb) b sys_mkdir
Breakpoint 1 at 0xffffffff80c90614: file /usr/src/sys/kern/vfs_syscalls.c, line 3582.
(kgdb) c
Continuing.
[New Thread 100086]
[New Thread 100063]
[Switching to Thread 100086]

Thread 78 hit Breakpoint 1, sys_mkdir (td=0xfffff80003fd8580,
    uap=0xfffff80003fd8940) at /usr/src/sys/kern/vfs_syscalls.c:3582
3582            return (kern_mkdirat(td, AT_FDCWD, uap->path, UIO_USERSPACE,
(kgdb) list
3577    #endif
3578    int
3579    sys_mkdir(struct thread *td, struct mkdir_args *uap)
3580    {
3581
3582            return (kern_mkdirat(td, AT_FDCWD, uap->path, UIO_USERSPACE,
3583                uap->mode));
3584    }
3585
3586    #ifndef _SYS_SYSPROTO_H_
(kgdb) c
Continuing.
これでFreeBSDのカーネルをリモートデバッグするための環境が手に入りました。この環境を利用して『FreeBSDのブートプロセスをみる』を読んでいこうと思います。

2019/09/20

FreeBSDでカーネルデバッガを使ってみる

カーネルを勉強をしてみたいと以前から考えていましたが、どこから手をつければ良いのか、迷っていました。独習するとしても、何か伴走してくれるような参考書があると助かります。そこで手持ちの書籍から『FreeBSDのブートプロセスをみる』(白崎博生、ASCII、2006年)の辿った道程を追体験していきながら、カーネルになじんでいくことにしました。

この本はUNIX MAGAZINEの連載をまとめたものですが、もう15年ほど前に執筆されたので対象となるFreeBSDはバージョン5.1です。いろいろと変わったところもあるでしょうが、枝葉末節を気にしなければ、大筋は変わっていないかもしれません。それは別にどちらでもよくて、変化していても、変化していなくても、それを踏まえて、カーネルの世界を歩いていく練習をするのが目的です。

学ぶ環境はVirtualBox上に構築することにします。まずは連載最終回の第17回「カーネルデバッガ」の手順を追体験してみます。

カーネルデバッガを使えるようにする基本的は変わっていないようですが、指定できるオプションがFreeBSD 12では違いがありました。またカーネル構築手順も違っています。

カーネル定義ファイルは、記事同様に「UMKERNEL」としておきます(これはUnix MagazineのKernelという意味なのでしょう)。記事では既存のカーネル定義ファイル(GENERICなど)を変更して作成することが想定されているようですが、今回は次のようなファイルを新規に作成しました。これはFreeBSDハンドブックの「8.4. コンフィグレーションファイル」に書いてあることに倣ったものです。
include         GENERIC
ident           UMKERNEL

options         DDB
options         DDB_NUMSYM
options         GDB
カーネルのコンパイル方法も違っています。記事にあるのは伝統的なBSDにおけるカーネルコンパイル方法ですが、「8.5. カスタムカーネルの構築とインストール」に倣って、次のようにしました。コンパイルに1時間半ほどかかりました。
# cd /usr/src
# make buildkernel KERNCONF=UMKERNEL
# make installkernel KERNCONF=UMKERNEL
カーネルを入れ替えたら、再起動します。記事では「DDBの呼び出し方」として5種類あると書かれていますが、このあたりも今は若干違うようです。記事にも書いてある最初の手順「キーボードのCtrlとPrtScキーを同時に押す」を実行したところ、カーネルデバッガに入ることが出来ました。

ひとまず、ここまでは成功です。次はリモートデバッグに挑戦してみようと思います。すでに実験しているところです。概念は難しくないのですが、うまくいきません。記事ではVMwareを利用していますが、僕はVirtualBoxにしようと思っています。それが手強い原因とも思えませんが、なんとか解決したいと思います。

2019/09/18

佐和山城址


OSのカーネルを理解するには?

OSのカーネルを理解したいと昔から考えていました。このように考えている人は世間に多いようで、いろいろな書籍が出ていますし、Webにも情報が溢れています。しかし、まがりなりにも最後まで到達したという情報は少なく、多くは三日坊主です。

またOSの選択も多様です。最も多いのがLinuxのカーネルを素材とする場合です。その他にはBSD系やUNIX V6などもありますが、あまり活発ではありません。

もう20年以上前の1996年10月30日に当時のネットニュースfj.os.bsd.freebsdに西村享さん(奈良先端科学技術大学院大学情報科学センター) が投稿した記事があり、参考になると思っています。その記事によると、FreeBSDのカーネルを読もうとした或る人物の投稿への返信として、次のように語っています。
大学院生のソース読み輪講につきあったことがあるのですが、彼らも同じような非効率なアプローチを取りました。システムコールが呼ばれた時の制御の流れや、コンテキストスイッチとはCPUの何をどうすることかなど、超基本的な知識を咀嚼できてない状態で「生のOS」のソースコードに手を出すのは難がある(ひどく遠回りをするという意味)ように思います。

さらに『4.3BSDの設計と実装』を読もうとしていることに対して、次のように語っています。(原文ママ)
他の方も指摘されていますが、改訂版もでています。私は旧版新版どちらもお奨めしません。なぜなら、よく誤解されているようですが、入門書でないからです。以前comp.os.*なしがしだったかで、これらを評して「too dry」だとの発言を見たことがあります。私もまったくその通りだと思います。これらの本に書いてあることを理解するには、まずソースコードを読んでおくことが先決です。「UNIXカーネルの全体像を得る」 などという目的でこれらの本に取り組むとおそらく自滅するでしょう。それらは前提知識の範疇に含まれるように思います。

閑話休題。カーネルのソースは、LinuxでもBSD系(FreeBSD、NetBSD、OpenBSD)でも容易に入手できます。どれを読むか悩むところですが、個人的にはBSD系を選ぼうと思います。NetBSDの情報が多いような気もしますが、FreeBSDにしようかと考えているところです。

カーネルは大規模ですが、全体を区分すれば、ボリューム的に大部分を占めるのはデバイスドライバではないかと思います。またファイルシステム、ネットワークスタック、ブートストラップ、システムコールなどの構成要素に分割できると思うので、一つずつ取り組んでいけば(大変だとは思いますが)無謀な取り組みでもないと思っています。

TCP/IPの教科書

TCP/IPの挙動について理解したいと思い、パケットの状況をwiresharkで調査してみました。このようなツールを使えば現実の通信状況が見えるので、とても理解がすすむのですが、基礎的な理解ができていないと行き詰まってしまいます。

TCP/IPの基本について学んでおこうと思います。TCP/IPの入門書は多数出版されているものの、その多くは入門的すぎて満足できません。その中でも定評があるのが次のシリーズです。

どちらも3巻組で、第1巻がプロトコル、第2巻が実装、第3巻がアプリケーションになっています。詳しく記述されているのでページ数も多く、値段も高いです。これらのシリーズは以前から知っていたのですが、値段もネックだし、どちらを選ぶかも迷っていて、入手していませんでした。

迷っているだけでは、いつまでたっても進歩しないので、思い切って両シリーズの第1巻を買うことにしました。翻訳書だと、中古本であっても、両方合わせて1万円以上するので、さすがに躊躇します。そこで旧版の原書をabebooks経由で購入することにしました。

例えば「Internetworking with TCP/IP Volume 1 : Principles, Protocols, and Architecture」は新版もありますが、旧版なら$1でした。しかし送料は別に必要ですが、合計しても10ドル以下なので、円換算しても千円以下です。

到着まで時間がかかるのが難点です。しかし急ぐわけでもないので、ゆっくり待とうと思います。

2019/08/30

VirtualBoxではkdumpが動かないのか

つい先日、VirtualBox上にCentOS7の環境を作りkdumpが動作するか確認しました。するとCentOS 7.0~7.6まで(症状が多少違うところもありますが)全て失敗したので、CentOSでkdumpが動かないものだと判断してしまいました。

しかしWeb上で見つけた情報「カーネルクラッシュダンプの基本や取り方など」によると、CentOS 7.6でkdumpが動いているようです。それならばVirtualBoxで動かないのは、CentOSの問題ではなく、VirtualBoxの問題ということになります。

試しにVMware Workstation Player上にCentOS7の環境を作って、kdumpの実験をしてみました。するとkdumpが動くのです。やはりCentOSの問題ではなく、VirtualBoxの問題だったのでしょう。しかし未だに疑問なのは、VirtualBoxでkdumpできないのは、僕だけなのか、世間一般でそうなのかという事です。VirtualBoxの既知のバグで動かないのであれば、将来のバージョンで動くようになるかもしれません。しかし、何か設定をすることでkdumpできるようにするTipsがあるのであれば、ぜひ知りたいと思います。

それにしても、何が問題なのか情報がないと、調査の糸口も掴めません。CentOSは、旧いOSのように起動時にメッセージがズラズラと出てこないので、何が悪いのか判断する情報が得られないのです。昔は起動時に長々とメッセージがコンソールに流れていましたが、一般受けしないので出さなくする傾向にあるのだと思います。

なんとか情報が得られないかと調べていたら、GRUB2のブートメニューで編集モードに入り、パラメータを変えれば良いようです。パラメータ「rhgb quiet」の指定を消せば昔のOSのように起動ログが出てくるようになります。また更に詳しい情報が必要ならパラメータ「loglevel=7 systemd.log_level=debug」を指定すれば、もっと詳しく情報が出てきます。

この指定をおこなってVirtualBoxでkdumpを起動しようとしたところ、2nd kernelの起動ログが出る前にVirtualBox自体が落ちてしまいました。そもそも2nd kernelに制御が渡っていないようです。

2019/08/26

「電撃戦」と「鎖国」

岩波新書の『独ソ戦』(大木毅)を読んでいます。独ソ戦というのは歴史として知っていますが、より踏み込んだ内容については詳しく知りません。まだ読んでいる最中ですが、これまでの理解が正しいとは言えなかったことを知りましたし、最新の研究成果を反映しているので、より正確な理解ができると期待しています。

なかでも驚いたのが、以下の記述です(47頁)。
「電撃戦」という単語自体、第二次世界大戦前半の一連の戦役ののちに、外国のジャーナリスト、あるいはプロパガンダ当局が用いはじめたもので、軍事用語ではなかったことを解明している。

第二次世界大戦当初のドイツ軍の快進撃は「電撃戦」として解説されることが多いと思っていましたが、ドイツ軍の軍事的な原則ではなかったというなら驚きです。通俗的な歴史理解は、実は歴史的な正確な理解とは限らないという事なのでしょうか。

そこで思いだすのが、日本史で耳にする「鎖国」です。通俗的な日本史では江戸時代は「鎖国」と言われますが、歴史研究者からは「鎖国」などは無く、「海禁」と理解されるという見解も出ています。

当たり前だと思っていた歴史理解が、実はそうではないという事例は、他にもありそうです。

2019/08/23

カーネルがパニックしても再起動がかからない

Linuxにおいて、コマンドラインから意図的にカーネル・パニックを発生させる方法があります。Webを検索すれば情報はすぐに見つかると思います(例えば「sysrqキーでパニックさせる」がそうです)。Linuxであれば、Ubuntuであろうが、openSUSEであろうが、CentOSだろうが、ディストリビューションを選ばないと思っていました。ところがそうでもないようです。

発端はCentOS 7.4でした。カーネルがパニックを起こしたら自動的に再起動するような設定にした筈なのに、実際にパニックを起こしているようであるのに、再起動しないのです。その時点で、マシンへのpingは通りませんし、コンソール画面には何も映っていません。もう電源を手動で落とすしかない状態です。

実際に運用中の環境で「パニックの実験」は出来ませんから、VirtualBox上にCentOS 7.4の最低限の環境を作って試してみました。するとやはり再起動しないのです。現象は再現したと言えるのかもしれませんが、もしかすると何か手順を間違えているのかもしれません。そこで、VirutalBox上で動作するように準備しているUbuntu 18.04やopenSUSE 13.1で試してみました。するとどちらもカーネルがパニックすると再起動します。手順に誤りは無いと判断して良いでしょう。

Webには「CentOS7.0でカーネルパニックを発生させてみる」という情報があるのです。CentOS 7.0なら再起動して、CentOS 7.4では再起動しないというのも不思議な話です。そこでVirtualBox上にCentOS 7.0から7.5までの各環境を準備して、再起動されるか否かを実験してみました。その結果、驚いたことに再起動したと言えるのはCentOS 7.1だけでした。
  • VirtualBoxがダイアログを出し、仮想マシンが落ちてしまう(CentOS 7.0、CentOS 7.2、CentOS 7.3)
  • 画面が固まり、再起動しない(CentOS 7.4、CentOS 7.5)

CentOS 7.4で再起動されない現象は確認できましたが、運用上の理由から再起動して欲しいのです。システムパラメータに何か関係しそうな設定があるのかもしれないと考えてCentOS 7.3とCentOS 7.4を比較してみましたが、それらしい設定はなさそうです。

解決策が見出せないまま手詰まりかと思ったのですが、ふと「kdumpが再起動を邪魔しているのではないか」と思いつきました。カーネルがパニックするとkdumpでクラッシュダンプを取得することになるので、kdumpが居なければ再起動できるのではないかと考えたのです。そこで確認してみるとCentOS 7.0以降の全バージョンでkdumpサービスが動いていました。

コマンドラインから「systemctl stop kdump」でサービスを止めて、当初の手順でカーネル・パニックを起こしてみると、なんとCentOS7.4でも再起動しました。やはりkdumpが邪魔していたのでしょう。



2019/08/15

小平尚道『アメリカ強制収容所』を読んで

雑誌「ナショナルジオグラフィック(日本版)」の2018年10月号を読んでいたら(定期購読しているので毎月郵送されてきているのですが、忙しくて読む時間がとれずに溜まっています。時間をみつけて、読んでいる最中なのですが)、「強制収容された日系人」という記事がありました。話題がそれますが、この記事のタイトルがこれで正しいのか不明です。というのは、目次にあるタイトルは、先述したようになっていますが、本文にはそれらしいタイトルがなく、タイトルらしきものとして「私はアメリカ人です。戦時中の日系人強制収容が今の米国に問いかける。」とあるだけなのです。

閑話休題。第二次世界大戦中のアメリカにおける日系人強制収容については、話には聞いていましたが、詳しく知りません。1980年頃になってからアメリカ政府が誤りを認め謝罪したとの話も聞いたことがありますが、詳しく理解している訳ではありません。

まずは参考になるような書籍を読んでみようと図書館で調べてみたら『アメリカ強制収容所―戦争と日系人―』(小平尚道、1980年)というのがあったので借りてきて読んでみました。著者である小平尚道は、1912年に米国生まれの日系二世で、シアトル長老教会牧師でした。日系人として強制収容された体験者です。本書は、その体験記であり、アメリカにおける日系人強制収容の全貌を明らかにしているわけではありません。本書の序文で著者が以下のように記しているとおりです。
 したがって、私の経験はミネドカ収容所に限定され、これを一般化することはできない。あくまで私個人の体験で、どこの収容所も、こうだったとは言えない。それ故、この本はアメリカ収容所の全体を画いたものでなく、その一部を録したものにすぎない。

 著者は日米開戦前の1940年夏から秋にかけて日本を訪れ、満州にも行ったことが、まず最初に記されています。本書の基調は体験談なので、その時に著者の身に何があったのか、また著者が当時の日本の状況をどのように見ていたのか、そして日米の違いをどう感じていたのか等に主眼をおいて記されています。その内容は著者の主観ですから、それを割り引いて理解する必要がありますが、その反面として著者の関心の在りかや感想を通して、当時の社会をより深く知ることができます。これはとても興味深いことで、無味乾燥な教科書の(可もなく不可もなく、と言った)淡々とした記述に比べると、説得力があると感じました。

2019/08/10

映画「スティング」

NHK BSプレミアムで2019年8月15日の午後1時から映画「スティング」が放送される予定です。NHKのサイトでは、次のように紹介しています。
P・ニューマン、R・レッドフォード、G・R・ヒル監督、「明日に向って撃て!」の名トリオが、1930年代のシカゴを舞台に、仲間の復しゅうのため、ギャングの大親分に挑む詐欺師たちの華麗で大胆な活躍を描く傑作犯罪コメディー。(以下略)

ギャングのボスをだまそうとする詐欺師の話だとは思っていましたが、「コメディー」とは考えていませんでした。娯楽映画だとは思うし、実録もののドキュメンタリーではないですし、観終わったときに暗い気持ちになる訳ではないので、すっきりする楽しい映画だとは思います。

しかし「コメディー」と言われると、そうなのかなぁと思います。コメディ映画に出演しているポール・ニューマンやロバート・レッドフォードは「コメディアン」という事になってしまうのでしょうか。

2019/08/09

rsyncで除外指定(--exclude)の問題が解決した

dynabook SS SX/15AにNetBSD/i386を入れて利用しています。この他に、日常的に使用しているデスクトップPCがあり、それはWindow10です。Windowsのフォルダ「Documents」にあるファイルをNetBSD側にコピーしておけば、ノートPCを持って出かけた時に参照できて便利だと思うので、同期させておこうと考えています。ただしdynabookのディスク容量が厳しいので、出先では無用なファイルは同期対象から外したいと思っています。

まず同期する仕組みはrsyncを使います。Windows10上のWSLを利用すれば、U*IX系の各種ツールが利用できるため、Win32版rsyncなどを利用するよりも安心できます。rsyncを利用してファイルを同期することは、あまり苦労することもなく出来ました。

やっかいだったのが、除外対象を除いて同期させることです。rsyncで除外対象を指定するにはオプション「--exclude」を指定すればよいようなのですが、指定方法に癖があり、苦労している情報がWebには溢れています。Webで見つけた以下の情報を参考にしました。
  1. rsync の複雑怪奇な exclude と include の適用手順を理解しよう 

最終的に期待する動作をするようになったのですが、うまくいかなかった原因はrsyncのオプションの指定方法ではなく、自作したシェルスクリプトの書き方の問題でした。

当初シェルスクリプトでは次のように書いていました。除外対象は今後増減する可能性がありますし、rsyncに指定するオプションは他にもあるので、それを分離したつもりでした。
EXC_OPTS="   
                    --exclude='*.[eE][xX][eE]'
                    --exclude='*.[jJ][pP][gG]'
"
しかし期待した動作をしない原因は、この指定にあったようです。以下の書き方をすると、期待した動作をするようになりました。違いは、オプションの中でシングルクォートで括っているのを止めたことです。
EXC_OPTS="
                    --exclude=*.[eE][xX][eE]
                    --exclude=*.[jJ][pP][gG]
"
 この解決に至る過程で、rsyncのオプション「-vvv」を利用しました。文字「v」を増やすほど情報が増えるようです。そこに以下のような出力が現れているのが確認できます。除外対象が期待した通りに処理されていれば、このような出力になるはずです。うまく指定されていなければ、「because of pattern」という表示がなく、除外対象にしている筈なのに、なぜか同期対象とされてしまい、頭を捻ることになります。
[sender] hiding file a/b/c/1.jpg because of pattern *.[jJ][pP][gG]
問題の原因がわかってしまえば、至極当然なことと思えますが、解決できていないときには、五里霧中という気持ちになります。ともかく解決できて、一安心しました。

2019/08/05

Microsoft Windows 10からNetBSD/i386へのDocumentsフォルダの同期にrsyncを利用する

dynabook SS SX/15AのOSをNetBSD/i386に入れ換えて利用しています。日常的に利用しているのはMicrosoft Windows 10のデスクトップPCです。ここにあるDocumentsフォルダをdynabook側にもコピーしておくことで、出先にdynabookを持っていた時、ファイルを参照できる環境となるようにしています。

元々はdynabookにはMicrosoft Windows Vistaが入っていたので、ファイルを同期するのは簡単でした。共有フォルダとして見えるようなっていれば、XCOPY.EXEを利用してファイルをコピーできました。

Vistaがフェーズアウトし、OSをNetBSDに入れ換えたことにより、同期する仕組みを工夫する必要が出てきました。うまい仕組みを作り上げたと思っても、動作が不安定で、なかなか満足のいくものになりませんでした。

そうこうしているうちに、Microsoft Windows 10でWSL(Windows Subsystem for Linux)が利用できるようになりました。WSLを使えば、Windows側のファイルをWSL側から参照することができます。しかも本物のLinuxディストリビューションを利用できるので、U*IX系OSとしてNetBSDとの親和性も高く、同期方式が作りやすくなります。

結局、WSL上でrsyncを使って、ローカルにあるDocumentsフォルダのファイルを、リモートにあるNetBSD上の所定のディレクトリにコピーすることにしました。試しに動かしてみると、上手くいっています。この点では成功と言えるでしょう。

ただし問題もあります。dynabook SS SX/15Aのディスクは60Gしかないので、OSやアプリケーションを入れた後で使える容量は、あまり残っていません。Windows側のDocumentsフォルダにあるものを全てコピーしてしまうと、ディスクが溢れる恐れがあります。そこで余分なファイルはコピーしないようにしたいところです。

このような要望のために、rsyncにはオプション「--exclude」が用意されており、これを使えば解決と言いたいところです。ところが指定方法が難しく、指定してみても、期待した動作をしません(要するに、コピー対象から除外したつもりなのに、コピーされてしまう)。Webを検索しても、うまくいかずに苦労している人達が溢れています。

コピーは出来ているので、ひとまず成功と言えるのですが、コピー除外がうまくいっていないので、完成しているとは言えません。なんとか問題を解決しようと思います。

2019/08/02

PythonにNetworkXをインストール

最長片道切符のグラフ問題を扱うために、PythonにNetworkXを導入してみました。導入するのは簡単ですが、pipを利用します。Python 3.4以降には標準で入っているという情報がありますが、FreeBSDのパッケージで入れたpython 3.6には入っていないようでした。
tpe530c> python3.6 -m pip list
/usr/local/bin/python3.6: No module named pip
tpe530c> uname -a
FreeBSD tpe530c 12.0-RELEASE-p8 FreeBSD 12.0-RELEASE-p8 GENERIC  amd64
tpe530c> python3.6 -V
Python 3.6.9
furusawa@tpe530c> python3.6
Python 3.6.9 (default, Jul 11 2019, 01:10:39)
[GCC 4.2.1 Compatible FreeBSD Clang 6.0.1 (tags/RELEASE_601/final 335540)] on freebsd12
Type "help", "copyright", "credits" or "license" for more information.
>>>

pipを導入するのは簡単ですが、パーミッションの都合によりrootで操作する必要があります。
# curl -kL https://bootstrap.pypa.io/get-pip.py | python3.6
tpe530c> python3.6 -m pip list
Package    Version
---------- -------
decorator  4.4.0 
networkx   2.3   
pip        19.2.1
setuptools 41.0.1
wheel      0.33.4

グラフ構造を扱うためにNetworkXが必須かというと、そういうわけでもないと思います。しかし重み付きグラフの情報を記したファイルを読み込んでくれるヘルパー関数があるので、自前で似たようなプログラムを書くより楽ではないかと思います。

NetworkXを極めるよりも、最長片道切符のグラフ問題を解くために必要なプログラムを書けるようにするため、NetworkXの使い方を学んでいきたいと思います。

2019/07/31

「65日間日本一周最長片道切符」(bit、1975年1月号)を読んで

かつて共立出版が発行していた「bit」に「65日間日本一周最長片道切符」(平野照比古、1975年1月号)という記事が掲載されていることを知り、読んでみました。国鉄が日本全国に鉄道網を持っていた時代には、このような最長距離の片道切符を考えるのが話題になっていました。最も有名なのが『最長片道切符の旅』でしょう。

 記事には、最長距離片道ルートを求めるアルゴリズムが開設されていますが、概念レベルが書かれているだけなので、具体的なロジックはわかりません。文末にデータ作成作業をしてくれた人達への謝辞が書かれています。当時は今日のような路線検索サイトがある訳ではありませんから、おそらく時刻表を利用して、必要な情報を拾ってグラフ構造を作ったのでしょう。楽な作業ではないと思いますが、本文中でも「まず、駅の集合をVとする。実際には分岐点や行きどまりの駅だけを考えれば充分であることは明らかであろう。」と書かれているように、旧国鉄の全駅のデータが必要になるわけではなく、グラフ構造を作り上げるために必要な分岐駅や末端駅の名前と区間距離だけで良いわけです(それでも膨大なデータになることは違いないでしょう)。

アルゴリズムの解説では、サブブロック化に重点がおかれています。北は北海道から南は鹿児島までの旧国鉄の路線網をグラフ構造にしたとしても、現実の日本列島を考えれば、全体を一気に計算するよりも、一部分(これをブロックと呼んでいる)を計算して、最後に全体を統合すれば、最終的な計算量が削減されることが期待できます。

例えば、北海道と本州は青函連絡船を使うしかないし、九州と本州は関門トンネルを使うしかないわけです。だから、北海道内や九州内のルートを計算する場合には、それ以外の地域の事を考えなくてよいことになります。

北海道、四国、九州は、上述したようなサブブロックとして計算できますが、本州をどうするかが問題です。サブブロックに分けられそうでもあり、分けるのは困難のようでもあり、なんとかしたいところです。ブロックに分けようとする意図は、全体を闇雲に計算すると計算量が爆発し、その当時の計算機では処理が終わらなくなる恐れがあるからでしょう。当時の計算機よりも、今日のパソコンの方が性能が圧倒的に良いと思うので、もしかすると余計なサブブロックを考えなくても、計算できるかもしれません。

プログラムはFORTRANで組んだようです。その当時なら、このような計算をするならFORTANに決まっているでしょう。この記事には、それ以外(プログラムリストとか、実行時間など)の具体的なことは何も書かれていません。CiNiiで探してみたら、京都大学学術情報リポジトリに「長い片道切符について(計算機によるパズル・ゲームの研究)」というメモが「数理解析研究所講究録(1976), 263:75-76」として見ることができました。手書きなのが時代を反映しているところですが、「使用言語はFORTRANで使用計算機はFACOM 270-20(LOAD/ADD 4.8μs)での時間である」とあります。

面白そうなので、自分でもやってみたくなりました。プログラムはFORTRANでも良いのですが、今ならPythonを使ってみたいところです。グラフ構造を取り扱うためのPythonモジュールがあれば、いろいろと楽ができるでしょう。

ここで行く手に大きな問題があることに注意が必要です。1975年当時の国鉄と、2019年現在のJR各社とでは、事情が大きく変わっているのです。特に次の点が重要です。
  1. 新幹線開業にともない並行在来線がJRから切り離されている。
  2. 鉄道網が衰退(特にJR北海道)しており、グラフ構造で最長片道ルートを計算するというほど路線が残っていない。

2番目の問題は、計算量が少なくてガッカリするという程度の話にすぎませんが、1番目の問題は重大です。北海道新幹線が開通したことにより、JR北海道から切り離された道南いさりび鉄道の扱いが問題になるからです。新幹線が開業したことによりJRから切り離された路線は他にもありますし、長野新幹線の開業により横川と軽井沢の間は在来線が無くなりました。このような事情を考えると、どのような方針を採用するか考えておく必要があります。
  1.  全ての新幹線もルート検討に加える。ただし、路線の距離は、「営業キロ」なのか「実キロ」なのか、混乱しないようにすべきである。
  2. JRから切り離された第三セクター路線を、ルート検討に含めるか、除外するか決めておく。もし新幹線も除外し、第三セクター路線も除外するならば、北海道から本州に抜けるルートが無いということになります。
  3. いっそのこと全ての私鉄もルート検索の対象に含める。しかし「最長片道切符」の本来の意図は、「一枚の切符で最長距離」となることに意義があるため、ちょっとやり過ぎなのかもしれません。

最長片道切符のルート問題は、グラフ理論の応用問題です。ここで日本の鉄道網であるという知識を利用すると、すっきりしたグラフ理論のアルゴリズムというより、個別事情の集合という汎用性の乏しい問題に堕ちてしまいそうではあります。いずれにせよ、面白そうなので、なんとかものにしてみたいと思います。

2019/07/28

2019年7月28日3時31分発生三重県南東沖地震

2019年7月28日3時31分頃に三重県南東沖でM6.5の地震が発生しました。震源の深さは約420kmだそうですから、かなり深いところで起きています。

気象庁が発表した震度分布図を見ると、直観とは異なる状況が見て取れます。

まず第一に、震源が三重県南東沖なのに、愛知県では震度1程度にもかかわらず、宮城県で震度4、福島県や茨城県で震度3が観測されていることです。三重県では震度1の観測すらありません(実際には、微かな揺れを感じた人はいるのかもしれませんが)。震源に近い愛知県が震度1で、東北地方から関東地方の太平洋沿岸で強く揺れているようです。

次に、北海道の釧路町でも震度2を観測しているのに、西日本(中国、四国、九州)では、震度1の観測が全くありません。

地球の内部構造は、同心円状に揺れが伝わっていくわけではないということなのでしょう。三重県沖であれば、西日本全体を覆っているユーラシアプレートの範疇なのにもかかわらず、東日本を覆っている北アメリカプレートのエリアの方が揺れているという現象が起きているのが、興味深いところです。

2019/07/27

「梅雨明け」の基準と実態

気象庁のWebに「令和元年の梅雨入りと梅雨明け(速報値)」というページがあり、「 更新日:令和元年7月25日」では東海、関東甲信、東北南部、東北北部の梅雨は明けていないことになっています。しかし梅雨前線は、とっくの昔に消えていて(素人目には、そう見えます)、数日前から最高気温が30度を超すようになっていますし、既に梅雨は明けているように見えます。四国、中国、近畿は「7月24日ごろ」に梅雨が明けていることになっているので、東海や関東甲信も梅雨明けで良いのではないかおもいますが(素人考えでは)、きっと気象庁の「梅雨明け基準」の何かを満たしていないのでしょう。

気象庁が発表する情報は、さすがに「何となく」というわけにはいかないでしょうから、何らかの基準を踏まえて発表するのでしょう。熱帯低気圧が台風になり、さらに温帯低気圧に変わる場合や、台風の大きさや強さを表現する場合は、何らかの尺度に従って発表されます。それは現実を表していると言って良いだろうと思います。これに対して、気象庁が発表する「桜の開花日」などは、地元の桜を全て見て廻るわけにはいかないでしょうから、サンプルとして指定された「特定の桜」が開花したかどうかに過ぎないはずです。代表として選ばれた桜の開花が、その地域を代表すると考えて差し支えないように選ばれているはずですが、本当に代表しているのか評価はしていない(しようがない)だろうと思います。

話を梅雨明けに戻すと、Webを検索すれば「梅雨明けの基準」と思われるものが見つかります。しかし気象庁の判断を類推しているに過ぎないので、本当に間違いない情報なのかという確実性はなさそうです。

今年の梅雨明けは何時になるのでしょう。いつ発表されるのでしょう。もしかすると「既に梅雨は明けていました」という発表になるのでしょうか。

2019/07/26

地域の祭りと部署の宴会

Webの掲示板を見ていたら、地域外の者が地域の祭りに参加するのは非常識なのかという問いかけがありました。それに対して、そんなことはないという意見もあれば、駄目に決まっているという意見もありました。個人的には、参加者を制限する「祭り」って一体なんだろうと思いますので、地域内外を問わずに自由に参加して構わないと考えます。しかし参加しようとしたところ、地域外の者であることを理由に拒否されたという経験がある事例も少なくないようです。

この問題は、「祭り」という言葉が表している「状態」に対して、個々人の受け止め方に差異があるのが原因のひとつではないかと思います。「祭り」という言葉から連想するのは、全国的にも有名な京都の祇園祭、大阪の天神祭り、浅草の三社祭など各地にあります。これらは、当初は地域の中で小ぢんまりとして始まったのでしょうが、現在では全国的な観光行事となっているので、参加者を限定することはないでしょう。これほど大規模でなくても、祭りというのは全て地域の人達の営みから生まれており、人々の一体感を盛り上げるために来るもの拒まずとして運営されるものですから、参加者を制約するのはありえないと思います。

ここで注意しておきたいのは、「祭り」という言葉が、上述したような状況を必ずしも表現した言葉にはなっていない事例もあるという事実です。例えば、ファミレスなどの季節イベントの名前として、「春のご卒業・新入学おめでとう祭り」のように「祭り」という文字を入れてくることがあります(これは例のひとつであり、現実の何かとは関係ありません)。これは常識として「祭り」といっても、上述した「祭り」とは違うと、普通は理解しています。それは問題ではないのですが、「祭り」という言葉が、「祭り」とは違う派生した状況を表現していることは、問題を生む原因となり得るでしょう。

話が飛躍するかもしれませんが、会社が部署ごとや全社規模でおこなう「宴会」について考えてみてはどうでしょうか。新年会でも忘年会でも、送別会でも歓迎会でも構いません。全社規模で行われる「宴会」なら、社員誰でも参加できるでしょうが、部署ごとに行われる「宴会」なら、他部署の「宴会」なら、参加しようとすると断られる可能性は否定できません。このような事は当然だと思えるし、その理由も納得できるでしょう。

「祭り」という言葉が(伝統的な)祭りを意味せず、ファミレス的な「祭り」や、宴会的な「祭り」までも意味している可能性が、問題を引き起こしている気がします。「祭り」ではないものを「祭り」と呼ぶのも問題ですが、ならば「私たちが言う「祭り」とは、このようなものです」と定義すれば良いのかというと、それは違うだろうと思います。

意味の広い語彙を使うなら、その意味で表現される範囲を踏まえた行動をせざるを得ないでしょう。それを避けたいのであれば、意味の限定された語彙を選択すべきなのではないかと思います。

2019/07/25

鉄道の「駅」の由来

NHKが放送している「ネーミングバラエティー日本人のおなまえっ!」で、2019年7月18日放送では「鉄道のおなまえ」でした。その中の話題のひとつとして、鉄道の「駅」というのは古代から続く「駅制」の「駅」から採用されたと紹介していました。

古代駅制というのは律令時代の話だと思っていたのに、それが明治時代になってステーションの訳語として「駅」を採用する根拠になったことに驚きました。古代の制度が明治直前まで残っていたのだろうかと思います。

そういう疑問を感じていたところで、偶然『ある明治人の記録』を読んでいたところ、興味深い記述を見つけました。柴五郎が青森から東京に出るため、地租改正調査のために東北巡回中の大蔵省役人の首席である長岡重弘の供を願いでて許されました。その件に次のような記述があります。
 六月初旬なり。父上より賜りし竹行李を背負い、草鞋履き山高帽を耳までかぶりて出発す。長岡氏は牛輿に乗り、他は徒歩なり。長岡氏は心優しき人にて、幼少の余をいたわり、同氏の輿に同乗させ、あるいは駅馬に乗せなどして、実際に歩行せるは一日のうち四、五里なり。
ここに「駅馬」という語が現れます。これが番組で紹介された古代駅制のことなのでしょうか。

東京に出てきた柴五郎は、鉄道開通にも立ち会っています。
 九月十二日、東京―横浜間に最初の鉄道開通す。新橋停車場に造られた桟上に登りて参観す。天皇陛下、柿色の御装束を召され、同じく束帯の百官を従え、横浜より帰着の汽車より降り立ち給う。外国公使もまた列席し、荘厳華麗な式典なり。式後御浜御殿苑内開放されてさまざまなる余興あり。紅白の餅を撒き、余もこれを拾いたるを記憶す。

同じような事が『維新前夜』(野村兼太郎、昭和16年4月30日発行)の「鉄道開業式入場券」にも書かれています。しかしそれは『日本鉄道史』からの孫引きです。『日本鉄道史』というのは大正10年に鉄道省が発行したものだと思います。これは国立国会図書館のデジタルコレクションから見ることができます。

『ある明治人の記録』と『武士の娘』

Webで見かけた記事に紹介されていた『ある明治人の記録』を読んでみました。会津藩士の家に生まれた柴五郎が戊辰戦争に巻き込まれ、斗南に移住して底辺を彷徨った末に東京に出てきて陸軍幼年学校に入ります。戊辰戦争で会津が戦った頃から、陸軍幼年学校時代に西南戦争が起こり、その後の竹橋事件の頃までを本人が後年に書き記したものを、石光真人が若干の編集を加えて出版したものです。

会津藩士である柴家は、本書で「父柴佐多蔵は会津藩士、280石の御物頭」とあります。当時の著名な会津藩士というと、家老の西郷頼母が1,700石、同じく家老の家柄の山川大蔵が1,000石ということですから、武家としては中位に属しているのかと思います。柴五郎は陸軍大将にまで上り詰めたということです。戦前までの旧日本陸軍では、陸軍中将は1,200名以上もいるのに、陸軍大将となったのは134名に過ぎなかったそうです。薩長閥が階級を独占していた当時において、会津出身者としては頂点を極めたといえるでしょう。

このような華麗な経歴から逆算すると、人は勝手な想像をたくましくして、幼少の頃から神童の誉れが高かったのだろうとか、陸軍幼年学校に抜擢されて、なるべくしてなったのだろうとか、思いがちですが、本書を読むとそのような印象はまったく無く、むしろ底辺を彷徨った挙句に、運よく道が開けたという感じです。

戊辰戦争で会津藩が敗れ斗南に国替になったとき、柴五郎も親と共に斗南に移り住んだようです。斗南での生活の悲惨さは多く語り伝えられているとおりですが、柴五郎も例外ではなく、極寒の地に放り出された状態で、よくぞ生き残れたものだと思います。

生活が底辺を彷徨うようになると、知らず知らずのうちに精神が荒んでくるものです。当時は「プライド」のような横文字はなかったでしょうし、「自尊心」という言葉もなかったかもしれません。しかし「武士の子たることを忘れしか」と父に叱られたというエピソードが語られる中に、心が崩れていくのを押し留める決意が感じられます。

このようなエピソードに触れたとき、以前に呼んだことがある『武士の娘』を思い出しました。著者の杉本鉞子は越後長岡藩の家老だった家に生まれました。明治6年の生まれなので、既に長岡藩はなく(したがって家老の家でもなく)、戊辰戦争も体験していません。長岡藩は奥羽越列藩同盟の一員として戦い、会津同様に長岡城下が戦場になっています(河井継之助が有名です)。時代は明治なので「四民平等」とされていましたが、「武士の娘」としての教育を受け、その一端が本書で語られています。

柴五郎にしても、杉本鉞子にしても、武家としての誇りを失わずに生きたように思います。しかし失うまいと意地を張っているわけではないように思います。やせ我慢をしているということではないと思います。自然とそうなるのでしょう。その姿を見習いたいものだと思います。

2019/07/20

投票と宝くじ

今年は4月に統一地方選があり、7月には参院選もあり、選挙が多い年になりました。以前から言われていることですが、投票率が下がっているようです。投票することは選挙権の行使ですから、投票しないのは権利を放棄していることになります。権利を行使しないのは残念なことだと思いますが、投票を強制させるような施策を講じるのも違うだろうと思います。

投票しない理由に、「投票しても何も変わらないから」というものがあると聞きます(他にも投票しない理由はあると思いますが)。この理由の真意をもっと分析しないことには軽々しく言えないとは思いますが、ようするに「自分の投票した候補者が当選したら「あたり」で、投票して良かったと感じるが、落選したら「はずれ」で、投票なんかして(時間の)無駄だったと思う」ということなのでしょうか。

こう考えているとすると、投票するのは勇気がいるでしょう。何故なら、誰が当選するか分からないと投票できないからです(勝ち馬に乗りたいということでしょう)。一番圧倒的な候補者に投票しておけば無難なのでしょうが、そういう候補者なら「自分が投票しなくても当選するだろう」と勝手に思い込み、結局投票しないかもしれません。

もしかすると、投票するという行為を、宝くじを買うという行為のように考えているのだろうかと思います。「あたる(当選する)なら、宝くじを買いたい(投票してもよい)」が、「あたるかどうか分からないなら、無駄金を使いたくない(時間を無駄にしたくない)」と、博打を打つ感覚なのでしょうか。

投票というのは、結果も大切なのは当然ですが、支持する(しても良いかなと思える)候補者を選ぶという行為に過ぎません。それだけのことです。それをすることが現代社会にコミットすることになりますから、投票しなければ、その人物は存在しているのに「存在していないとして扱われる」という奇妙な状態を選択していることになるでしょう(意識していないかもしれませんが)。

投票(選挙権の行使)は、自分の考えだけでおこなえば良いことで、他者の意向を気にする必要はないはずです。「自分は政治をよくわかっていないから」とか、「皆さんはどうするんですか」とか、こういうことを考えているなら、考える方向がおかしいと思います。日本人は笑い話のネタにされるくらい同調性を気にする国民なのかもしれませんが、自分の投票する候補者くらい他者の意向を気にせず選べば良いのにと思います。

2019/07/19

名詞に「お(御)」を付けるか否か

名詞に「お」や「御」をつけるのは「丁寧語」に区分されます。これは「敬語」を構成する「尊敬語」、「謙譲語」、「丁寧語」の一つに相当する訳ですが、異論もあります。別に敬意を表しているわけではないから「美化語」と呼ぶべきだと主張しますが、今のところ異説のひとつであって、主流にはなっていないようです。

それはともかく、「お」は和語に、「御」は漢語に付けるのが原則です。ならば外来語の扱いが気になりますが、基本的は「お」も「御」も付けないと考えています(若干の例外はありますが)。

上述したルールは原則なので、例外も勿論ありますが、「お(御)」の有無にも個人差があります。社会一般における許容範囲というものもありますが、特定の世間(業界)における習慣なども考えられ、許容度の異なる集団が接触した場合に違和感や反発が生まれるようです。

よく耳にするのが「なんでも「お」を付けておけば無難」とする考え方です。そう考えている人にとっては、「お紅茶」、「おコーヒー」、「おビール(!)」のように表現するそうなのですが、僕には違和感があります。特に「おビール」とか言われたら「ここはいったいどこなんだ」と思うでしょうが、 「お酒」という表現には違和感がありません。「おビール」と「お酒」で良し悪しが分かれるのは、社会的習慣のなせる業としか言いようがないでしょう。

「お」を付ける語と付けない語の分別は、社会における合意があるようで、微妙なところで一致していないと思われます。だから差異が出てしまうのは仕方のないことで、その違いを愉しむことがコミュニケーションの醍醐味であるのかもしれません。少なくとも、「お」の有無に目くじらを立てて、自分の基準に相手を合わせようと仕向けるのは、多様性を認める社会のあるべき姿ではないと考えます。

さらに考察を進めると、「お」が付くことで意味が変わる場合があります。例えば「受験」という語はどうでしょうか。「お受験」となる場合、「お」を付加したことによる「丁寧語(美化語)」というだけではない含意があります。誰かに対して「受験するのですか?」と尋ねた場合と、「お受験するのですか?」と尋ねた場合は、意味が変わってきます。前者であれば、誰もが経験するような高校受験や大学受験などを想像しますが、後者であれば、(エリートコースを狙っているか否かわかりませんが)私立の小学校受験(もしくは、中学校受験や、場合によっては幼稚園受験など)が言外に意味している筈です。

さらに「勉強が得意ですね」と「お勉強が得意ですね」を比べれば、前者なら誉め言葉として受け取れますが、後者だと(誉め言葉だと主張できる余地を残していますが)あてこすりと判断されてもやむを得ない側面があります。

このように「お」という語は日本の文化や社会現象を表象していると考えてよいだろうと思います。

派生的な話題となりますが、最近たまに耳にするようになった言葉として「お名前様」というものがあります。「名前」を丁寧に表現するために「お」が付いているのに、それだけでは丁寧さが表現できていないと考える人が多くなっている模様です。「なんでも「お」を付けておけば無難」とする発想の延長線上に、「なんでも「様」をつけておけば無難」とする発想が生まれてくるのでしょう。これは現代日本に限った現象ではないだろうと思います。例えば「御御御付け」という言葉があるように、丁寧さを狙って生まれた語彙が、丁寧さとしての感覚を失った際に、さらなる丁寧語が付加されるのは、昔からある現象ということでしょう。

2019/07/18

「微分方程式('17)」と検算のためのWolfram AlphaやMaxima

放送大学で今期は「微分方程式('17)」を受講しています。もうすぐ単位認定試験が行われるので、試験準備のために勉強しています。過去に受講した科目では、試験ぎりぎりになって慌てずに済むように4月から勉強しておけば良かったと(強く)思いながらも、6月末から7月になってから一夜漬けで試験勉強を済ませ、なんとなく単位を取得していました。こんな方法では身につかないと、いつも思うのですが、他にもやることがあることを言い訳にして、いつも直前に焦って試験対応をしていました。

今回は講義の進行に合わせて4月から勉強してきました。印刷教材の章末問題も解き、通信指導についている自習型問題も解いてみました。過去に受講した科目では、これらをやろうと思いながらも、手つかずのまま単位認定試験に臨んでおり、その結果として不完全燃焼感が後に残りました。その反省を踏まえて、4月から少しずつ勉強してきたわけですが、それでも微分方程式は簡単ではありません。印刷教材の内容も、あまり理解できずにいる箇所も少なくありません(特に証明)。 しかしながら、今までは微分方程式(や微積分)は五里霧中という感じでしたが、僅かに薄日が差してきたような気もしています。何事もそうかもしれませんが、勉強してみて分からなかったからと言って投げ出さず、振り落とされそうになってもしがみついていたら、僅かずつでも理解できるようになっていくのではないかと思います。スラスラできるようになれば嬉しいですが、そうでなくても一歩前進したことは間違いありません。

微積分のような理数系科目は、語学のような文系科目に比べると、正誤がはっきりしているので、考えようによっては勉強しやすいとも言えます。微積分を学んでみて、漠然とした概念レベルであれば、別に難しくはないと思います。思考方法の癖のようなものがあったとしても、概念の理解に差し障るほどではないと感じています。それでは何が難しいのかというと、実際に演習問題を解くことです。

理論を理解できているか確認するために、演習問題が用意されている教科書が多くあります。問題が解ければ、理論を理解したと判断されます。もし解けなければ、理論が分かっていないと判断されることになります。理屈の上ではそうですが、実際には問題は解けたけど、理論は理解できていないという事も少なくないのではないかと思います。仮にそうだとしても、演習問題に取り組むことは大切です。問題が解ければ、理解したという気持ちになれますし、問題を解く過程で、教科書に記述されている事柄の意味が分かってくることもあります。

演習を解いて、正解ならば良いのですが、問題なのは不正解だった場合です。よくある間違いは、不正解となった問題を放置して、他の問題に取り組むことです。出来る問題を多数こなした方が良い場合もありますが、不正解の問題について、式の展開などを見直して、間違えたポイントを納得することも大切です。

微積分(に限りませんが)に役立つ道具として「Wolfram Alpha」と「Maxima」を使ってみました。これらの存在は以前から知っていましたが、便利そうな道具らしいと考えているだけでした。どちらにも使い方のコツのようなものがあるので、自分に合った方を使えばよいと思います。今回はWolfram Alphaを多用しました。

Wolfram Alphaを使えば、問題によっては一気に答えが出てきます。便利と言えば便利ですが、自分で勉強しなくても答えが出てくるのは危険でもあります。その答えが導き出される過程を学んでいる筈なので、答えが出てきたことに喜んでいるだけでは、話になりません。しかし途中結果を確認するために使うのであれば、とても役に立ちます。自分の計算が、最終的に正答にならない場合、途中計算のどこで間違えているのかを確認することができるからです。教科書の演習問題によっては、途中結果が示されていないこともありますし、仮に途中結果が示されていたとしても、自分の計算過程とは違う場合もあります。このような場合にWolfram Alphaで計算させてみれば、自分の誤りを見つける参考になります。

Wolfram Alphaを使ってみて便利であることを実感しましたが、無料で使える範囲は制限されており、機能の制限をなくすには有償となるようです。一方でMaximaは、Wolfram Alphaに比べれば素朴な完成度に見えますが、全ての機能を無料で利用できます(自分のマシンにインストールしなければなりませんが)。Maximaが普段使いの道具となるように、使い方を練習しておこうと思います。

2019/07/15

System panicked: kernel diagnostic assertion "(l->l_pflag & LP_INTR) == 0 || panicstr != NULL" failed: file "/usr/src/sys/kern/kern_condvar.c", line 170

dynabook SS SX/15AにNetBSD/i386を入れて利用しています。もう10年以上前のマシンなので、いろいろなところが故障していても不思議ではないとは思いますが、本当に故障しているのか、何か他に原因があるのかは見極めなければなりません。

今春あたりから、カーネルが頻繁に落ちるようになりました。酷い時は、ブート中に落ちて、再起動がかかっている最中に再度落ちて、それが何度も繰り返されます。ところが全く問題なく起動できることもあるのです。何が悪いのでしょう。何処が悪いのでしょう。

何が問題なのか突き止めていませんが、感覚的には「公共施設で無料で使えるWiFiを利用していると落ちることが多い」ような気がしてきました。自宅でも落ちることはありますが、外出先と自宅とでは頻度が全然違う感じがしています。

またクラッシュ情報を解析すると、落ちる場所は決まっています。
# crash -M netbsd.34.core -N netbsd.34
Crash version 8.99.41, image version 8.99.43.
WARNING: versions differ, you may not be able to examine this image.
System panicked: kernel diagnostic assertion "(l->l_pflag & LP_INTR) == 0 || panicstr != NULL" failed: file "/usr/src/sys/kern/kern_condvar.c", line 170
Backtrace from time of crash is available.
crash> bt
_KERNEL_OPT_NARCNET(0,104,c011b026,8,c06f2ad3,c1138f1d,0,104,c10a7924,dc6bdee8) at 0
_KERNEL_OPT_BEEP_ONHALT_COUNT(104,0,c10a7924,dc6bdee8,c4d142e0,c516abe8,c516abe4,dc6bdedc,c0db730e,c10a7924) at _KERNEL_OPT_BEEP_ONHALT_COUNT+0x1
vpanic(c10a7924,dc6bdee8,dc6bdf0c,c090c2a0,c10a7924,c10a788b,c115c4c4,c115c4a0,aa,c5169000) at vpanic+0x13d
kern_assert(c10a7924,c10a788b,c115c4c4,c115c4a0,aa,c5169000,c51d61c8,c5169000,c516abe4,c516abe8) at kern_assert+0x23
cv_wait(c516abe8,c516abe4,ffffffff,c00,82000008,c4d142e0,c5169000,dc6bdf94,c02cc9d8,c5169004) at cv_wait+0x1a8
wpi_stop(c5169004,1,8,82000008,2,101,dc9c6010,dc9c6010,c0921aa9,c13de400) at wpi_stop+0x80
wpi_softintr(c5169000,0,c0100400,1674000,1670010,30,c0100010,10,0,1d14020) at wpi_softintr+0x2cb
softint_dispatch(c4d14020,4,37bbaff2,a1a6dfbe,76bef7da,27b6dfdb,dc6c0ff0,dc6c0e2c,dc6c0e80,80050033) at softint_dispatch+0xc1
Bad frame pointer: 0xc4fdbe48
crash>

カーネルの不具合なのか、マシンのハードウェアが故障しているためなのか、どちらの原因なのか判断する情報がありません。なんとか探ってみようと思います。

2019/07/13

矢内原忠雄「ヨブ記研究」を読んで

NHKで放送されている「100分 de 名著」で「旧約聖書」を取り上げた時に「ヨブ記」が紹介されました。旧約聖書というと「創世記」、「ノアの箱舟」や「モーセの十戒」が有名です(それだけではありませんが)。聖書は「世界で一番売れている書物」とも言われているので、「創世記」や「出エジプト記」を始めとする「旧約聖書」に含まれる諸本は常識の範疇なのかもしれません。

それ以来「ヨブ記」を読んでみようと思っていましたが、ようやく読む機会がありました。それほど長い物語ではないので、読むこと自体は難しくありません。しかし「ヨブ記」に限りませんが、聖書の物語は、旧約聖書も新約聖書も、字面の表面的な意味だけでは理解しにくく、その奥にある含意を理解したいところです。そこで教会に行ってみて質問するという方法もあるかもしれませんが、それよりも一般に参照できる文章として読んでみて、それでも理解できなければ(次の方法として)教会の門を叩くことを考えてみようと思います。そこで図書館に行ってみたところ『聖書講義VIII(第1分冊)』(矢内原忠雄、岩波書店、1978年)の中に「ヨブ記研究」などが含まれていたので借りてきて読んでみました。

「ヨブ記」の解釈が、この書籍に書かれている事柄しかないという訳ではないとは思います。しかし納得できる解釈が提示されていると感じました。「2 ヨブ記の主題」には次のように書かれています。
 ヨブ記の主題は「人生における苦難の意義」である。ヨブ記の著作された時代のこの問題に関する一般的見解は、神は義人に祝福として人生の幸福を与へ、悪人に刑罰として苦難と災害を与へ給ふ、といふのであつた。更に進んで、人の義とこれに与へられる祝福、罪とこれに課せられる災禍とは、それぞれ量的に比例するといふ機械的な考へが支配的であつた。

ここから三段論法的に次のような解釈がなされると書かれています。
  1. 神は義人に幸福を与へ、悪人に災禍を与へ給ふ。
  2. ヨブは大なる災禍を与へられた。
  3. それ故ヨブは大なる悪人であるに違ひない。
  4. ヨブは己が罪を告白して、神の赦しを求むべきである。
  5. さうすれば神はヨブの苦難を解き、彼に幸福をかへして下さるであらう。

このような思考方法は、ヨブ記の時代だけではなく、現代でも同じでしょう。不幸に苦しむのは己の罪によるのだという自己責任論は、今日でも一般に流通しています。しかしヨブは反論します。これを現代風に表現すれば(嫌な表現だとは思いますが)「逆ギレ」していると言われるところでしょう。

ヨブ記では最終的に、ヨブは神に対して己の無知を告白することになります。ここの下りに対して本書では次のように書かれています。
この常識的に見て意外な結末が信仰的に見て意外でないことを知ることこそ、ヨブ記から学ぶ最大の教訓でなければならない。ヨブ自身その教訓をヱホバの御言から学んだが故に、彼はおのれについて後悔し、ヱホバについて満足したのであつた。

これは一体どういうことなのでしょう。世界各地で信仰されている宗教に対して、人々の多くは「義人には幸福を、悪人には災禍を」という素朴とも言える発想で理解しています。だから不幸なのは(だと感じるのは)我が身に罪があるからだと理解しています。しかしながら現実の世界は、悪人(のように見える)なのに幸福で、義人(である筈)なのに災禍にみまわれるのは、良くあります。だから「この世には神はいないのか」とか(心の中で、ですが)叫ぶ人が少なくないのです。

「ヨブ記」はハウツー本ではないので、これを読んで理解すれば直ちにハッピーになれるというようなものではありません。読んで学んだことを自分の人生に生かすには、もっともっと考えなければならないでしょう。その手掛かりの一つを与えてくれる書物には違いないと思います。

2019/07/12

XML形式の情報をCSV形式に変換したい

Microsoft Windowsで使用しているパスワード管理ソフトIDMの情報はXML形式で保存されています。またNetBSDで使用しようと思っているパスワード管理ソフトKeePassXCではCSV形式の情報を取り込むことができるようです。そこでXML形式の情報をCSV形式に変換する手法を検討しようと思います。

すぐに思いつくのが、手頃なツールでテキスト処理をおこなうことでしょう。pythonであれば、標準ライブラリElementTreeでXMLを扱えますし、同じく標準ライブラリCSVもあります。python以外を使っても構いませんし、XMLパースを行わず、XML形式を意識しないでテキスト処理をおこなうことも可能でしょう。

別な方法としてXSLTを利用することもできるようです。
  1. [XML]xsltprocを使って、XMLをCSVに変換する
  2. xmlからcsvへの変換(xsltprocコマンド)
  3. XML to CSV Using XSLT

XSLTについては、名前だけは知っていますが、実際に使ってみた経験はありません。それを言ったら、pythonでElementTreeやCSVを扱った経験もないのですが、python自体は経験がありますので、その延長線上でなんとかなると思っています。ここでXSLTを使ってみるのも、経験値を上げるには良いのではないかと思っています。

NetBSDではpkgsrcにあるtextproc/libxsltxsltprocが入っているようです。またIBMのサイトに次のような情報も見つけました。
  1. ヒント: XSLT の極意
  2. XSLTはどのような言語か

Sn(f;{xj},{ξj})

以前に入手したサイエンス社の「数理科学」2018年5月号(特集/微積分の考え方)を読んでいます。内容が専門的(と言っても、専門の中では初歩段階ですが)なので、理解しながら読もうとすると、なかなか先に進みません。理解できる(と自分では思える)必要がなければ、数ページ程度ならあっという間に読んでしまえますが、それでは読んだ後には何も残らないでしょう。そこで時間はかかりますが、何度も繰り返し読んで(他の書籍、Web情報などからの理解も試みますが)みて、少しずつでも理解できるようにしているところです。

このような専門的な記事を理解する際には、その専門知識の素養が必要となる事は言うまでもありません。加えて、教科書などで説明されるほどでもないような、ちょっとした知識(常識と言い換えても構いません)が、理解する上での障害になることもあります。

例えば「積分の見方」(筧三郎、pp.35-42)には次のような記述がありました。
 そして,閉区間[a,b]上で定義された関数f(x),[a,b]の分割{xj} (j=0,1,...,n),代表点{ξj} (j=1,2,...n)を定めたときの“リーマン和”Sn(f;{xj},{ξj})を,次のように定義する:

ここで疑問に思ったのが「Sn(f;{xj},{ξj})」で使われている「;」です。専門的な書籍において、たまに(自分にとって)見慣れない使われ方をしている記号を目にすることがあります。その説明が書籍内にあれば、ひとつ理解が進んだという気になれるのですが、何も説明がない場合が(多いように思う)あります。おそらく著者にとって常識に属しているので、わざわざ説明するまでもないと考えているのでしょう。

こういう場合にWebを検索し、自分と同じような疑問を解決しようとしている情報を見つけることができます(見つからないかもしれませんが)。すると「数学でのセミコロンについて」を見つけました。要するに「真っ正面から論じれば、セミコロンなんか使う意味はありませんで、カンマにしとく方が真っ当である。」ということのようです。ここに書かれているような解釈で正しいのかは別途検証する必要がありますが、当面気にしすぎなくても良いということが分かってホッとしています。

2019/07/10

KeePassXCの文字化け(「@」→「"」)が復旧

dynabook SS SX/15AにNetBSDを入れ、MATEデスクトップ環境を採用し、利用環境を整えています。ただ残念ながら所々に怪しい動作が残っています。Firefox(pkgsrcから入れるとNightlyになりますが)を入れ、パスワード管理ソフトとしてKeePassXCを入れました。

パスワード管理ソフトとして、Microsoft WindowsではIDMを使っています。NetBSDでは、過去にはKeePassを使おうとしていましたが、よく落ちて不安定なので、あまり利用していませんでした。そこでKeePassを止めてKeePassXCを使ってみることにしました。

KeePassXCを使うのが初めてなので、IDMで利用しているエントリを試しに入れてみて使い勝手を確認してみようとしました。ユーザーIDはメールアドレスなので「@」が含まれています。ところが入力時に「@」が「"」に化けてしまいます。このままでは利用できないので、調査しました。

全ての文字が化けている訳ではないようです(確かめた訳ではありませんが)。「@」が「"」に化けるというのは、ASCII配列キーボードとJIS配列キーボードの相違を思い起こさせます。

問題の在所を絞り込むために、幾つか条件を変えて挙動を確認しました。
  1. rootアカウントで動作を確認しました。rootアカウントではMATEデスクトップ環境を使用しておらず、昔懐かしtwmのシンプルな(質素な?)画面構成です。ここでは問題となっている文字化けが起きませんでした。と言う事は、MATEデスクトップ環境の何かに原因がありそうです。
  2. KeePassXCを起動する前に、環境変数LANGCにして起動してみました。しかし問題となる現象は変わりませんでした。
  3. xevを使ってKeePassXCがブラウザに送っているイベントを調べてみました。やはり「"」を送っているようです。
    KeyPress event, serial 39, synthetic NO, window 0x3200001,
        root 0x7e, subw 0x0, time 1699682, (657,286), root:(811,465),
        state 0x2001, keycode 11 (keysym 0x22, quotedbl), same_screen YES,
        XKeysymToKeycode returns keycode: 48
        XLookupString gives 1 bytes: (22) """
        XmbLookupString gives 1 bytes: (22) """
        XFilterEvent returns: False

MATEデスクトップ環境の設定の中に「キーボード」があるので、調べてみました。すると何故か以下のようなエントリが入っており、しかも「US English」が最上位になっています。
  1. US English
  2. Japanese
  3. Japanese (kana)
  4. Japanese

不思議なのは、キーボードの指定の最上位に「US English」があっても、通常のキー入力には何の問題もないのです。dynabook SS SX/15Aのキーボードは(ノートPCとしての)JIS配列です。これまで使っていて、JIS配列通りにキー入力が出来ています。しかし設定が怪しいので、「デフォルト」ボタンを押したら、「Japanese」のエントリを残して、他の3つのエントリが消えました。

この状態でKeePassXCの動作を確認したところ、問題となっていた文字化けは解消しました。キーボードの指定が変だったのが原因だったようです。

これでKeePassXCは正常に使える状態になったので、利用環境を整える調査を続行しようと思います。

「ブラウザー統合」を有効にしたKeePassXCとFirefoxが接続できない

dynabook SS SX/15AにNetBSDを入れて、利用環境を整えようとしています。ブラウザとしてFirefoxを使うので、パスワード管理ソフトとしてKeePassXCを使ってみようと考えています。pkginを使って入れた出来合いのバイナリパッケージは、「ブラウザー統合」が有効になっていませんでした。仕方ないので、「ブラウザー統合」が有効になるように定義して、自前でビルドしました。

自前ビルド版KeePassXC 2.4.0を立ち上げると、設定画面に「ブラウザー統合」が現れました。そこでFirefoxを選択したのですが、設定が記憶されません。立ち上げるたびに、Firefoxの設定が外れているので、毎回設定する必要がありますが、何が悪いのか分かりません。

ブラウザ(Firefox)側にはKeePassXCと連携するためのアドオンを入れる必要があります。入れたのですが、エラーが出てしまいます。
Cannot connect to KeePassXC.  Check that browser
integration is enabled in KeePassXC settings.

KeePassXCとブラウザが連携すると使い勝手が良いようなのですが、連携しなくてもKeePassXCは利用できる筈です。ひとまず非連携モードで使ってみました。

試しにエントリを準備してみました。使い勝手は、Microsoft WIndowsで利用ているIDMと似ている気がします。そのような使い勝手であることには納得しましたが、なぜか入力文字列が化けてしまいます。文字が全て化けるのではなく、メールアドレスに使われている「@」が「"」に変化してしまいます。どうしてこうなるのでしょう。これが解決しない事には、KeePassXCを本格的に利用するわけにはいきません。なんとかしたいと思います。

ちなみに、自前でビルドして「ブラウザー統合」が有効になりました。しかしブラウザ側と繋がらないし、なくても良さそうなので、 pkginから導入する出来合いのバイナリパッケージを使うことにしようと思います。

「ブラウザー統合」を有効にしたKeePassXCがビルドできた

dynabook SS SX/15AにNetBSDを入れて利用しています。このマシンには元々はMicrosoft Windows Vistaが入っていました。その頃に利用していたIDMというパスワード管理ソフトの代替を探していましたが、KeePassXCが良さそうなので使ってみることにしました。手間暇を惜しむためにpkginを利用して出来合いのバイナリパッケージを使うことにしています。

KeePassXCを起動してみると、なぜか設定画面に「ブラウザー統合」がありません。調べてみたところ、どうやらpkgsrcから作成すると「ブラウザー統合」が無効になっていることが分かりました。そこで「ブラウザー統合」を有効にしたものをpkgsrcから自前でビルドしてみようと思います。

ところがビルドしようとしたらエラーが出ました。
[  5%] Built target keepassxcbrowser_autogen
[  5%] Building CXX object src/browser/CMakeFiles/keepassxcbrowser.dir/NativeMessagingBase.cpp.o
In file included from /usr/include/stddef.h:37:0,
                 from /usr/include/g++/cstddef:50,
                 from /usr/pkg/qt5/include/QtCore/qglobal.h:46,
                 from /usr/pkg/qt5/include/QtCore/qatomic.h:41,
                 from /usr/pkg/qt5/include/QtCore/QAtomicInteger:1,
                 from /usr/pkgsrc/security/keepassxc/work/keepassxc-2.4.0/src/browser/NativeMessagingBase.h:22,
                 from /usr/pkgsrc/security/keepassxc/work/keepassxc-2.4.0/src/browser/NativeMessagingBase.cpp:19:
/usr/pkgsrc/security/keepassxc/work/keepassxc-2.4.0/src/browser/NativeMessagingBase.cpp: In member function 'void NativeMessagingBase::newNativeMessage()':
/usr/pkgsrc/security/keepassxc/work/keepassxc-2.4.0/src/browser/NativeMessagingBase.cpp:65:5: error: invalid static_cast from type 'std::nullptr_t' to type 'intptr_t {aka int}'
     EV_SET(ev, fileno(stdin), EVFILT_READ, EV_ADD, 0, 0, nullptr);
     ^
*** Error code 1

Stop.
make[2]: stopped in /usr/pkgsrc/security/keepassxc/work/keepassxc-2.4.0/build
*** Error code 1

このエラーを見るとEV_SET()に問題がありそうです。調べてみると、EV_SET()が使われているのは、どうやらここだけのようです。
% find work/keepassxc-2.4.0/src -type f | xargs grep EV_SET
work/keepassxc-2.4.0/src/browser/NativeMessagingBase.cpp:    EV_SET(ev, fileno(stdin), EVFILT_READ, EV_ADD, 0, 0, nullptr);

しかも、この箇所はLINUX以外のUNIX系OSにしか影響がないようです。ソースの変更状況を確認するとKeePassXC 2.3.0-betaの頃に入ったコードのようです。
    53  void NativeMessagingBase::newNativeMessage()
    54  {
    55  #if defined(Q_OS_UNIX) && !defined(Q_OS_LINUX)
    56      struct kevent ev[1];
    57      struct timespec ts = {5, 0};
    58
    59      int fd = kqueue();
    60      if (fd == -1) {
    61          m_notifier->setEnabled(false);
    62          return;
    63      }
    64
    65      EV_SET(ev, fileno(stdin), EVFILT_READ, EV_ADD, 0, 0, NULL);
    66      if (kevent(fd, ev, 1, nullptr, 0, &ts) == -1) {
    67          m_notifier->setEnabled(false);
    68          ::close(fd);
    69          return;
    70      }
    71
    72      int ret = kevent(fd, NULL, 0, ev, 1, &ts);
    73      if (ret < 1) {
    74          m_notifier->setEnabled(false);
    75          ::close(fd);
    76          return;
    77      }
    78  #elif defined(Q_OS_LINUX)
    79      int fd = epoll_create(5);
    80      struct epoll_event event;
    81      event.events = EPOLLIN;
    82      event.data.fd = 0;
    83      if (epoll_ctl(fd, EPOLL_CTL_ADD, 0, &event) != 0) {
    84          m_notifier->setEnabled(false);
    85          ::close(fd);
    86          return;
    87      }
    88
    89      if (epoll_wait(fd, &event, 1, 5000) < 1) {
    90          m_notifier->setEnabled(false);
    91          ::close(fd);
    92          return;
    93      }
    94  #endif
    95      readLength();
    96  #ifndef Q_OS_WIN
    97      ::close(fd);
    98  #endif
    99  }

EV_SET()に問題がありそうだという事、またLINUX系ディストリビューションには影響がない(から、そちらからのフィードバックで修正される)事は分かりましたが、どのように直したら良いのかわかりません。ただしエラーメッセージを見る分にはキャスト絡みのようです。Webを検索したら「*BSD で kqueue・kevent を使ってみよう」というページが見つかりました。それを見ると、EV_SET()の最後のパラメータはNULLが指定されています。これが問題の原因なのでしょうか。

試しにnullptrNULLに書き換えてみたところ、エラーが消えてビルドに成功しました。ただし、このような変更が正しいのかは、確信がありません。nullptrというのはC++11で導入されたようですが、次のような情報も見つかりました。
  1. NULLとnullptrの違い 
  2. C NULLがC 11 nullptrと等しいか 

ビルド出来ましたが、keepassxc-proxyというのも出来ていました。このためPLISTを変更する必要がありました。
--- PLIST.org   2019-03-23 00:56:41.000000000 +0900
+++ PLIST.new   2019-07-10 09:31:09.155023065 +0900
@@ -1,5 +1,6 @@
 @comment $NetBSD: PLIST,v 1.4 2019/03/22 15:56:41 ryoon Exp $
 bin/keepassxc
+bin/keepassxc-proxy
 bin/keepassxc-cli
 lib/keepassxc/libkeepassx-autotype-xcb.so
 man/man1/keepassxc-cli.1

ちなみにMakefileは次のように変更しました。
--- Makefile.org        2019-03-23 00:56:41.000000000 +0900
+++ Makefile.new        2019-07-10 15:29:19.274685074 +0900
@@ -18,7 +18,7 @@
 USE_CMAKE=     yes
 USE_LANGUAGES= c c++
 CMAKE_ARG_PATH=        ..
-CMAKE_ARGS+=   -DKEEPASSXC_BUILD_TYPE=Release
+CMAKE_ARGS+=   -DKEEPASSXC_BUILD_TYPE=Release -DWITH_XC_BROWSER=ON -DWITH_XC_NETWORKING=ON
 CONFIGURE_DIRS=        build
 
 NOT_PAX_MPROTECT_SAFE+=        bin/keepassxc
@@ -36,6 +36,7 @@
 .include "../../devel/zlib/buildlink3.mk"
 .include "../../graphics/hicolor-icon-theme/buildlink3.mk"
 .include "../../security/libgcrypt/buildlink3.mk"
+.include "../../security/libsodium/buildlink3.mk"
 .include "../../security/argon2/buildlink3.mk"
 .include "../../sysutils/desktop-file-utils/desktopdb.mk"
 .include "../../x11/qt5-qtbase/buildlink3.mk"

2019/07/09

KeePassXCの「ブラウザー統合」は有効に出来そうだけど、ビルド失敗

dynabook SS SX/15AにNetBSDを入れて利用しています。パスワード管理にKeePassXCを使おうと思いましたが、pkgsrcからビルドされるバイナリには拡張機能「ブラウザー統合」が有効になっていないことが分かりました。

この問題を解決するために、pkgsrcの枠組みに沿って変更するためには、どのようにするのが正しい方法なのか不明です。それは追々調べるとして、まずは「ブラウザー統合」を有効にしたバイナリをビルドしてみようと思います。

まずsecurity/keepassxc/Makefileを以下のように変更してみました。またlibsodiumが必要になるようなので、依存関係の定義を追加しました。libsodiumのパッケージ自体も入れておきます。
--- Makefile.org        2019-03-23 00:56:41.000000000 +0900
+++ Makefile    2019-07-09 20:05:49.976935366 +0900
@@ -18,7 +18,7 @@
 USE_CMAKE=     yes
 USE_LANGUAGES= c c++
 CMAKE_ARG_PATH=        ..
-CMAKE_ARGS+=   -DKEEPASSXC_BUILD_TYPE=Release
+CMAKE_ARGS+=   -DKEEPASSXC_BUILD_TYPE=Release -DWITH_XC_BROWSER=ON -DWITH_XC_NETWORKING=ON
 CONFIGURE_DIRS=        build

 NOT_PAX_MPROTECT_SAFE+=        bin/keepassxc
@@ -36,6 +36,7 @@
 .include "../../devel/zlib/buildlink3.mk"
 .include "../../graphics/hicolor-icon-theme/buildlink3.mk"
 .include "../../security/libgcrypt/buildlink3.mk"
+.include "../../security/libsodium/buildlink3.mk"
 .include "../../security/argon2/buildlink3.mk"
 .include "../../sysutils/desktop-file-utils/desktopdb.mk"
 .include "../../x11/qt5-qtbase/buildlink3.mk"

この状態でビルドさせてみると「ブラウザー統合」が有効になっていることが確認できます。
===> Configuring for keepassxc-2.4.0 keepassxc-2.4.0
*SNIP*
-- Enabled features:
 * Auto-Type, Automatic password typing
 * Networking, Compile KeePassXC with network access code (e.g. for downloading website icons)
 * KeePassXC-Browser, Browser integration with KeePassXC-Browser

-- Disabled features:
 * SSHAgent, SSH agent integration compatible with KeeAgent
 * KeeShare, Sharing integration with KeeShare
 * KeeShare-Secure, Sharing integration with KeeShare with secure sources
 * YubiKey, YubiKey HMAC-SHA1 challenge-response

-- Configuring done
-- Generating done
-- Build files have been written to: /usr/pkgsrc/security/keepassxc/work/keepassxc-2.4.0/build

またlibsodiumなどの依存関係も大丈夫そうです。
=> Tool dependency glib2-tools-[0-9]*: found glib2-tools-2.60.3
=> Tool dependency cmake>=2.8.1nb1: found cmake-3.14.5
=> Build dependency x11-links>=1.13: found x11-links-1.15
=> Build dependency cwrappers>=20150314: found cwrappers-20180325
=> Full dependency qrencode>=4.0.2: found qrencode-4.0.2
=> Full dependency hicolor-icon-theme>=0.9nb1: found hicolor-icon-theme-0.17
=> Full dependency libgcrypt>=1.6.0: found libgcrypt-1.8.4
=> Full dependency libsodium>=0.3: found libsodium-1.0.17
=> Full dependency argon2>=20161029nb1: found argon2-20171227
=> Full dependency desktop-file-utils>=0.10nb1: found desktop-file-utils-0.23nb1
=> Full dependency qt5-qtbase>=5.11.2nb3: found qt5-qtbase-5.12.2nb1
=> Full dependency qt5-qtsvg>=5.11.2nb2: found qt5-qtsvg-5.12.2
=> Full dependency qt5-qttools>=5.11.2nb2: found qt5-qttools-5.12.2
=> Full dependency qt5-qtx11extras>=5.11.2nb2: found qt5-qtx11extras-5.12.2

これでビルド出来るかと思いきや、なにやらエラーが出てしまいました。
[  5%] Built target keepassxcbrowser_autogen
[  5%] Building CXX object src/browser/CMakeFiles/keepassxcbrowser.dir/NativeMessagingBase.cpp.o
In file included from /usr/include/stddef.h:37:0,
                 from /usr/include/g++/cstddef:50,
                 from /usr/pkg/qt5/include/QtCore/qglobal.h:46,
                 from /usr/pkg/qt5/include/QtCore/qatomic.h:41,
                 from /usr/pkg/qt5/include/QtCore/QAtomicInteger:1,
                 from /usr/pkgsrc/security/keepassxc/work/keepassxc-2.4.0/src/browser/NativeMessagingBase.h:22,
                 from /usr/pkgsrc/security/keepassxc/work/keepassxc-2.4.0/src/browser/NativeMessagingBase.cpp:19:
/usr/pkgsrc/security/keepassxc/work/keepassxc-2.4.0/src/browser/NativeMessagingBase.cpp: In member function 'void NativeMessagingBase::newNativeMessage()':
/usr/pkgsrc/security/keepassxc/work/keepassxc-2.4.0/src/browser/NativeMessagingBase.cpp:65:5: error: invalid static_cast from type 'std::nullptr_t' to type 'intptr_t {aka int}'
     EV_SET(ev, fileno(stdin), EVFILT_READ, EV_ADD, 0, 0, nullptr);
     ^
*** Error code 1

Stop.
make[2]: stopped in /usr/pkgsrc/security/keepassxc/work/keepassxc-2.4.0/build
*** Error code 1

なかなか一筋縄ではいきません。この問題を解決する方法を探ってみます。

2019/07/08

KeePassXCの拡張機能「ブラウザー統合」が無効

dynabook SS SX/15AにNetBSD/i386を入れ、MATEデスクトップ環境を利用しています。パスワードを管理するために、以前はKeePassを使おうとしていましたが不安定(すぐに落ちてコアを吐く)だし、pkgsrcにあるソースからビルドしようとしても、依存関係にあるMonoがビルド出来なかったりで、散々でした。KeePassを使い出した頃は選択肢が他になかったのですが、今ではKeePassXCがpkgsrcに入っているので、こちらを使用することにしました。

KeePassXCはブラウザ側にアドオンを入れることで連携できるようになるそうです。連携できると何か便利になるのか、それとも無くても構わないものなのか、体験してみないことには判断できません。ブラウザにはFirefoxを使っているので、アドオン「KeePassXC-Browser」を入れて、どんなものなのか動作を確認してみようとしました。ブラウザ側のアドオンを使うには、KeePassXC側の設定「ブラウザー統合」で利用するブラウザを選んでおく必要があるそうです。そこでKeePassXCの設定画面を開いたのですが、「ブラウザー統合」という項目がありません。

Webで情報をあつめてみても、「ブラウザー統合」 という設定項目は存在しているもののようです。事前に何かの設定を有効しておく必要があるとか、前準備が要るというものではないようです。しかしNetBSD/i386のpkgsrc 2019Q1にあるKeePassXCには「ブラウザー統合」がありません。どういうことでしょう?

この現象が起きているのは、僕のマシンが不良なのか、NetBSDの問題なのか、KeePassXCの特定のバージョンに起因する障害なのか、原因を絞り込まなければなりません。Webを検索して直ちに解決策が見いだせれば良いのですが、「ブラウザー統合がメニューに出てこないのは何故?」というような質問をしている人は見つかりませんでした。

NetBSDでMATEデスクトップ環境を利用する上で、何かの調査に役立つかと思って、Microsoft WIndows10上のVirtualBoxでUbuntu MATEの環境を作ってありました。ここにKeePassXCを入れてみて、NetBSDとの違いを確認してみます。すると驚いたことに、設定画面には「ブラウザー統合」が最初からありました。やはり存在するのが当たり前ということなのでしょう。

UbuntuのKeePassXCには設定「ブラウザー統合」があり、NetBSDのKeePassXCには設定「ブラウザー統合」がありません。その事実は確認できましたが、もっと情報を集められないでしょうか。KeePassXCのメニューの中に「デバッグ情報」という画面がありました。

まずNetBSDでは以下にようになっています。
KeePassXC - Version 2.4.0

Libraries:
- Qt 5.12.2
- libgcrypt 1.8.4

Operation system: NetBSD 8.99.43
CPU architecture: i386
Kernel: netbsd 8.99.43

Enabled extensions:
- Auto-Type
次にUbuntuでは以下のようでした。
KeePassXC - Version 2.4.3
Revision: 5d6ef0c

Qt 5.9.5
Debugging mode is disabled.

Operation System: Ubuntu 18.04.2 LTS
CPU architecutre: i386
Kernel: linux 4.18.0-15-generic

Enabled extension:
- Auto-Type
- ブラウザー統合
- SSHエージェント
- KeeShare (signed and unsigned sharing)
- YubiKey

Cryptographi libraries:
libgcrypt 1.8.1

どうやら拡張機能「ブラウザー統合」が利用できない状態になっているようです。それは確認できましたが、なぜ利用できないのか、その原因は不明のままです。NetBSDにある共有ライブラリの何かに問題があるのかもしれませんし、拡張機能「ブラウザー統合」が利用できるのはLinuxとかWindowsなどに限定されているのかもしれません。

GitHubにあるKeePassXCの「Build and Install KeePassXC」を見ると、衝撃的な記述がありました。
cmake accepts the following options:

-DWITH_XC_AUTOTYPE=[ON|OFF] Enable/Disable Auto-Type (default: ON)
-DWITH_XC_YUBIKEY=[ON|OFF] Enable/Disable YubiKey HMAC-SHA1 authentication support (default: OFF)
-DWITH_XC_BROWSER=[ON|OFF] Enable/Disable KeePassXC-Browser extension support (default: OFF)
-DWITH_XC_NETWORKING=[ON|OFF] Enable/Disable Networking support (e.g., favicon downloading) (default: OFF)
-DWITH_XC_SSHAGENT=[ON|OFF] Enable/Disable SSHAgent support (default: OFF)
-DWITH_XC_TOUCHID=[ON|OFF] (macOS Only) Enable/Disable Touch ID unlock (default:OFF)
-DWITH_XC_FDOSECRETS=[ON|OFF] (Linux Only) Enable/Disable Freedesktop.org Secrets Service support (default:OFF)
-DWITH_XC_KEESHARE=[ON|OFF] Enable/Disable KeeShare group synchronization extension (default: OFF)
-DWITH_XC_KEESHARE_SECURE=[ON|OFF] Enable/Disable KeeShare signed containers, requires libquazip5 (default: OFF)
-DWITH_XC_ALL=[ON|OFF] Enable/Disable compiling all plugins above (default: OFF)
拡張機能「ブラウザー統合」を利用するためにはビルド時に「-DWITH_XC_BROWSER」を指定しなければなりませんが、デフォルトは「OFF」なので、あえて指定してビルドしない限り「ブラウザー統合」が無効になっているKeePassXCが出来上がってしまうのです。

pkginが拾ってくる2019Q1の出来合いのバイナリは、拡張機能が無効になったままでビルドされたのでしょう。デフォルトが「ON」になっている拡張機能は「Auto-Type」だけのようですから、上述したデバッグ情報に出ているものと一致します。

ここまで確認したところで、pkgsrc「security/keepassxc」をビルドさせてみました。コンパイルが始まる前の環境設定情報収集フェーズのログを見ると、案の定、ほとんどの拡張機能が無効になったままでした。
-- Enabled features:
 * Auto-Type, Automatic password typing

-- Disabled features:
 * Networking, Compile KeePassXC with network access code (e.g. for downloading website icons)
 * KeePassXC-Browser, Browser integration with KeePassXC-Browser
 * SSHAgent, SSH agent integration compatible with KeeAgent
 * KeeShare, Sharing integration with KeeShare
 * KeeShare-Secure, Sharing integration with KeeShare with secure sources
 * YubiKey, YubiKey HMAC-SHA1 challenge-response

-- Configuring done
-- Generating done
-- Build files have been written to: /usr/pkgsrc/security/keepassxc/work/keepassxc-2.4.0/build
=> Rewrite cmake Dependencies files
===> Building for keepassxc-2.4.0
これで原因が判明しました。pkgsrcをビルドすると、拡張機能「ブラウザー統合」が無効になったKeePassXCが出来てしまうのです。これを有効にしたければ、pkginなどで出来合いのバイナリパッケージを利用しては駄目だということです。自分でソースからビルドさせる必要があるでしょう。

2019/07/07

/usr/pkg/qt5/lib/libQt5XcbQpa.so.5: Undefined PLT symbol "FT_Get_Font_Format" (symnum = 407)

dynabook SS SX/15AにNetBSD/i386を入れて利用しています。先月以来アプリケーションを更新するために四苦八苦してきましたが、ようやく落ち着いてき(たと思ってい)ました。

元々このマシンはMicrosoft Windows Vistaがインストールされていました。OSをNetBSDにしましたが、使い勝手を同等にしようと考えていたので、その意図を満たせるアプリケーションを入れていました。そのひとつがKeePassです。Microsoft WindowsではIDMを使っていましたので、代替ソフトとしてKeePassを選んでみました。KeePass以外にも、KeePassXKeePassXCがあることを承知していますが、IDMの代替ソフトを探していた当時はpkgsrcにKeePassXCが入っていませんでした。KeePassXは機能的に満足せず、消去法でKeePassを選択しました。

KeePassはC#で書かれているそうです。NetBSDではMonoという実装を使っており、あまり具合が良くありません。特に問題なのが、pkgsrcからのビルドでトラブルを起こすことです。また実行中におちたりしますが、これはMonoが悪いのか、マシンの環境の何かの不具合なのか見極められていません。KeePass自体は悪くないと思うのですが、Monoにはうんざりしていました。ありがたいことにpkgsrcにはKeePassXCが入っているので、KeePassからKeePassXCに乗り換えることにしました。

KeePassXCを起動しようとしたら、次のようなエラーが出て動きません。調査しようと思って先延ばしにしていましたが、実は同じエラーがwiresharkでも出ていました。
/usr/pkg/qt5/lib/libQt5XcbQpa.so.5: Undefined PLT symbol "FT_Get_Font_Format" (symnum = 407)

この問題を解決しようとWebに情報を求めましたが、解決に至るような情報を見つけられませんでした。念のために、いつものように、/usr/bin/lddで共有ライブラリの参照状況を確認してみましたが、参照不能はありませんでした。しかし参照状況が怪しいものが見つかりました。freetype.17を参照しようとしてlibfreetype.so.18を見にいっています。
-lfreetype.17 => /usr/X11R7/lib/libfreetype.so.18
libfreetype.so/usr/X11R7/libにあるので確認してみました。するとlibfreetype.so.18のリンク先がlibfreetype.so.17.4.11になっています。
lrwxr-xr-x  1 root  wheel      22 May 23  2016 /usr/X11R7/lib/libfreetype.so -> libfreetype.so.17.4.11
lrwxr-xr-x  1 root  wheel      22 May 23  2016 /usr/X11R7/lib/libfreetype.so.17 -> libfreetype.so.17.4.11
-r--r--r--  1 root  wheel  589796 May 23  2016 /usr/X11R7/lib/libfreetype.so.17.4.11
lrwxrwxr-x  1 root  wheel      22 Jul  7 14:34 /usr/X11R7/lib/libfreetype.so.18 -> libfreetype.so.17.4.11
このシンボリックリンクは、何時頃のことなのか記憶に定かではありませんが、自分で作りました。何かのアプリケーションがlibfreetype.so.18を必要としており、このようにリンクを張ったら動作したので、それで解決したと思っていました。それが今頃になって悪さをしているようです。

それでは本物のlibfreetype.so.18は何処にあるのでしょうか。調べてみるとNetBSD 8.0が提供するxbase.tgzに含まれているようです。考えてみると、このマシンにNetBSDを導入した時はNetBSD 7.0.1でした。その時はlibfreetype.so.17だったのでしょう。その後にソースからビルドしたNetBSD 8.99系に更新しましたが、X関係は手付かずのままだったようです。

障害の原因は見えてきたので、NetBSD 8.0に含まれているX関係コンポーネントを全て入れることで、NetBSD 7.0.1時代のX関係コンポーネントを上書きしました。これでkeepassxcが動くことを確認しました(wiresharkも)。
lrwxr-xr-x  1 root  wheel       22 Jul 17  2018 /usr/X11R7/lib/libfreetype.so -> libfreetype.so.18.0.13
lrwxr-xr-x  1 root  wheel       22 May 23  2016 /usr/X11R7/lib/libfreetype.so.17 -> libfreetype.so.17.4.11
-r--r--r--  1 root  wheel   589796 May 23  2016 /usr/X11R7/lib/libfreetype.so.17.4.11
lrwxr-xr-x  1 root  wheel       22 Jul 17  2018 /usr/X11R7/lib/libfreetype.so.18 -> libfreetype.so.18.0.13
-r--r--r--  1 root  wheel   613332 Jul 17  2018 /usr/X11R7/lib/libfreetype.so.18.0.13

これまでNetBSDの更新は/usr/srcでビルドして入れ換えていましたが、/usr/xsrcは何もしていませんでした。X関係を更新するのがNetBSDのメジャー番号が上がった場合だけで良いなら、今回同様にキットから展開すればよいでしょう。それともソースからビルドして入れ換える必要があるのか、調べておきたいと思います。

2019/07/05

共有ライブラリの参照状況を確認

dynabook SS SX/15AにNetBSD/i386を入れ、アプリケーションはpkgsrcから入れています。もう1年以上もアプリケーションを更新していなかったので、6月上旬にpkgsrcをCVSでカレントの最新にしてpkg_rolling-replaceで作りなおし始めました。しかし導入済みのアプリケーションが多く、もとより数日で終わるとは思っていませんでしたが、ディスクが溢れたり、毎晩カーネルが落ちて日中の作業が無駄になったりして、6月下旬になっても全更新作業が終わりませんでした。

このままでは何時になったら全更新が完了するのか不安になってきたので、ソースから自前でビルドsるのを止めて、pkginを使って出来合いのバイナリ(2019Q1のpkgsrcからビルドされたもの)をインストールして済ませることにしました。流石にバイナリを入れるだけなので、ソースからビルドするのに比べると圧倒的に速く全更新が完了しました。

しかしpkgsrcのカレントからビルドしたパッケージと、2019Q1のpkgsrcからビルドされたパッケージが混在し、共有ライブラリの参照に不整合が生じてしまいました。不整合に気づくたびに対処していく事で、復旧できるのは確かですが、全体的に不整合が残っているのか解消したのか、判断できず不安が残ります。なんとかしたいので、対処してみました。

実現方法の詳細はともかくとして、やろうとすることは単純です。すなわち/usr/bin/lddで検査して異常がないことを確認するだけです。例えば以下に示す例ではlibclang.so.7が見つからずに「not found」となっています。参照できない状態がなければ問題ないと判断します。
/usr/pkg/qt5/bin/qdoc:
        -lexecinfo.0 => /usr/lib/libexecinfo.so.0
        -lelf.2 => /usr/lib/libelf.so.2
        -lgcc_s.1 => /usr/lib/libgcc_s.so.1
        -lc.12 => /usr/lib/libc.so.12
        -lclang.7 => not found
        -lQt5Core.5 => /usr/pkg/qt5/lib/libQt5Core.so.5
        -lz.1 => /usr/lib/libz.so.1
        -licui18n.63 => /usr/pkg/lib/libicui18n.so.63
        -licuuc.63 => /usr/pkg/lib/libicuuc.so.63
        -licudata.63 => /usr/pkg/lib/libicudata.so.63
        -lpthread.1 => /usr/lib/libpthread.so.1
        -lstdc++.8 => /usr/lib/libstdc++.so.8
        -lm.0 => /usr/lib/libm.so.0
        -lpcre2-16.0 => /usr/pkg/lib/libpcre2-16.so.0
        -lgthread-2.0.0 => /usr/pkg/lib/libgthread-2.0.so.0
        -lglib-2.0.0 => /usr/pkg/lib/libglib-2.0.so.0
        -lpcre.1 => /usr/pkg/lib/libpcre.so.1
        -lintl.1 => /usr/lib/libintl.so.1

/usr/bin/lddの出力から「not found」を見つけるために、簡単なawkスクリプトを準備しました。文字列を検索するだけならgrepでも出来ますが、見つかった文字列の属しているファイル(この例であれば/usr/pkg/qt5/bin/gdoc)が何なのか記録できません。awkスクリプトは次のようなもので、単独のコマンドとして使えるように、実行ビットを立てておきます。
#!/usr/bin/awk -f
/:$/ {
        filename = $0;
}
/not found/ {
        print filename, $0;
}
# [EOF]

共有ライブラリの参照に問題があるのは、動的リンクされた実行ファイルや共有ライブラリだけです。静的リンクされた実行ファイルとかテキストファイルなどは検証する必要がありません。当初は検証対象を限定しようと思っていたのですが、対象ファイルを見つける方法を考えるのが面倒になってきたので、強引ですが、マシン内の全てのファイルを対象とすることにしました。処理に無駄が出ますが、単純な処理で済みますし、結果をファイルに落としておいて最終的に確認すれば良いだけのことです。結局2時間ほどで全ファイルの検証が終わりました。

この検証をおこなったコマンドは以下の通りです。上述したawkスクリプトは「notfound.awk」というコマンドにしています。
find / -type f | sed -e 's/^/ldd "/' -e 's/$/"/' | sh 2>&1 | notfound.awk > notfound.log

findで対象を見つけた場合には、xargsでコマンドに渡すのが定番です。しかしsedshを組み合わせてコマンドを動かしています。当初はxargsを使おうと思っていたのですが、Microsoft Windows由来のファイルがあり、ファイル名の中に空白文字が含まれるため、findxargsの組み合わせでは、処理できなかったのです。

結果を記録されたファイルには、予想していたよりも相当多いファイル名が記録されていました。しかし/usr/pkg/opt/usr/pkg/emul/linuxなどにあるLinux版ファイルが大多数を占めており、本当に問題があったのは数ファイルだけでした。それらは対処したので、不整合の問題は解決した(それ以外に起因する問題は残りますが)と思います。