2014年4月23日水曜日

アナと雪の女王とgentoo

アナと雪の女王を見てきました


gentooの次にディズニー映画が好きな僕ですが、最近、よく映画を見るようになったのですが、どれもつまらない映画ばかりで損した気分になるところを、やはりこの映画は問題なく面白かったです。

ミュージカル的なノリで最後まで飽きずに見る事ができました。
松たかこの歌がいいですねぇ、すごい歌唱力だなと感心しました。



私もカラオケで歌えるように練習しようと思っています。

やはりディズニー映画はワールドを感じますね、子供も大人も楽しめる映画を作れるというのはそう簡単にできる事ではありませんよね。

で、gentooとどこが関係あるのって言われそうですが、ただいいたいだけです。

でも、是非みにいってみてください。

すこしも寒くはないわ/gentoo

...



2014年4月20日日曜日

消費税8%問題とceil関数の罠

1円が合わないのはなぜ? 


最近、消費税が8%に上がり、お買い物が楽しくなった今日この頃。チョット気になる問題が僕を襲いました。なんとceil関数の罠にドップリはまり、2、3日、酒浸りになりました。

ことの発端が、この計算
<?php
$v = ceil(15000 * 1.08);
print($v . "\n");
?>
cuomo@localhost ~ $ php sample.php 
16201
ちょ、まて、俺が望んでるのは、16200だぞ!

これに気づきませんでした...

「1円!違ってるけどどうなってんのっ!、いっぱい1円違うじゃないのぉーーー (怒)」

言われるはずです、早速直して対応したのですが、なんで?って思いますよね...
調べましょう、Gentooで......


そもそもの間違い


ceilのせいでは....ないんですよ、ceilはドキュメントに書いてあるとおりに動作しています、手で計算した結果を鵜呑みにして、さらに和をかけて思いこみの沙汰が酷過ぎ、単なる浅はかさがこの事態を生んだ模様です 笑...。

調査開始


まずPHPのceil関数をしらべてみたら、ext/standard/math.cでceil関数を呼んでいる、ceil関数はgentooですとglibcパッケージ(libm)に入っていますので、そちらを確認してみましょう。

<pre>
PHP_FUNCTION(ceil)
{
    zval **value;

    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z", &value) == FAILURE) {
        return;
    }
    convert_scalar_to_number_ex(value);

    if (Z_TYPE_PP(value) == IS_DOUBLE) {
        RETURN_DOUBLE(ceil(Z_DVAL_PP(value))); /* ceil関数を呼び出し */
    } else if (Z_TYPE_PP(value) == IS_LONG) {
        convert_to_double_ex(value);
        RETURN_DOUBLE(Z_DVAL_PP(value));
    }
    RETURN_FALSE;
}
</pre>


ですね、これを元にceilを利用したサンプル関数を作ってみる

実際はどんなことしてるんだ


glibcのコードをソースコードレベルで解析したいので、面倒ですがglibcをdebug版でコンパイルしなおす。まぁ、emergeするだけなので楽勝ですが、出きるまでビールでも呑んでましょう。
サンプルコードとgdbを利用して、libmのceil関数へブレークポイントを仕掛けて、実行してみる。


#include <stdio.h>
#include <math.h>

double subceil(int);

int main(void)
{
  double v;
  v = subceil(15000);
  printf("%f\n", v);
  return 0;
}

double subceil(int v)
{
  return ceil(v * 1.08);
}
cuomo@localhost ~ $  gcc -g ceil.c -L/usr/lib64/debug/lib64 -lm -lc -O0 -o c.out
これを、gdbで止めてみると../sysdeps/x86_64/fpu/multiarch/s_ceil.S:37で停止するのですがSSE4のroundsd命令で 一撃でやられちゃってよくわからないので(自分がSSEをよくわかってない...笑)、正確ではないのですが違う関数ceillで再度確認。
Breakpoint 1, __ceil_sse41 () at ../sysdeps/x86_64/fpu/multiarch/s_ceil.S:37
37              roundsd $2, %xmm0, %xmm0
(gdb) l
32      END(__ceil)
33      weak_alias (__ceil, ceil)
34
35
36      ENTRY(__ceil_sse41)
37              roundsd $2, %xmm0, %xmm0 /* xmm0レジスタ一撃ですわ */
38              ret
39      END(__ceil_sse41)

