あるソースコードにテーブルが配列として含まれているという状況で、メンテナンス性を高めるためにその内容を別のファイルに分離して、機械処理で配列として出力し、それをincludeするという手段を考えました。 これをautomakeで実現するのはそれほど難しくないのですが、autotools依存を避けるためにCMakeで実現する方法を調べてみました。 最終的に、以下のようなCMakeLists.txtで実現できました。 src/kk2.cがk2rom_hepburn.cをincludeすることを前提としています。k2rom_hepburn.cはperl scriptを通してtable/k2rom_hepburn.txtから生成します。 生成するスクリプトはadd_custom_commandを使います。OUTPUTに出力するファイル名、COMMANDに実行するコマンドを記述します。行が長くなる場合には、改行を任意の箇所で入れられるようです。 出力するファイルk2rom_hepburn.cを直接ターゲットとして扱えないようなので、add_custom_targetでgenerate_headersというターゲットを明示して作成し、その依存関係としてk2rom_hepburn.cを記述します。 最後に、作成したターゲットを依存関係へ組み込むためadd_dependencyを使います。これで、libkakasiの生成にgenerate_headersが依存することを明記しました。 以上のステップを踏むことによって、k2rom_hepburn.txtからk2rom_hepburn.cが生成された上でkk2.cがコンパイルされ、それをもとにlibkakasi.soが出力されます。
Rowhammer問題私的まとめ
確認できた範囲の情報を記録しておこうと思います。 Rowhammer問題 最近のメモリで見られる 同じ行に連続してアクセスすると直接アクセスしていない領域の値が化ける現象(RowHammer問題) を利用してLinuxで権限昇格ができる模様 http://t.co/10kwCTzMyJ — Fadis (@fadis_) 2015, 3月 10 PC Watchの記事「DRAMスケーリングの課題と打開策」にて解説がなされています。以下当該記事より引用: Row Hammer問題は、DRAM技術が微細化したことで深刻になり始めたメモリセル間の干渉によって発生するエラーの問題だ。 DRAMメモリセルの同じRow(行)に対する連続したアクセスが、隣接したRowのセルのデータを不安定し、エラーを生じさせる。この問題は2012年頃から話題になり始めた。Intelはメモリ制御に関する特許(Row hammer condition monitoring, US 20140006704 A1など)の中で言及した。そして、今年(2014年)6月のコンピュータアーキテクチャ学会「ISCA (International Symposium on Computer Architecture)」でRow Hammerに関する論文が発表されたことで、コンピュータ業界で広く知られるようになった。 ハードウェアについてあまり詳しくないのですが、高密度化、高速化したメモリで、特定のセル(row)に高い頻度でアクセスすると隣接するrowのメモリ内容が化ける、という現象のようです(Rowhammerの論文PDF)。 攻撃への応用 Googleのセキュリティ対策チーム”Project Zero”が、この現象を応用して攻撃に利用する、という記事を公開しました(“Exploiting the DRAM rowhammer bug to gain kernel privileges“)。応用例として、ChromeのNaClサンドボックス上で本来実行できないはずの命令を実行させたり、カーネルの権限上昇を行う手法が解説されています。 確認手段 userlandで試験を行うツールがgithubで公開されています(“https://github.com/google/rowhammer-test“)。また、memtest86 6.0.0 Free editionにもRowhammerテスト機能が追加されているようです。 rowhammer_testを実行して、実際にエラーが起きると以下のような出力をして停止します。 自分はデスクトップ(non-ECC)x2、ノート(non-ECC)x1、サーバー(ECC)x1に対して実施してみましたが、以前から挙動が若干怪しげなデスクトップマシン1台でのみ検出されました。 Google Groupsにてある程度報告が上がってきていますが、発生するときは数十~数百程度の試行回数で発生するようです(上記自分の例では11回目で発生)。自分の他のマシンでは1万以上行っても問題が出ませんでした。 自分はVirtualBox環境下でこのテストに引っかかったのですが、GroupsではXen guest上でエラーを検出できたという報告もありました。Cygwinでも確認できるよそうです。 @knok 参考になるかはわかりませんが、原理上 Cygwin… Continue reading Rowhammer問題私的まとめ
ruby+selenium+chromeでgmail送信
rubyのselenium-webdriverでgmailの操作を試みた結果、なんとか動くものができたのでメモしておきます。 同様のことをC#でやっている事例はあったのですが、rubyのCSSセレクタが思うように動きませんでした。結局、CSSではなくIDを指定してボタンの操作をしました。 URLはこんな感じの組み合わせでメールの内容を指定できます。 https://mail.google.com/a/?view=cm&tf=1& (定型?) to=nokubi@gmail.com& (toに送信先アドレスを指定) su=test& (suにサブジェクト) body=test (bodyに本文) これは”Mailto: for GMail“の拡張を参考にしました。
OpenCVのテンプレートマッチング
3DSのプチコン3号をどうにかしたいという目標を持ったので、3DSタッチパネルディスプレイに表示されるソフトウェアキーボードを、OpenCVを使って位置を認識させる、ということを試してみました。 まずはあらかじめ、キーボードの写真を撮っておきます。撮影にはNexus5の内蔵カメラを使いました。画像が若干傾いていたので、撮った写真をgimpで加工し、ほぼ長方形になるよう調整しました。 この画像から、キーを一つ切り出します。とりあえず「1」のキーを切り取ってみました。 キーボードの全体画像からこの「1」のキーを検出する方法として、テンプレートマッチングを行ってみます。OpenCVのサイトにそのものずばりのC++サンプルが掲載されています。自分はどこかのページで見たコードを参考に以下のようなものを作成しました。 search_imgを対象画像とし、tmp_imgにマッチする領域をtemplateMatch関数で算出します。アルゴリズムの選択には、特に何も考えずサンプルのまま(CV_TM_CCOEFF_NORMED/Collection coefficient)にしました。これにより、演算結果がresult_imgに代入されます。 その結果から、minMaxLoc関数を用いてresult_imgから値が最大となる位置を算出します。cv::Matは行列データ型であり、minMaxLocは行列内の最大値、最小値を持つ座標とその値を取得する関数です。今回の場合、必要なのは最大値の座標だけです。 サンプルプログラムではrectangle関数で該当する矩形領域に線を引いています。 自分はC++に不慣れなので、同じことをPythonでやってみようとしました。いろいろと試行錯誤の結果、以下のようなコードになりました。 rectangleに与えるべき引数がC++とはちょっと異なります。C++では矩形の起点と高さ+幅を与えるのに対し、Pythonでは2つの対角上の頂点の座標を指定します。最初この違いに気付かなくて、思うような結果にならず悩みました。 今回はスケールが同一の画像でのテンプレートマッチングだったので期待通りの結果を得ることができましたが、実際の利用をする場合には異なるサイズや、若干傾いた画像、他に余計なものが写りこんでいる画像などを相手にする必要があるので、もっといろいろな下処理などが必要になるものと思われますが、まずは第一歩を進めることができました。
壊れた仮想ディスクを扱う
立ち上げっぱなしのWindowsマシンが、気が付くとBSoDで落ちてしまいました。原因は追加したHDDにあるようで、Linuxで観測してみると不定期にSATAのエラーを吐きます。 再起動したら、HDD自体が認識されず困ったので、testdiskでパーティションテーブルの復元を試みました。幸いなことに、これでNTFSパーティションの復旧はできました。このtestdiskはSystemRescueCD辺りも含まれているので、普段から起動ディスクとして用意しておくと安心です。 しかしこれだけでは不完全で、NTFSパーティション自体がdirtyになっていたので、回復コンソールからchkdsk /fを実施することでファイルシステムレベルの修正できました。 しかし不幸はこれだけでは終わりませんでした。対象HDD内においていた仮想マシンが起動しなくなり、grubのプロンプトに落ちるという状況になりました。Debianのインストーラーrescueモードで見ると、そもそもext2/3としてのsignatureまで壊れてしまっているようでした。 使っていた仮想マシンのディスク形式はVMware Playerからimportしてきたvmdk形式だったので、いったんqemu-imgでraw形式に変換し、kpartxでパーティションを認識、fsckを実施しました。 大量のエラーが発生し、lost+foundにかなりのデータがおいやられたものの、なんとかfsckは完走しました。/homeごとなくなってしまいましたが… 幸い、以前変換したときの元のイメージも残っていたので、現在はそちらをraw形式に変換してデータの復元を試みています。重要なデータはlost+foundの方を参照することにします。
安価なBluetoothヘッドフォン
ずいぶん前にAmazonで購入したBluetoothヘッドホンを長らく使っていました。MM-BTSH24と同等品だったと思うのですが、当時2500円ぐらいで購入した記憶があります。 メーカー純正品は結構高価なのですが、同等品が当時と同じぐらいの値段で売られているようです。 長く使っていたせいか、耳あて部分の片方が若干痛んできています。先週末にあきばお~でBSHSBE19(白)が税別1999円で販売されていたので、この機会に買ってみました。Amazonでも3000円程度で購入できるようです。 違いはいろいろありますが、どちらにも一長一短があります。BSHSBE19は新しい製品なので、以下のポイントが個人的に良いと思っています。 Bluetooth 4.0対応 マルチポイント(2デバイス対応) ノイズキャンセリング搭載 microUSBによる給電 一方MM-BTSH24の方がよかったなあ、と思う点は以下です。 クリップ型 個人的に耳は小さい方なので、カナル型よりもクリップ型である点は好みでした。必然的にノイズキャンセリング機能は載せられなくなってしまいますが、自分の用途だと主にジムで運動しながらというシチュエーションが多いので、むしろ環境音も聞こえた方が都合が良いです。 操作ボタンが多い 物理的サイズが大きい分、搭載されている操作ボタンが電源・再生ボタン、ボリュームボタンx2、選曲ボタンx2と多くあります。一方BSHSBE19は電源(スライドスイッチ)、マルチファンクションボタン、ボリュームボタンx2となっています。ボリュームボタンを長押しすると選曲ができるのですが、選曲を含めたあらゆる機能に音声ガイドがついているため、何か操作するたびに喋るのがちょっと煩わしいところです。 MM-BTSH24も使えなくなったわけではないので、当面は両方を使い分けることになりそうです。
VMware PlayerからVirtualBoxへの移行
最近のスラッシュドットの記事から、VMware Playerのライセンスにおける「非商用の解釈がかわった」という記事(ライセンス解釈が変わったようです。)を目にし、この機会にVirtualBoxへの移行を実施しました。 移行対象は違いますが、既にやってみた人の記事(VMware Fusion 5からVirtualBox 4.3への移行)があったので、作業自体はそれほど難しくはありませんでした。ただ、この記事にもあるようにストレージをSCSIからIDEに変更する、という作業はVMware Playerでも同様に必要でした。 自分の場合、もう一点「ホストオンリーネットワークもそのまま移行したい」という希望があったので、そのために若干の作業が発生しました。参考にしたのは「VirtualBoxのネットワーク設定とCentOS6.5のインストール」です。こちらの記事はMacOSXのようですが、Windowsでも行うことはあまり変わりません。 VirtualBox マネージャーからメニューの「ファイル」「環境設定」を選択し、ダイアログを開きます。さらに「ネットワーク」「ホストオンリーネットワーク」を選択し、ネットワークを追加します。ネットワークレンジやネットマスクを、これまでVMware Playerで使っていたものと同じになるよう設定します。 ここで一点注意があります。VMware Playerが入ったままだと、VMwareの仮想ネットワークインターフェースが設定として保持されたままになるので、vmnetcfg.exeで設定を変更するか、VMware Playerをアンインストールする必要があります。そうしないと、同一のネットワーク設定が存在しているとWindows側に認識され、リンクローカルなネットワークが強制的に割り当てられてしまいます。 あとはOVF化した仮想マシンをVirtualBoxからインポートし、ネットワーク設定を先ほど作成したホストオンリーネットワークに指定して、実際に通信ができれば完了です。 NATネットワークの移行も、ほぼ同様の手順で実行し、Window側のネットワーク共有を使えばできると思います。
Web APIのリトライ処理実装
Web系のAPIをたたいていると、たまにエラーが発生することがあります。要因はサーバー側がたまたまおかしかったり、proxyだったりと様々です。 エラー時にはリトライしつつAPIをたたく方法はいろいろ考えられますが、C#でのスマートな実例がStackOverflowで紹介されていました。リトライ専用のクラスとstaticメソッドを実装して、呼出にはデリゲート、ラムダ式を用いるという手法です。 Rubyでも同様の処理を行うコードを考えてみました。
CVE-2008-0166の爪痕
偶然にも500万個のSSH公開鍵を手に入れた俺たちはという資料が公開されました。GitHubから公開鍵を大量に集めて調査してみたという内容なのですが、なかなか衝撃的だったので英語blogで内容をかいつまんで紹介してみました。 500万個のssh公開鍵のうち、Debian/Ubuntuで作成されたブラックリスト入りの鍵が208件あったそうです。割合として考えてみればそれほど多くはないのですが、まだ爪痕が残っていることを実感します。
ELECOM UCAM-C0220Fを使う
ふと思うところがあって、安価なUSBカメラを購入しました。エレコムの200万画素で安価(1000円程度)なモデルです。 最終的な目的の用途とは異なるのですが、とりあえず自宅の様子をストリーミングさせてみました。かつてはgstreamerを使っていろいろと余計な苦労をする羽目になったのですが(Google Slideの資料9ページ目参照)、いまどきはffmpeg/libavを使ってVorbis/TheoraやWebMにエンコードし、icecastに配送させるのが簡単だと思います。 このデバイスは映像入力をUVCクラス、音声(マイク)入力をAudioクラスとした複合デバイスに見えます。 ffmpegでalsaデバイスとしてこのオーディオデバイスを使うと、定期的に”[alsa @ 0x15fcc00] ALSA buffer xrun.”というエラーが出ます。どうもUSB audioとしての動作が何かおかしいようです。この状態でoggfwdを続けていると、icecast側から接続を切られてしまいます。まあ自分の主目的は映像をとることなのでその用途には十分使えそうです。