朝は整形外科でリハビリテーション。 牽引こんでなかった。
やっと噂の一般保護例外が出た。 例によって cc1 だがとても楽しいことになっている。
GPE flags 00003202 err 00000000 0033:0101356e * RAX 00000001 RCX 00000AED RDX A656C63796320 RBX 012B7050 RSP 7FFE731E3668 RBP 00000000 RSI 00000007 RDI 015B7AED R8 015B7AED R9 0000007F R10 00000005 R11 00000007 R12 7F146FCAB410 R13 7F146FCC0078 R14 015B7AED R15 7F146FC8C248
表示しているのは VMM 内に自分で追加したテストプログラムなので表示がいい加減なのはそのせい。 とにかく %rip=0x0101356e で一般保護例外だ。 フラグは IOPL=3, IF=1, bit1=1 以外は 0 だ。
[31] cs 33 ip 0101356e sp 7ffe731e3668 code 04d info1 00000000 info2 00000000 ( 00b78900 c3ff5fd0/2be81872 85ff56df) br[00c67aee->01013560] ex[7f146ff13828->7f 146ff13860]
これも自分が追加したプログラムによる出力なので意味がわからないと思うが、code 04d が一般保護例外による #VMEXIT を表す。 謎の 00b78900 は Guest Instruction Bytes を出したもので、一般保護例外は対象でないので記録されておらず、下位 4 ビットは 0 になっている。 その後ろの 2be81872 85ff56df のところは、%rip を同じ論理 CPU 上で VMM から読み出したもので、キャッシュが壊れているわけではないことを確かめるためにやってみたものだ。br のところが LastBranchFromIP と LastBranchToIP である。 最後の分岐が 0x00c67aee から 0x01013560 だと言っている。
%rip のところを gdb で逆アセンブルすると以下のように出た:
ここまでなら、「条件ジャンプで一般保護例外が出るなんて!」で終わる。 そのまま再開すれば動くんじゃないのとも言いたくなる。 しかし、そうじゃないんだな。 スタックを見てみよう。=> 0x101356e <_Z22private_is_attribute_pPKcmPK9tree_node+14>: jb 0x1013588 <_Z22private_is_attribute_pPKcmPK9tree_node+40>
0x7ffe731e3668: 0x0000000000c67af3 0x000000fb00000010
0x0000000000c67af3 は 0x00c67aee+5 であり、call 命令のようである。 そこは正しい。 呼び出しもとの call 命令は以下のようにちゃんとある。
c67aee: e8 6d ba 3a 00 callq 1013560
なので、分岐の情報は合っている。 じゃ、その先は?
1013560: 48 83 ec 08 sub $0x8,%rsp 1013564: 8b 42 20 mov 0x20(%rdx),%eax 1013567: 48 39 f0 cmp %rsi,%rax 101356a: 75 1c jne 1013588 101356c: 48 8b 72 18 mov 0x18(%rdx),%rsi
一発目にスタックポインターの減算である。 上のスタックダンプを見ての通り、これは実行されていないとしか思えない。 しかも、%rip が指しているのは 4 バイトの mov 命令の 3 バイト目である。 ますますおかしい。
ここで頭をよぎるのが、何度も見ている 0x40 問題。 まさか、このサブルーチンの 0x40 手前に何かあるのだろうか?
1013520: 48 8b 57 10 mov 0x10(%rdi),%rdx 1013524: b8 01 00 00 00 mov $0x1,%eax 1013529: 48 85 d2 test %rdx,%rdx 101352c: 74 e9 je 1013517 101352e: 48 8b 4a 10 mov 0x10(%rdx),%rcx
それっぽい命令が並んでいる。 順に検証しよう。 最初の mov 命令が読み取るメモリーの内容を確認する。
(gdb) x/xg 0x10+$rdi 0x15b7afd: 0x000a656c63796320 (gdb) p/x $rdx $5 = 0xa656c63796320
完全に一致。 次の mov 命令がセットするレジスターの内容を確認する。
(gdb) p/x $rax $6 = 0x1
これも完全に一致。 その次の test は上で確かめた %rdx の値に対してで、これを実行すると必ず CF=0, OF=0 になる。 また、%rdx の下位 8 ビットで立っているビットはひとつだから、PF=0 だ。 値はゼロでないので ZF=0 だ。 つまりフラグレジスターの値にも矛盾はない。 当然その次の条件ジャンプはジャンプせず、その次の mov 命令でアクセスすることになるのが %rdx+0x10 番地。 この番地は 48bit の符号付き整数で表せる範囲を超えているので、そこにアクセスすれば一般保護例外が発生する。 そしてこの命令がある番地 0x101352e は、見事に %rip-0x40 だ。 うわぁぁぁ。
さて、これを再開するとしたら、まず、いくつかのレジスターの値を復旧させなければならない。callq 1013560 の直前を見ると %r12->%rdx, %rax->%rsi だったことがわかるので、そこから %r12->%rdx をもう一度と、%rsi->%rax をすれば復旧完了。 あとは %rip=0x1013560 にして再開だ。 予想通り成功した。
そんなわけでね、ここ数日の印象としては、命令デコーダーか何か、その辺がひどく変な感じがする。 命令関係のキャッシュが原因の可能性もありそう。 番地の違うキャッシュをなぜか使っちゃってる、みたいな? そしてそのキャッシュだかなんだかわからないがたぶん 64 バイト単位なのでは。 でも分岐アドレスがズレて記録されていたのもあったな。 あれは何だ。
自宅サーバー PC につながらなくなり、自宅電話にもつながらない状態。 だいぶ不安になりながら帰宅し、ルーターの状態を確認。 電話は「auひかり電話サービス利用不可」という表示。WAN 側 IP アドレスは表示されていたが、再起動を行ったところそれも消えてしまった。
ダイナミック DNS の更新のログを見ると 16 時過ぎにはつながらなくなっていた模様。KDDI に電話で聞いてみたところ、建物全体で問題があるようで原因調査中とのこと。 なんだろうねぇ。 だいぶ前に一度あったんだよね、こういうの。
au ひかりは、結局、きのうの 16 時 17 分には使えなくなっていたのが、今日の 19 時 17 分も使えなかったようで、そこから 20 時頃までの間に復活したようだ。7 年前にトラブった時は迷惑掛けましたって紙がポストに入っていたと思ったが、今回はそのときより長く 24 時間超えたけど何も無し。
職場のノート PC にむち打って (冷却ファンがとまっていて熱々に...) Debian GNU/Linux 9 へのアップグレードを実行した結果、systemd を消そうとして停止するという被害にあった。
おっかしいな、なおってるってことになっているっぽいな。 まあいい、手で何とかした。 これは sysvinit にしてある他の環境では問題にはならないと思う。 他には、console-setup のフォント設定が起動時に反映されない被害に遭っている。
これは不思議なことに自宅の Ryzen PC では問題が起きていないので、UEFI ブートかどうかが関係しているのかも。 まー原因はともかく、最近の高解像度ディスプレイともなればデフォルトのフォントサイズは目つぶしでしかないと思うので、最初からもっと大きくしてていいんでないのかな。1024x768 でテキスト 80x25 が収まるくらいのサイズで十分でしょう。
64 バイトズレの問題のきっかけはやはり、先日出た不思議なページフォールトの件だ。 この問題は TLB フラッシュやら分岐の記録やらしなくても何度か再現している。 今日見た 2 回分 (1 秒以内に連続して発生) を下に載せてみる。 前のと表示内容は変えてある。
[31] cs 33 ip 0113f57d sp 7ffeb1823680 code 04e info1 00000006 info2 0000000a pte 00000003be53c025 PF flags 00003206 err 00000006 cr2 a 0033:0113f57d * RAX 00002000 RCX 00000007 RDX 00000000 RBX 02867F40 RSP 7FFEB1823680 RBP 7FFEB1823698 RSI 00000001 RDI 7F2E8E9CF000 R8 000009BA R9 7F2E8E987DD0 R10 7F2E8E983000 R11 000001F2 R12 0289B9D0 R13 0000000A R14 0000000A R15 0289D410 [31] cs 33 ip 0113f57d sp 7ffd7de01330 code 04e info1 00000006 info2 0000000a pte 00000003be53c025 PF flags 00003202 err 00000006 cr2 a 0033:0113f57d * RAX 0000F680 RCX 00000007 RDX 00000000 RBX 02E15F40 RSP 7FFD7DE01330 RBP 7FFD7DE01348 RSI 0000001F RDI 7FB0E8021000 R8 00001513 R9 7FB0E7FDF898 R10 7FB0E7FD5000 R11 00000437 R12 02E51DB8 R13 0000000A R14 0000000A R15 02E535E0 113f57d: 45 8b 69 10 mov 0x10(%r9),%r13d 113f53d: 49 89 55 00 mov %rdx,0x0(%r13)
これ。 エラーコードが 6 で、書き込み時のページフォールトを表し、アクセス先のアドレスは 0xa。 しかし %rip が指す命令は、全然違うアドレスの読み取り。 そしてちょうど 64 バイト手前にそれっぽい命令があるという形。 この 64 バイトはただの偶然の可能性もあったが、その後も LBR や call 先のズレなどの形で現れたというわけ。 なお、このページフォールトの件ではこの 0x113f57d の直前にジャンプ命令などなく、レジスターの中身を見ても直前までは順番に実行されてきたとしか思えない状態。
美しく説明できるのはこのくらいで、他はいきなりアドレス 0x11 にアクセスとか、アドレス 0x11 にジャンプとか、アドレス 0 にジャンプとか、そんなふうにいまいちわからないものも多い。 ま、たまに以下のようにファイルサイズのことなるイメージが出力されていることもあるしな。 問題が起きてもクラッシュに至らないケースもあるということだろう。
104 -rw-r--r-- 1 root root 7056208 2017-06-22 16:35:45.535340840 +0000 arch/x86/boot/bzImage 105 -rw-r--r-- 1 root root 7056176 2017-06-22 16:37:15.741843546 +0000 arch/x86/boot/bzImage
『恋のから騒ぎ』の小林麻央出演のところ、YouTube で少し見てみた。 こんな声だったかな、と思ったけど、説教部屋のシーン見てたら思い出してきたよ。 やっぱこの頃は見てたなーこれ。 同学年だし。 番組おもしろいし。
【ノーカット】市川海老蔵、妻・小林麻央さん死去を報告「愛してる」と言って旅立つ - YouTube
あごに転移とか、退院・在宅医療とか、最期が近づきつつあるともとらえられるニュースはちらほらあったけど、ついに。35 歳をむかえる前に。 同年代の人が病気で旅立つというのはやはり寂しい。 合掌。
きのう、今日と天気が良かったので掘りやすかったけど、今年は小さめのが多かったな。 畑が変わって何か違うのかな。
帰って洗って乾かして段ボール箱に。 一個はスコップを突き刺してしまったので夜には食べた。
ブックオフの株主総会には行こうかと思っていたけどやめた。 おみやげ無くなったみたいだしな。
ディーエヌエーの株主総会には行った。 今回は渋谷だから大変行きやすい。 品川より本社に近いし (同じビル)、多摩地域だけでなく埼玉も横浜も新宿・渋谷あたりは行きやすいと思うのだが、なぜ今まで品川でやっていたのか。 キュレーション関係の問題で突っ込む人はそんなにいなかった。 確かに結構中の仕組みを入れ替えて来ている感じがするし。 最後の人は Google やら YouTube やらはいいのにといった感じの擁護意見、それはでも自分は違うような気がするけどな。 お金を払って書かせていたってのがね。
テレビでやってた映画『マーキュリー・ライジング』(原題: Mercury Rising)。1998 年のアメリカ映画。 日本語吹き替え版。 ブルース・ウィリス主演。 自閉症の子供が重要な役割を果たす。 自閉症は病気ではない、など、知的障害者と見なした人に対する反論も映画の中に出てきており、誤解を招かないよう注意深く描写されているような感じ。 前にもそういう障害を持つ人が出てくる映画見たな。 『レインマン』だ。 あれはサヴァン症候群だったけど。
暗号を解けてしまう自閉症の子供とその家族を消そうとするアメリカ国家安全保障局というアホな設定である。 他の自閉症の子供が解けないとでも思ったのだろうかという間抜けな話である。 ま、いいや、それで連邦捜査局に勤める主人公が何とか子供を守ろうとするのだった。
出てくるコンピューターがブラウン管ディスプレイ... なのはいいんだが、1998 年にしては、Windows 95 などの影響を受けていない感じの、昔風のインターフェイスが出てくる。 物語としては電話は盗聴されているしコンピューターを使うのもまずい、なんて話になり、タイプライターにカーボンコピーが使われ、そのカーボン紙が証拠になる。 自分は子供の頃にカーボン紙を触ったことがあって知っているが、今時の、2000 年頃以降に生まれた人達から見れば何がなんだかわからないかも知れない。 あ、一応、携帯電話は出てきたな。 大きくて、しかもそれを人に借りるという...
この映画、ちょっとした銃の撃ち合いがある程度で基本的には静かな映画なのかと思いきや、鉄道は出てくるし、ヘリコプターも出てくるし、派手な銃撃戦が最後に待っていた。 結構どかどかと派手にやってすっきりするタイプの映画だった。
映画を見ていたので裏番組の F1 アゼルバイジャン GP 予選を見ようと思って iMac を起動した。DAZN は Safari に Silverlight プラグインを入れると見られる。Mozilla Firefox でも見られるのかも知れない。iMac のディスプレイは動画向きではなく、残像が残るというかにじんだ感じになるが、画面が大きいのでタイムは見やすいし、映画の横でチラチラ見る分にはさほど気にならない。 というか、それより 25fps なのが気になる。
予選はさすがメルセデス。 ポールポジション獲得回数一覧に未だにアイルトンセナの名前が残っているわけだが、ついにハミルトンが抜いた。 もうちょっとでミハエルシューマッハの記録に到達だ。 このトリッキーな市街地コースでこのタイムだし、本当にすごいなぁ。
車のワイパーゴムを初めて自分で交換した。 特に工具もいらない簡単な作業。 ゴムの溝にブレードのつめが引っかけてある形、ゴムの溝の端っこにストッパーのためのふくらみがあり、端っこのつめがそこにはまって取れにくくなっている。 それと、金属製の棒がはまっていて、これがブレードと合わせてバネの効果を出しているみたい。
そんなわけなので、ストッパーを無視して無理やり引っこ抜き、金属棒を新しいゴムに移して、またブレードのつめに引っかかるように差し込み、最後にストッパーに引っかかるように押し込めば完了。 抜くとき、ブレードを外さずに行うと、ワイパーを立てるとガラスに当たって抜けないので、少し浮かせたくらいの角度で引っこ抜き、ブレードがガラスに当たらないようにワイパーを立てておく。 入れる時もまた似たような角度で入れる。
NETGEAR の GS108E を導入。 これで Ryzen PC とバックアップ用 PC をちゃんとつなぐことができた。8 ポートで VLAN にも QoS にも対応、お手頃価格でちょっと PC が増えてきた家庭用にぴったりである。 なお、ルーターとつないでいる LAN ケーブル (自宅にある LAN ケーブルの中では一番長い) が思っていたより 10cm くらい短くて、当初考えたところにスイッチングハブを置けなかったけど、まいっか。
よく寝た日。
今回の Formula One アゼルバイジャン GP は本当にぐだぐだだった。 いくら市街地コースとはいえここまでひどいのは久しぶりでは。 セーフティカーが機能していないと言ったらアレだが、タイヤ温度が下がってしまって、再開のたびにアクシデントが起こるという悪循環、結局赤旗。 そもそもはセーフティカーがなかなか入らなかったのも謎だが、その結果、レース序盤では想像もしなかったメンツが表彰台、ルーキーのストロールは初表彰台。 ドライバーズポイントを争うふたりもぐだぐだとは言え 4・5 位完走。 ペレスやライコネンは結局リタイヤ。 まーでも今回の見てても、フェラーリやメルセデスや、フォースインディアもかな、ちょっとホイールが接触した程度ではサスペンションが壊れることはないんだよな。 今年のマクラーレンは何かとすぐ壊れる感じ。
そういえば 2 週間ほど前に睡眠薬を飲んで車を運転して単独の物損事故を起こした芸人のニュースがあった。 たいした事故じゃなかったのは良かったが睡眠薬を飲んで運転とは何事かという話であった。
自分は睡眠薬は飲んだことがないが、眠気を催すおそれのある薬というのはいくらでもあり、そういう注意書きがある薬を飲んで車両 (車やバイクや自転車) を運転したことは何度もある。 そういう意味では他人事ではないのだが、明らかに眠くなった経験のある薬を飲んで眠くなる前に運転をしたというのはないと思う。 たぶん。 普通の総合感冒薬にもその手の成分は入っているが、何度も飲んでいてそれで眠くなった経験がないものは自分的には大丈夫なのかなという判断。
もちろん、いつも大丈夫だったからといって次も大丈夫とは限らないといえばそうで、体調次第では変なふうに効き目が現れるおそれもある。 しかし、それを言うなら、薬を飲んでいなければ大丈夫という話ではなくて、睡眠不足とか体調不良とか、そういうところに気をつけなければならない。 まぁでも現実は、旅客運送などのプロドライバーの方を除いて、ちょっと体調が変だからとか、ちょっと睡眠時間が短かったからとか、そんな理由で運転を完全に取りやめることはないものかも。 病院に行くにも車がないとという環境もあるだろうし、そういう時に体調がすぐれない場合は、休み休みいくとか、人通りの少ない道と時間を選んでゆっくりいくとか、万が一のことがあっても被害を最小限に食い止める工夫も必要だろうか。
なお、今処方されている薬の中にモービック錠というのがあり、視力や眠気に関する注意書きが書かれていることに最近気づいた。 薬局でも特に口頭で言われたことはないし、もう 2 週間くらい飲んでいるけど (分量は変わったけど) そういう症状は何も出ていない。 過去に何かですごく眠くなる薬を処方されたことはあった気がする。 でもあのときも毎回だいたい眠くなるタイミングってものがあったような...
あ、この問題って運転に限らないな。 歩いていても、駅や踏切でばったり倒れて線路の中に入ってしまったら一大事だ。
Ryzen PC の gcc (cc1) が吐いた core dump。Segmentation fault と出て、さらに、dmesg を見ると segfault が出ていた。 何か、core dump を吐かせるためにわざとシグナルハンドラーを消して再実行でもしているのかと思っていたが、core dump をよく見るとどうやら違ったみたいだ。
dmesg に残った segfault と core を見ればアドレス 0x11 を読み取ろうとしてクラッシュしており、アドレス以外に不審な点が見当たらない。 何度か見ていたなぜかアドレス 0x11 にジャンプする事象、それと関係はあるのだろうとは思っていたが、バックトレースには internal_error() などの関数名が出ており、よくよく追ってみたところ、全く同じ事象だった。 真相はこうだ。
そんなわけで、シグナルハンドラーらしきところにフレームを戻し p/x *(struct sigcontext *)($sp+0x38) でそれっぽいレジスター状況が確認できた。 プログラム的に $sp には push %rbx の内容、+8 には戻り番地が入っているはずで、その先のオフセットは手探り。IA-32 なら引数はスタックに積まれるのが普通なので、戻り番地の次にシンプルにシグナル番号と struct sigcontext が見えるはずなのだが、AMD64 ではレジスター渡しが普通なので、struct はどうやって渡されるんだったかな。 でもどっか近くにあるだろということで、フラグレジスターや %cs レジスターの値が合うようにずらしたらこの +0x38 で出た。 で、中身を見ていくと見事にアドレス 0x11 へのジャンプ。 なんでそんなところにジャンプしてしまうのかは、まだ特定できていない。
ま、とりあえず、core dump がはかれるケースがある理由が特定できたのは進歩だ。 別にクラッシュ原因を深く追う意味はないんだけど、こういうパズルは楽しいので。
謎が解けてきたぞ。%rip=0x11 で停止した時のスタックポインター 0x7ffc95e3ed48 の手前を見るとこうだ。
0x7ffc95e3ed28: 0x00007ff14f638dc8 0x00007ff14f638db0 0x7ffc95e3ed38: 0x0000000000d858e0 0x0000000000000011 0x7ffc95e3ed48: 0x0000000000000011 0x0000000000000000
0x11 に ret してしまったらしいこれ、その前にある 0x0000000000d858e0 が、実は 0x40 ズレた位置の戻り番地だ。(以下、シンボル名は長いので削ってある。)
d8589b: e8 90 d2 2b 00 callq 1042b30 d858a0: 8b 54 24 7c mov 0x7c(%rsp),%edx
%rip が本来の位置とはズレたまま call を呼んだわけだ。 相対番地なので call 先もズレてしまうようだ。
1042b70: 39 c2 cmp %eax,%edx 1042b72: 0f 47 d0 cmova %eax,%edx 1042b75: 83 fa 01 cmp $0x1,%edx 1042b78: 0f 85 97 00 00 00 jne 1042c15 1042b7e: b8 01 00 00 00 mov $0x1,%eax 1042b83: 5b pop %rbx 1042b84: c3 retq
来た来た。push していないのに pop して ret したらそりゃズレる。 レジスターの値をいくつか確認したがそれっぽい。 例えば %rbx は 0x0000000000d858e0 になっている。 だがここでいくつかのレジスターを壊してしまうから追いにくい。 それをもうちょっと調べられるといいなと思ったわけだ。 そこで、call 先がズレた時に int3 が実行されるように cc1 をバイナリーエディターで改造してみた。
2808992,2808993c2808992,2808993 < 1042b26: 66 2e 0f 1f 84 00 00 nopw %cs:0x0(%rax,%rax,1) < 1042b2d: 00 00 00 --- > 1042b26: e9 ee 72 89 ff jmpq 8d9e19 > 1042b2b: e9 e5 00 00 00 jmpq 1042c15 2809013,2809018c2809013,2809020 < 1042b67: 0f 84 ac 72 89 ff je 8d9e19 < 1042b6d: c1 e8 06 shr $0x6,%eax < 1042b70: 39 c2 cmp %eax,%edx < 1042b72: 0f 47 d0 cmova %eax,%edx < 1042b75: 83 fa 01 cmp $0x1,%edx < 1042b78: 0f 85 97 00 00 00 jne 1042c15 --- > 1042b67: 74 bd je 1042b26 > 1042b69: c1 e8 06 shr $0x6,%eax > 1042b6c: 0f 1f 44 00 cc nopl -0x34(%rax,%rax,1) > 1042b71: 39 c2 cmp %eax,%edx > 1042b73: 0f 47 d0 cmova %eax,%edx > 1042b76: 83 fa 01 cmp $0x1,%edx > 1042b79: 75 b0 jne 1042b2b > 1042b7b: 0f 1f 00 nopl (%rax)
ちょうどルーチンの手前にある長い長い nop と、遠距離条件ジャンプがふたつもあったおかげで工夫がきいた。 長い nop のところに遠距離無条件ジャンプをふたつ入れ、遠距離条件ジャンプふたつを近距離条件ジャンプに変えることで 8 バイトを手に入れ、それを 5 バイトと 3 バイトの nop で消費、5 バイトの nop の最後に cc (int3) を仕込んでおいた。 これで通常動作は OK だが、1042b70 に飛び込めば int3 が実行される。int3 は segfault とは異なりシグナルハンドラーが登録されておらず、いきなり落ちるので都合が良い。 再現実験は cc1 の繰り返しで見事成功した。
Program terminated with signal SIGTRAP, Trace/breakpoint trap. (gdb) info reg rax 0x1 1 rbx 0x7f39d6851930 139886388910384 rcx 0x40 64 rdx 0x40 64 rsi 0x7f39d6851940 139886388910400 rdi 0x7ffc56f4d870 140721767372912 rbp 0x7ffc56f4d870 0x7ffc56f4d870 rsp 0x7ffc56f4d808 0x7ffc56f4d808 r8 0x0 0 r9 0x1 1 r10 0x40 64 r11 0x7f39d6b080a8 139886391754920 r12 0x0 0 r13 0x7f39d6b080a8 139886391754920 r14 0x11 17 r15 0x0 0 rip 0x1042b71 0x1042b71 eflags 0x202 [ IF ] cs 0x33 51 ss 0x2b 43 ds 0x0 0 es 0x0 0 fs 0x0 0 gs 0x0 0 (gdb) x/40xg $rsp-0x40 0x7ffc56f4d7c8: 0x00007ffc56f4d8a8 0x00007f39d5d32440 0x7ffc56f4d7d8: 0x00007f39d5ff1b40 0x0000000000000000 0x7ffc56f4d7e8: 0x0000000000000003 0x00007f39d6c7a540 0x7ffc56f4d7f8: 0x0000000001ee38d0 0x00007f39d6851930 0x7ffc56f4d808: 0x0000000000d858e0 0x0000000000000011 0x7ffc56f4d818: 0x0000000000000000 0x00007f3900000000 0x7ffc56f4d828: 0x0000000000000000 0x00007f39d5d0e000 0x7ffc56f4d838: 0x0000000000000000 0x0000000000000000 0x7ffc56f4d848: 0x0000000000000000 0x0000000000000000 0x7ffc56f4d858: 0x0000000000000001 0x00007f39d6c66e70 0x7ffc56f4d868: 0x00007f39d5d0e0a8 0x00000000000000d0 0x7ffc56f4d878: 0x0000000000000000 0x00007f39d5d0e0a8 0x7ffc56f4d888: 0x0000000000000001 0x000000000000001a 0x7ffc56f4d898: 0x0000000000da0bcd 0x000000000136874d 0x7ffc56f4d8a8: 0x00007f39d6b08bd0 0x000000000000001a 0x7ffc56f4d8b8: 0x00007f39d6b080a8 0x0000000000000000 0x7ffc56f4d8c8: 0x0000000000000000 0x0000000000000000 0x7ffc56f4d8d8: 0x000000ffffffffff 0xffffffff80000001 0x7ffc56f4d8e8: 0x00007f39d6851930 0x00007f39d5ff1b40 0x7ffc56f4d8f8: 0x0000000000000000 0x00007ffc56f4da00
たぶん、ズレは d858b9 のあたりだ。
d85873: 48 98 cltq d85875: 0f b6 53 04 movzbl 0x4(%rbx),%edx d85879: 44 0f b7 84 00 a0 a6 movzwl 0x12ca6a0(%rax,%rax,1),%r8d d85880: 2c 01 d85882: 48 8d 73 10 lea 0x10(%rbx),%rsi d85886: 48 8d 7c 24 60 lea 0x60(%rsp),%rdi d8588b: 41 0f b7 4b 34 movzwl 0x34(%r11),%ecx d85890: 44 89 44 24 7c mov %r8d,0x7c(%rsp) d85895: 81 e1 ff 03 00 00 and $0x3ff,%ecx d8589b: e8 90 d2 2b 00 callq 1042b30 d858a0: 8b 54 24 7c mov 0x7c(%rsp),%edx d858a4: 41 89 c2 mov %eax,%r10d d858a7: 89 44 24 78 mov %eax,0x78(%rsp) d858ab: 41 c1 e2 06 shl $0x6,%r10d d858af: 41 39 d2 cmp %edx,%r10d d858b2: 77 44 ja d858f8 d858b4: 48 8d 6c 24 60 lea 0x60(%rsp),%rbp d858b9: 48 8d bc 24 80 00 00 lea 0x80(%rsp),%rdi d858c0: 00
d858b9 が実行されたかどうかは定かでないが、call の後そこまでは正常に実行されていたとおぼしき内容は確認できる。 残念ながらズレた時の d85890 の実行で 0x7c(%rsp) は破壊されているので d858a0 の内容の検証はできないが、今回は int3 のおかげでそのときのレジスターの値は残っている。%r10 に 0x40 (1<<6) が入っていること、0x78(%rsp) (0x7ffc56f4d888) に 1 が入っていること、%r10d と %edx が等しいこと、%rbp に 0x60(%rsp) (0x7ffc56f4d870) のアドレスが入っていることから、d858b4 までは実行されたと考えて矛盾はない。 また、0x4(%rbx) には以下のように 1 が入っているため、ズレた時に d85875 は実行されなかったと考えるのが自然。
(gdb) x/bx $rbx+4 0x7f39d6851934: 0x01
d85879 の 0x12ca6a0(%rax,%rax,1) は以下の内容でレジスターと一致。
(gdb) x/hx 0x12ca6a0+$rax+$rax 0x12ca6a2 <mode_precision+2>: 0x0000
次の d85882 と d85886 もレジスターの内容が一致。その次の d8588b もメモリーの内容が一致。
(gdb) x/hx 0x34+$r11 0x7f39d6b080dc: 0x0040
d85890 による書き込み結果は上にある通り 0x7c(%rsp) (0x7ffc56f4d88c) には 0 が書き込まれているため一致しており、d85895 の and 結果もフラグレジスターの内容も一致するので、たぶん、d858b9 を実行しようとした時になぜか d85879 からの命令列を実行していたということで、これで 0x11 問題は説明できていると思う。
マルハニチロの株主総会。 今日は土産をもらいに行っただけ。 ここは株主総会のおみやげもちょっと豪華。 鯖水煮缶詰と鮭フレークとゼリーと DHA 何とか、都心の人なら交通費分くらいはあるし、9 時ちょっと過ぎの時点でもう土産持って歩いている人を見たので、近辺に勤めている人なら、朝イチに寄って土産もらってから出勤なんて人もいるかも。
続いて FFRI の株主総会。 初。 来ている株主はそんなに多くはない印象。 報告はシンプル、ナレーションがちゃんと入ってると思ったが、招集ご通知の内容をスライドに貼ってナレーションはそれを読み上げているだけだったw 海外展開始めますよー、ってのが新たなポイントなのか。 まずは北米から。 個人向けは特に Android 等向けは販促費がかかるとのことで、見直していくつもりのよう。 昨今のランサムウェアの被害増大に伴い需要は増えているもよう。 あんまり質問も出ないので、平均勤続年数 2.1 年ってどうなんですかと聞いてみたら、2014 年頃から新卒採用や中途採用をしてきた人数が結構あるらしくて、それで短くなってますーとのことだった。
FFRI は株主総会後に休憩を挟み、代表と取締役もう 1 人が出てきて、今後の展望についての説明があった。 海外向けを伸ばしていきたいもくろみらしい。 まぁあの主力製品をメンテし続けていられるなら技術力的にはそんなに心配はないだろうと思う。 こういう製品があるんだ、とユーザーに認知してもらうところのハードルは確かにあるよなぁ。
朝 6 時台に目覚めてしまったので、テキトーに移動を開始。 すでに雨は降りだしていた。 バスで三鷹まで出て、各駅停車の始発を狙う作戦。 バスは混んでいた。7 時台はこんなに込むものなのか。 府中からなので余裕で座っていたのだけど、前の一人席にいたら、混雑してきて横に立っていた女子高生がだんだん近寄ってきて... 途中からもうバス停スキップしてたな、なんかアナウンスしてたからたぶん後続のバスに乗ってくれということなんだろう。 バス専用レーンのあるところはすいすいだ。 まぁこのあたりはバスの本数が多いから、バス専用レーンの渋滞回避効果は高いだろう。 原付で通ったことはあるが、バスからその景色を見るのは初めてだった。
三鷹の整列乗車はやっぱり意味わかんない。 何がなんだか。 都営三田線の停車駅を調べた結果、地下鉄東西線直通で、大手町まで出ることにした。 これもまぁ席は埋まる程度には混雑するが、ぎゅうぎゅうにはならない。 九段下あたりで降りる人と乗る人が多く、大手町は案外誰も降りなくて人をかき分けることになってしまったが...
やっぱり大手町で見る通勤客の皆さんの足音は怖い。 ざっざっざっ、と、どこぞの軍隊か。 まぁでも端っこをゆっくり歩く分にはみんなスルーだ。 途中で迷ってきょろきょろしてるとちょっと邪魔っぽいけど、こんなところたまにしか来ないから仕方ないだろ!
時間が早かったので三田線の改札前にあったドトールで朝食を取った。 ドトールの中の仕組みも知らなかったよ。 朝は席取りは決済後。 水はセルフサービス。 意外と新聞なんか読んでのんびりしている人は多いように見えた。 んで三田線がまた意外と混雑しているような... 芝公園まで行ってメルパルクホール。
そこから今度は浜松町に出てみることにした。 そしたら山手線遅れてた。 京浜東北線に乗ったが田町で乗り換えるべきだった。 そしたら目の前だったし空いていたはず。 品川まで行ったら階段登っての乗り換えになった上、山手線ホームが遅れの影響で人だらけ。 田町だったらうまくいけば座れていたと思う。 まーそんなこんなで割とぎゅうぎゅうで恵比寿行った。 恵比寿で何度か靴が滑って危なかった。
帰りは渋谷経由で明大前でカレーを食って帰った。
レイドバトルだかなんだかそういうのができて、ジムがずいぶん変わったのだが、コマ落ちがひどくてなんだかよくわからず、一度バトルをしようとしたら、カウントダウンが出てきて、始まるぞというところで「ネットワークエラー」。 うーん。 それで、ジムにポケモンをおくというのは一応できて、以前のようにボーナスをもらおうとショップを開いたら、ない。 ボーナスのシステム変わったのか。 帰ってきた後で確認したら増えていた。
ポケストップがジムに化けたところがけっこうあって、アイテムもらえないのかと思えばそうでもなくて、一応ジムでもアイテムをもらえるようになっている。 今までジムだったところもアイテムをもらえるのでむしろアイテムをもらえるところが増えたとも言える。 しかし、ポケモン GO Plus がジムからアイテムを拾ってくれるわけではなさそうだ。 三鷹駅だと南口の通りの商店街にあるたくさんのポケストップは割とそのままで、駅前のケヤキだっけ、主にバス・タクシーのロータリーみたいになっているところがひとつジムになった。 多磨駅でも近くの体育館だったかな、そこがジムに化けた。 人見街道の、新撰組の何とかかんとか、近藤神社だっけ、そこも。 他にもいくつか。
cc1 のシグナルハンドラーが正常に機能すると core dump が出てこないので、何とかならないか、と考えていたが、ふと簡単な方法を思いついた。 この前、シグナルハンドラーから internal error が呼ばれている、というのがわかったとき、シグナルハンドラーのアドレスもわかってしまったのだ。 そこに int3 を仕込めば、core dump が出る。 しかも、struct sigcontext が残るので、ページフォールトの詳細などもわかる。 画期的!
632318c632318 < 7d6572: 53 push %rbx --- > 7d6572: cc int3
後はたくさん試行してたくさんの core dump をゲットすれば楽しみが増える。 なお、Debian GNU/Linux 9 のカーネルパッケージのアップデートに伴い、若干挙動が変わったようだが、前と同じ segfault も出ることは出るみたいなので、一晩実行して収集してみよう。
テレビでやってた映画『藁の楯』。2013 年の邦画。 約 2 年ぶり。 相変わらず読めない。
最初のほうはあまり記憶に残っていなかったが、移送を始めたところから記憶がよみがえってきた。 ただし詳細は覚えておらず、何か起こるたびに、ああそうだった、の繰り返し。 藤原竜也の狂った犯人の演技、大沢たかおのガチ SP っぽい演技などが見所だなぁ。 なお、拳銃を撃つシーンはいまいち迫力に欠ける。 反動がわざとらしいというか。
いくつか取れたが、試しにそのうちのひとつを調べ始めたらこれがよくわからない。 なぜか %rip=0 になっているので、当然、スタックを見て、戻り番地らしきものがあって、そこにはメモリーからジャンプ先アドレスを取得する call 命令があり、確かにそこから来てしまったもののよう。 さらにさかのぼって見ていったのだが、不審な点が見当たらない...
なお、こないだの int3 ハックを残してあるので、いくつかはその番地でクラッシュしている。 それらは全く同じパターンと見て良いだろう。 あと、クラッシュせずに internal error が出てしまうケースも発生した。
0x40 バイトズレ問題で気になるのは、ズレた時点ではきれいに命令境界にまたがることなくズレている点で、その後の call 等で変なアドレスに飛んでしまうことはあっても、ズレた瞬間に変な命令を実行しているケースはまだ確認できていない。 もしかしたら、変な位置にズレたら Machine Check Exception が出るのかな、なんて想像はしている。 それを検証するには、同じファイルのビルド繰り返しで同じトラブルが発生するパターンを使って、cc1 の一部のバイナリーを書き換えてわざと該当部分の命令をわずかに変えればいいのかな? うまくいくかどうかはわからないが。
Powered by Tomsoft Diary System 1.7.4
Hideki EIRAKU