自分的にわかりにくかったので、ceillでもう一度
#include <stdio.h>
#include <math.h>

double subceil(int);

int main(void)
{
  double v;
  v = subceil(15000);
  printf("%f\n", v);
  return 0;
}

double subceil(int v)
{
  return ceill(v * 1.08); /* ceil()をceill()に修正 */
}

もう一度、ビルドし直し、gdbでブレークしてみる

cuomo@localhost ~/Code/binaries/CProgs/ceil $ gdb ./c.out
GNU gdb (Gentoo 7.6.2 p1) 7.6.2
Copyright (C) 2013 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-pc-linux-gnu".
For bug reporting instructions, please see:
<http://bugs.gentoo.org/>...
Reading symbols from /home/cuomo/Code/binaries/CProgs/ceil/c.out...done.
(gdb) b ceill
Breakpoint 1 at 0x400520
(gdb) r
Starting program: /home/cuomo/Code/binaries/CProgs/ceil/./c.out
warning: no loadable sections found in added symbol-file system-supplied DSO at 0x7ffff7ffa000
warning: Could not load shared library symbols for linux-vdso.so.1.
Do you need "set solib-search-path" or "set sysroot"?

Breakpoint 1, ceill () at ../sysdeps/x86_64/fpu/s_ceill.S:12
7
8       #include <machine/asm.h>
9
10
11      ENTRY(__ceill)
12              fldt    8(%rsp)                 /*Floating Point Load */ 
13
14              fstcw   -4(%rsp)                /* store fpu control word */
15
16              /* We use here %edx although only the low 1 bits are defined.
17                 But none of the operations should care and they are faster
18                 than the 16 bit operations.  */
19              movl    $0x0800,%edx            /* コントロールレジスタのRCフィールドを切り上げにセット */
20              orl     -4(%rsp),%edx
21              andl    $0xfbff,%edx
22              movl    %edx,-8(%rsp)
23              fldcw   -8(%rsp)                /* コントロールレジスタを設定 */
24
25              frndint                         /* 切上処理の実行 */
26
27              fldcw   -4(%rsp)                /* コントロールレジスタを元に戻す */
28
29              ret
30      END (__ceill)
31      weak_alias (__ceill, ceill)
(gdb)
多分こちらはx87の浮動小数点計算処理でSSE命令より余計な部分が多いのですが、何をやっているのかわかりやすいのでこちらで確認。 x87の細かい使い方は専門の方へお願いするとして、数バイトstep実行させた後のST(0)の値、ここへ15000*1.08の計算結果が格納されている。この時点でお分かりですよね、そう小数点の部分が0ではないのです、これをfrndintでやってしまえばそれはそうなりますよって話 笑...
(gdb) info all-reg
...
st0            16200.000000000001818989403545856476 (raw 0x400cfd20000000000800)
...

ここからはつまらない話


x86拡張倍精度で80bitの形式で保存されていて、16進数で0x400cfd20000000000800という値を保存している、で、さらにこれを2進数80bitで表現すると...
0 100000000001100 1 111110100100000000000000000000000000000000000000000100000000000


  • 符号部(s) 0(1bit)
  • 指数部(e) 100000000001100(15bit バイアス値 16383)
  • 整数部(p) 1(1bit)
  • 仮数部(f)  111110100100000000000000000000000000000000000000000100000000000(64bit)
でわけられ、下の式で計算される
(-1)^s * 2^(e-16383) * p.f
※fは2進数を小数に変換したもの
これに習って計算してみると
8192 * 1.9775390625 ~= 16200.00000000000181... ※1.9775390625 ~= 1 + (1/2 + 1/4 + 1/8 + 1/16 + 1/32 + 1/128 + 1/1024 + 1/4503599627370496) こういうことに内部的になっているため、frndintを実行した場合に1を加えた数値になります。
実際の計算を終えた後の、浮動小数点レジスタの値はこの様な感じになってました。
st(0)の値がしっかり16201になってますね。
(gdb) info all-reg
...
...
es             0x0      0
fs             0x0      0
gs             0x0      0
st0            16201    (raw 0x400cfd24000000000000)
st1            0        (raw 0x00000000000000000000)
st2            0        (raw 0x00000000000000000000)
st3            0        (raw 0x00000000000000000000)
st4            0        (raw 0x00000000000000000000)
st5            0        (raw 0x00000000000000000000)
st6            0        (raw 0x00000000000000000000)
st7            0        (raw 0x00000000000000000000)
fctrl          0xb7f    2943
fstat          0x3a20   14880
ftag           0x3fff   16383
fiseg          0x7fff   32767
fioff          0xf7b5b610       -139086320
...
...

まとめると


通常の計算結果で端数が出ない浮動小数点の計算でも、機械の内部ではぴったり収まらないケースがあるということ。小数点は意外とムズカシイ... なので、解決方法として
  • 仕様としてなるべく切捨てを採用するよう上司に涙ながらに訴える
  • ceil(round($v, x))で小数点以下のどこで切り上げるか明確にする
  • 切上げの場合は、安易に掛け算とceilを利用しないで、足し算、引き算などで頑張る(やり方は分かりません)
  • Haskellのような分数と遅延評価を使える言語で頑張る(みんなにいやがられる)

ちなみにHaskell
Prelude> 15000 + (15000 * 8/100 :: Rational)
16200 % 1

みなさんceil関数をこんな感じで使ってる所ってない?..なんか気持ち悪いですね....ヒヤリハットです

最後に、消費税をもう今後上げない...無理でしょうけど

2014年4月14日月曜日

weakシンボルに時間をとられた

waekシンボル

ceil関数からを調べていたら
cuomo@karky7 ~ $ nm -D /lib64/libm-2.17.so | grep ceil
000000000001a810 i ceil
0000000000030220 i ceilf
0000000000039a70 W ceill
cuomo@karky7 ~ $
ceil関数を調べていてnmコマンドのWをみて、「これ何だっけ?」と半分忘れかかっていたので脱線...
weakシンボルとは書き換え可能な変数、または関数名(関数のエントリアドレス)で、同名称が非weakシンボルで名前解決される場合はそちらが利用される位しか覚えていませんがあってるかどうかわからない。 でこんな感じ、
int main ()
{
  test();
  return 0;
}
#include 
#include 
extern long double ceill(long double x) __attribute__ ((weak));

void test(void)
{
  if (ceill) {
    printf("%Lf\n", ceill(15000 * 1.08));
  } else {
    printf("ceillなんて実装してねぇし\n");
  }
}

ビルド方法


ceil.so共有ライブラリを作成し、それをmain.cへリンクさせる
cuomo@karky7 ~ $ gcc -fPIC -shared -o ceil.so ceil.c
cuomo@karky7 ~ $ gcc main.c ./ceil.so
これを普通に実行してみると
cuomo@karky7 ~ $ ./a.out
ceillなんて実装してねぇし
cuomo@karky7 ~ $
これはceill関数にリンクできていないから呼び出ない、これをこうすると
cuomo@karky7 ~ $ LD_PRELOAD=/lib64/libm.so.6 ./a.out
16201.000000
cuomo@karky7 ~ $
LD_PRELOADでlibmをしてするとちゃんとceillがリンクされて実行できる。

まとめると


GCC GNU拡張のアトリビュート__attribute__でweekを使うと、リンク時に-lmを指定しなくてもリンクできるようになる。
extern long double ceill(long double x) __attribute__ ((weak));
もしこれを書かないと、-lmで明示的にリンクが必要になる
cuomo@karky7 ~ $ gcc -fPIC -shared -lm -o ceil.so ceil.c
さらに、実行時に名前解決できない場合、そのシンボルが0で初期化されて、コード(a.out)自体は実行が可能になる、そうじゃないと実行時のリンクエラーで、コード(a.out)の実行ができない。 という、よくわからない説明ですが、そういう風になっていると思います。

2014年4月9日水曜日

gitでsshの公開鍵認証でハマる

公開鍵認証でSSH越しのgit cloneにハマる


意外とやってみてチョットハマったのでメモ、SSHの鍵認証を利用した時のgitでcloneしようと試したのですが、色々試したものの以下のメッセージがでてcloneできない


まず、普通の鍵認証でsshしリモートのサーバーへログインできることが前提です
cuomo@karky7 ~ $ ssh -i ~/.ssh/identkey user@123.456.789.999
Enter passphrase for key '/home/localuser/.ssh/prikey':
user@host ~ $

「Permission denied (publickey).」公開鍵が違うじゃねぇーか的なメッセージでてcloneできない
cuomo@karky7 ~ $ git clone ssh://user@123.456.789.999/home/user/mou_muridesu.git
Cloning into 'mou_muridesu'...
Permission denied (publickey).
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.
cuomo@karky7 ~ $

ssh越しにgitが出きるように設定する


どうやらgitでsshを利用する際に特定の秘密鍵をしてする方法があるらしく.sshディレクトリ以下のconfigファイルをおくというもの
cuomo@karky7 ~ $ pwd
/home/user
cuomo@karky7 ~ $ cat .ssh/config
Host remotehost
    HostName  123.456.789.999
    Port      22
    User      user
    IdentityFile  ~/.ssh/prikey
cuomo@karky7 ~ $
ここで注意することは、ファイルとディレクトリのパーミッション

  • .ssh ・・・ 0700
  • config ・・・ 0600

にしておいてください、Hostはエイリアスなので自分のわかりやすい接続名をつけてください、あとはわかりますよね。

git cloneしてみる


設定ファイルを置いたらcloneしてみる、ここでホストの部分はエイリアス名を指定する。
cuomo@karky7 ~ $ git clone ssh://remotehost/home/user/mou_muridesu.git
Cloning into 'mou_muridesu'...
Enter passphrase for key '/home/user/.ssh/identkey':
remote: Counting objects: 294, done.
remote: Compressing objects: 100% (224/224), done.
remote: Total 294 (delta 121), reused 160 (delta 59)
Receiving objects: 100% (294/294), 3.02 MiB | 584.00 KiB/s, done.
Resolving deltas: 100% (121/121), done.
Checking connectivity... done
cuomo@karky7 ~ $
cloneできました、configファイルを置くとその他のssh接続に影響がある場合がございますのでご注意ください、その他、環境変数 GIT_SSHなるものがありますが調べておりません。

案外面倒...

2014年4月8日火曜日

Gentoo勉強会に行ってきました - 2014年4月5日(土)

はじめてGentoo関係の勉強会に参加しました

2014年4月5日の土曜日に、芝エクセージビルディング5階のミラクルリナックスの会場にてGentoo勉強会が開かれるとのことで楽しみにしていました。

第1土曜日は Gentoo bug day という設定になっているというコンセプトのもと定期的に開催していくとのことで、まったく知りませんでした、今後も参加していきたいと思います。




発表内容

@matsuu さんの発表

Gentoo界隈では知らない人はいないと思いますが @matsuu さんの発表は、「Gentooプリインストールなノートパソコンの話」ということで、最近ハワイに行って買ってきたChromebookをネタにした発表で、ChromebookがGentooベースでできていて、emergeがうてるというおもしろい発表でした。

まず、
  • Chromebookはsamsungがいいらしい
  • ChromebookはGentooベース
  • Developer modeからubuntuを入れられる
など、おもしろい情報でした、developer modeにするにはchromeウエブストアからcrosh windowをインストールし、何やらコンソールからshellと入力すると、いつものGentooカラーのターミナルが起動し、emergeコマンドが実行できパッケージが入れられるようになります。チョットビックリでしたね、しかし、注意が必要でemerge出きるのはgoogle提供のバイナリパッケージだけらしいです。
自分は、Chromebookを持っていないので実際に試せないのですが、持っている方は是非お試しください。





@naota さんの発表

Gentoo developerで有名な @naota さんの発表で、あのみんなが利用するGenTwooシステムの gentooinstallbattle の生い立ちなどの発表でした。GenTwooとはemergeしたユーザーのパッケージ情報をtwitterに自動的に流すという斬新なソーシャルコンパイルシステムです。このビックデータを解析すれば、今後のパッケージのトレンドなんかを評価できたりと、非常に多方面に渡って期待できるシステムです。

皆さんもGentooをいれて、GenTwooを一緒にやりましょう。

GenTwoo: Social Compiling はこちらです


@aliceinwire さんの発表


Gentooのパッケージングシステムebuildとoverlayについてのお話でした。各コマンドのお話や外部リポジトリを簡単に取り込むことができるoverlayのlaymanなどの使い方のお話など、自分自身もSLOTについて質問させて頂いたりと、有益な情報を頂きました。僕も意外と知らなかったのですが、enalyzeコマンドなるものがありまして、こんな感じで実行しますと指定されたUSEフラグを使用しているパッケージリストが取得できます、USEフラグからパッケージを検索できます、これは便利で知りませんでした


karky7 ~ # enalyze analyze -v use
 Flag                                 System  #pkgs   cat/pkg-ver
+24bpp .............................. .......     1 net-libs/libvncserver-0.9.9-r1
+X .................................. default    80 app-editors/emacs-24.3-r2
                                                    app-editors/xemacs-21.4.22-r2
                                                    app-i18n/ibus-1.5.2
...
...
                                                    www-client/links-2.8-r1
                                                    x11-libs/libpciaccess-0.13.2
-zlib ............................... .......     1 sys-apps/pciutils-3.2.0
===================================================
Total number of flags in report = 455
Total number of installed ebuilds = 1918

karky7 ~ #
意外と使ってるけど知らない部分があったりと発見が多かった気がします、Gentooは奥が深いデスですね、さらにお勉強になりました。


最後に


最後に--mooです

karky7 ~ # emerge --moo
これは、是非インストールして自分で確かめてみてください 笑...


2014年4月7日月曜日

中伊豆の野球チーム、伊豆市リトルシニアに入団しました

入団式に行ってきました


山も綺麗に色づき、清々しい青空のもと、息子が中伊豆の野球チーム、伊豆市リトルシニアに入団することが決定し入団式に行って参りました。今回は10期生として29名の新中学1年生が入団します。



入団に当たっての説明や、書類の提出など色々忙しい1日でした。子供たちはもうみんなうち解けたようで、既にワイワイとやっていますが、親御さんたちは、ほぼはじめての対面で、若干緊張していたような気がします 笑...

子供が新しい環境に入るように、親も新環境に無理やり入れられるような感じで、あまりいい気分ではありません。そう思っているのは、多分、自分だけではないでしょう。(俺だけか?)
それでも、やりだせば楽しいこともあろうかと頑張っていきたいと思う次第です。

まぁ、2年半位ですけどあっという間に過ぎ去って行くのでしょうかね、それから、監督をはじめ関係者の皆さん、父母会など色々お世話になりますが、親子共々よろしくお願いします。

本日は新1年生入団おめでとうございました、先輩にシゴかれてください。



----

2014年4月6日日曜日

柿田川のBBQの思いでと清水のモツカレー

柿田川でBBQやって頂きました

会社のお休みに清水町の柿田川という公園で行いました。天気もよく素晴らしい陽気に恵まれて、皆さん相当お酒が美味しかったと思われます。何時ものことですが酔っ払いが多数見受けられました。写真などでたまに観光ガイドなどで見かけますが、やはり実際に見てみるとあまりの綺麗さに圧倒されます、やはり自然はすごいのですね。



桜も綺麗に咲いていました


こんな綺麗な桜を見ながら、酒を頂けるとは....叶いませんっ!

今日は、Gentoo勉強会!ではありませんかっ!

そうです今日は午後から、芝エクセージビルディングのミラクルLinuxさんで勉強会があるのを忘れてました、なので飲めません(若干飲んでしまいしたが...)

飲みはみんなに任せてお昼で撤退です、では行って参ります。
それから、準備をしてくれた皆さん、段取りしてくれたりと有難うございました。

清水のモツカレー旨かったです、今度みんなで食いに行きましょう。


柿田川公園


より大きな地図で 柿田川公園 を表示

2014年4月5日土曜日

中学入学おめでとう

息子の入学式に行ってきました


桜も舞っている2014年4月4日の晴天に、息子の入学で、20何年ぶりに自分の母校ではありますが、静岡県伊東市立対島中学校へ久しぶりに行ってきました。いけば色々同年代の親御さんがいっぱいいたり、もちろん同級なんか結構顔を合わせたりと、入学式よりそちらの始末の方が大変な1日でした。みなさんの子供も大変大きくなりまして、保育園で一緒だった子が中学で一緒のクラスになったりと大変狭い世の中だと痛感しました。それでも狭い分良く出きるような気がします。
みんな、これから、弁当だの、部活なの、勉強とか大変忙しいくなると思いますが、頑張っていきましょう。

それから桜もきれでした



しかし、2,3年生に比べて、1年は制服が似合わないですね、私はボンタン(既に死語ですか?)を先生にとられた記憶しか残ってませんが...


みんなおめでとう