新千葉 ガーベージ・コレクション

FPGA マガジンやインターフェースで書けなかったこと等をちょぼちょぼ書いてます。@ryos36

Min Caml コンパイラ その2

速攻MinCamlコンパイラ概説 をみればいいだけだったりして。ML の解説まで書いてある。
あと OCaml の参考書としては「プログラミング in OCaml」という本を読んでいる。Kindle版はあるが、紙の本の方は絶版だ。いい本だけに残念。

MinCamlはMLのサブセットです」とある。まず ML がわからないとダメ。ここで躓く。e::= の式も躓く。とりあえず自分の理解を書いておこう。

let が OCaml と違う。

let x = e1 in e2

となっている。OCaml では大域変数として

let pi = 3.14159

とかできるが、どうも Min Caml はできないらしい。上の文法を見るとそう書いてあるから、そうなのだが、ここで躓く。ML では let ... in ... しかないようにも見えるので(よく知らない)、Min Caml という名前から OCaml に誘導されそうになるが、「MinCamlはMLのサブセットです」ということらしい。

関数の定義が独自(?)

関数の定義にわざわざ「再帰関数定義」と銘打っているので、再帰じゃない関数があるのかと?勘違いするが、どうも、すべての関数(プリミティブを除くと)は「再帰関数定義」らしい。そして、

let rec f a0 a1 a2 = e1 in e2

となっていて、rec という特別なキーワードが出てくる。このキーワードは ML にも OCaml にもないように思う(自信なし)。(hatena のキーワードでハイライトされてしまった。OCaml に let rec が let とは別にあった)。ということで、関数の定義は let rec で、それは常に再帰関数定義となる。再帰関数定義の意味がよくわからないが、上の e1 でも使えるということなのだろうか?

最初に理解しなくて張らならないのは Min Caml の文法

OCaml の文法とは Min Caml は違うので、まず Min Caml 自身の文法を「CCaml とは違う」ということを念頭に理解しなくてはならないと思う。コンパイラを作るうえで OCaml の理解は必要だけど、極端な話、この時点では OCaml しらなくてよい。Min Caml を理解するのが先。そして、どこが OCaml と違うのかを理解する。というのが感想。とくに OCaml や ML 知らない人(私だよ)は特にそうだと思う。

Min Caml を使う

  • まず、 git clone する。
  • to_x86 というシェルプロを走らせる。(ほかに to_ppc, to_sparc なんてのがある)
  • make する。min-caml ができる。 (min-rt は興味のある人だけ make すればよい。直接コンパイラに関係ないから)
  • test をみて Min Caml の雰囲気を知る
  • 自分の環境で Min Caml のソースを作る(あるいは test からコピーする)
  • Min Caml でコンパイル
min-caml adder
adder: adder.s libmincaml.S stub.o
        gcc -m32 -g -O2 -Wall $^ -lm -o adder

こんな感じで理解を深めていけばよい。

*. はあるけど * はない?

OCaml で躓くのが整数と小数点ありの数。これ ML では別々の世界を持っていると考えるみたいね。なので、掛け算も小数点の場合は *. で、整数の場合は * 。
ただし、Min Caml で * はサポートされていないっぽい。*. はある。

let pi = 3.14159 in
    let rec f r = r *. r *. pi in
        print_int (int_of_float (f 789.0));
print_newline()

Kiss4 の環境作り

f:id:ryos36:20161008233416j:plain
Kiss4 という Zynq のボードのために、環境作り。Yocto で環境を作っている。krogoth という branch を使用。

  • poky
  • meta-xilinx
  • meta-openembedded

と zybo からぱくった

  • meta-kiss4

まちがえて meta-openembedded の branch を master にしたら、

python-dbus fails configure with "could not find Python headers"

というエラーが出て止まってしまった。branch をちゃんと krogoth に合わせたらうまくいった。
yocto に bug として出ていたのでバグかと思ってしまった。単純ミスだった。
https://bugzilla.yoctoproject.org/show_bug.cgi?id=2072

Pynq に大きく水をあけられてしまったので、こつこつ環境を構築して、追いつきたいと思う。

Mini Caml コンパイラ その1

github.com

ここにある pdf をみながら、社内でコンパイラ(型推論)の勉強会を開く。
http://esumii.github.io/min-caml/jpaper.pdf
いま、見たら tutorial-minicaml.doc なんてのがあった。

最初から躓くよね。「単相性」ってなによ。K くんの指摘で「多相型がないこと」の意味をちょっと理解する。template のように型をいくつも取れるのが多相型という理解をした。よんでいくと、決定できないときは int と推論するとある。そういうことか。

サンクとクロージャの違いが明確にわからん。とか、(クロージャは遅延評価とは関係ないのか、、、)正格性とか線形性とか、、、軽く読み飛ばす(深い理解もなく先に行く)。最初の週は OCamlLex と OCamlYacc をある程度理解すればいいと。MinCaml の抽象構文と型ってのが、そもそも Ocaml を理解してないとダメだ。数か月前に読んだんだけど、、、fix record の問題も軽く読み飛ばし。非カリー化、、う~む。先にいこう!!

ということで、3.1 に字句・構文解析にたどり着く。そして、3. 型推論を経て、K正規化で時間切れ。

まずはちゃんと OCaml を思い出して、構文を理解しないとね。そして、K正規化に突入していかないといけない。だれかがそういえば、Scheme で書いていたような。

Docker + WordPress 試してみた

Docker を試してみた。FreeBSD の jail みたいなものと理解している。というより、技術的なものは一切理解せずに使っている。

Docker のインストール

qiita.com
この辺のを見てインストールした。単に Docker からシェルプロを wget して(記事の中では curl だが)、sudo で実行しただけ。もう、勝手に何かしらインストールされてしまいました。何がインストールされたかはわからずじまいです。

$ wget -qO- https://get.docker.com/ | sh
$ sudo usermod -aG docker $USER

Docker を run させる。

よくわからないけど、まずは hello world を run させました。この時点で、何が起こっているのかわからない!!という状態です。つまり、 Docker (仮想環境というくらいは知っているが、基本的な知識としてはこのキーワードだけ)が何者かわからないうちに hello world 終了

$ docker run hello-world

ubuntu を起動させる

なんか ubuntu も起動させることが出来るらしいぞ、ということで ubuntu も起動。

$ docker run -i -t ubuntu /bin/bash

この時点でどうやら、どっかにイメージを作っているらしいことに気が付く。df でみてみると、確かにマウントしている。つまり、Docker は誰かが作った image を mount して Jail みたいにプロセスに割り当てて起動する技術らしい(今も詳細がわかっていないので、あくまで、らしいってことで)
一旦抜けても後から bash を起動できる

$ docker exec -it ubuntu /bin/bash

目的の WordPress を起動

tutum/wordpress というのを使ってみた。もう簡単。

$ docker run -d -p 8080:80 --name=wordpress tutum/wordpress

これで 8080 を 80 へフォワードする。後で調べると、じつはこのコンテナのなかで Linux + Apache + MySQL + PHP (いわゆる LAMP) が動いていることが分かった。調子に乗って、いくつも wordpress 入りのコンテナを作る。イメージがどこにあるのかしらないが、イメージなら、スナップショットが取れるのでは?と調べると commit というコマンドで取れることが分かった。

$ docker stop wordpress
$ docker commit wordpress wordpress-snap0

tutum/wordpresswordpress の旧バージョンが入っている。しかし、パーミッションの設定が悪く、WordPress 内部からアップデートできない。

$ cd /var/www/html
$ chown -R www-data:www-data .

てなぐあいにしてやると、うまくいく。あと、ついでに sendmail (WordPress が必要とする) がなかったので、apt-get でいれる。apt-get が古かったようなので update もする。

$ apt-get update
$ apt-get install postfix
$ service postfix start
$ service postfix stop

最初 sendmail を入れたら重かったので、postfix に変更。postfix の設定はしていない。(メールの送信だけだから)。service を stop していて大丈夫のはずだが、、、、stop しても ps でみるとデーモンが動いている。もう、目的主義で、その辺は気にしないことにする。

WordPress の設定

ここから混沌の道に入る。WordPress は簡単な言葉を使っているせいで、いままで Linux のサーバを使っていた人はかえってわからない。そして、うまく apache の裏に隠れてくれない(Proxyね)。

  • WordPress アドレス
  • サイトアドレス

この用語がわからない。どうやら、複数のコンテキストを管理できるように、WordPress の一般的な cgi とコンテンツ向けの cgi に分かれているようだ。生成される HTML のソースを見るとそう見える。なので、WordPress アドレスはコンテンツに関連なく共通の cgi のための URL。サイトアドレスはコンテンツのための URL。
結局どちらも、普通に同じ URL を設定し、おおもとの Apache で Proxy で転送。

ProxyPass / http://localhost:8080/

かな?ProxyPassReverse は WordPress が勝手にやってくれるから設定しない。WordPress 側は、もともとは http://192.168.0.XXX:8080 みたいになているはずなので、これを http://www.example.com のように(WordPress アドレスもサイトアドレスも)変更。
そしておまじないの

$_SERVER['HTTP_HOST'] = $_SERVER['HTTP_X_FORWARDED_HOST'];
$_SERVER['REMOTE_ADDR'] = $_SERVER['HTTP_X_FORWARDED_FOR'];

を wp-config.php に追加。追加するときは

require_once(ABSPATH . 'wp-settings.php');

より前にする必要があるらしい。WordPress 的には次のコメントの前に書くということになっている。

/* That's all, stop editing! Happy blogging. */

SSL

これはちょっとややこしい。が、結局、次のを wp-config.php に足しこむので OK だった。

define('FORCE_SSL_ADMIN', true);
$_SERVER['HTTPS']='on';

これを例のコメントの前に設定する。$_SERVER はどうやら apache のサーバの環境変数らしい。PHP の if 文なんかも書けるみたいだから、intra から接続したときは (192.168.0.X からの接続とか) は https を使わずに、、、、みたいな複雑なことも phpapacherewrite engine で可能、、、、らしいぞ。

危ない処理をする前にはイメージを commit すればよい

Docker 便利!!スナップショット取れるから、やり直しが簡単。あと、WordPress 的には wp-config.php

define('WP_SITEURL', 'http://192.168.0.XXX:8080/');
define('WP_HOME', 'http://192.168.0.XXX:8080/'); 

の両方或いは片方。を(例のコメントより前に)書き加えれば DB の設定を使わずに固定で立ち上がるぞ。こまったら、直接たぶん MySQL を書き戻せばいい(やらなかった。Docker で手戻りした。その方が簡単だったので、、、<= いや、今考えるとシェルプロで MySQL を書き戻すようにしたほうがよかった。後々その方が使える)

WordPress おすすめのテーマはこれだ!

標準なら Twenty Ten がお勧めかな。ロゴがはれないのがちょっと残念。インストールするなら Clean Journal が気に入っている。無料版がある。無駄にオシャレになれます。あとプラグインでは bbPress を使うとフォーラムとか作れるみたいだ。

でもって Docker だけど、、、

技術的に全く理解していない Docker。

  1. Dockerfile なるものを github に登録して、
  2. Docker hub の ID を取得して
  3. Docker hub で github の Dockerfile を読み込ませて、
  4. Docker hub でイメージを作成する

と一般に公開できるらしいぞ。Dockerfile をみるといろいろスクリプトがかいてあるので、debootstrap だっけ?で生成した root image に対して、コマンドを実行して DB つくったり、デーモン立ち上げたりをするみたいだ。実際に使っていないからなんともいえない。

vivado の dbg_hub ではまったのでメモ

Vivado で波形を見ようと mark debug したときにはまったのでそのメモ。

やろうとしたことは AXI Stream の波形を見ようとしていた。AXI Stream のクロックは Zynq から供給される。なので、そのクロックに合わせて Setup Debug を設定した。

しかし、bit stream をダウンロードしても

WARNING: [Labtools 27-3123] The debug hub core was not detected at User Scan Chain 1 or 3.
Resolution: 
1. Make sure the clock connected to the debug hub (dbg_hub) core is a free running clock and is active OR
2. Manually launch hw_server with -e "set xsdb-user-bscan <C_USER_SCAN_CHAIN scan_chain_number>" to detect the debug hub at User Scan Chain of 2 or 4. To determine the user scan chain setting, open the implemented design and use: get_property C_USER_SCAN_CHAIN [get_debug_cores dbg_hub].
WARNING: [Labtools 27-1974] Mismatch between the design programmed into the device xc7z045_1 and the probes file I:/TSDI/RGB_test/RGB_test.runs/impl_1/debug_nets.ltx.
The device design has 0 ILA core(s) and 0 VIO core(s). The probes file has 1 ILA core(s) and 0 VIO core(s).
Resolution: 
1. Reprogram device with the correct programming file and associated probes file OR
2. Goto device properties and associate the correct probes file with the programming file already programmed in the device.

というエラーが出てしまう。よくよく調べると、debug hub というモジュールにクロックが供給されていないことが原因だ。該当回路図を追って行くと、Zynq の FCLK_CLK2 から”ちゃんと”クロック供給がされている、、、、

というのはうそで、FCLK_CLK2 は Zynq の設定をちゃんとすると供給する。おそらく、ps7_init をちゃんと設定しないとクロックが出てくれない。そこで、SDK を起動して、Hello world のプロジェクトを作って、デバッグで実行。main で止まったところで、再度、bit stream をダウンロード。おーこれでちゃんとデバッグができるようになりました。ときどき vio でうまく以下なったのもこれが原因か、、、

SSLv3 のエラーだが apache.conf で解決

SSL を導入して通常のブラウザからはうまく https が見えるのだが、Smart HTTP(git-http-backend) 経由で Eclipse から import しようとするとエラーが出る。

[Wed Jul 06 15:01:32.119075 2016] [ssl:info] [pid 11614] [client 192.xxx.xxx.xxx:63694] AH02008: SSL library error 1 in handshake (server rt:443)
[Wed Jul 06 15:01:32.119169 2016] [ssl:info] [pid 11614] SSL Library Error: error:140943F2:SSL routines:SSL3_READ_BYTES:sslv3 alert unexpected message (SSL alert number 10)

ログだけ見ると SSLの v3 でエラーになっているように見える。しかし、いまや SSL の v3 は脆弱性が発見されているので使いたくない。でいろいろ調べてみると単純に apache.conf の書き方の問題。

ServerName www.sample.com

みたいに conf を書いておけばいいだけだった。いい加減に www とかにしてたのがよくなかった。
このページを発見していなければ解決できなかった。感謝。

Java - HTTPS通信が失敗するようになる: javax.net.ssl.SSLProtocolException: handshake alert: unrecognized_name - ttshikoのブログ

あと、Smart HTTP
Git - Smart HTTP
このページがかなり上位に来るのだが、Order が間違っているのか、この通りにするとうまく認証しない。ちゃんと apache の認証が通るようにしないとダメ。

ついでに SSLv3 も通さないように apache の設定をする。

        SSLProtocol all -SSLv3

確認は openssl コマンド

openssl s_client -connect www.sample.com:443 -ssl3

g++ あやまったリンクをした際の残骸

あやまったリンクをした際の残骸
記録として残してある。
reent.c
void *_impure_ptr;
newlib のリエントラントな構造を保持するための大域変数。
newlib 内の実装に必要。
libstdc++ を --use-newlib でコンパイルすると、exception の unwind に
この変数が必要となってしまう。
newlib に依存しているという誤った libstdc++ をリンクするとこの現象が出る。
一次的に回避するのに -fno-exceptions を使う。
exception を使いたいのであれば g++ が要求する unwind 用の関数を
実装する必要がある。

cxa_atexit.c
デストラクタの登録に cxa_atexit が呼ばれる。
RTOS として大域変数として登録されたオブジェクトは
そもそもデストラクタを呼ぶ契機がない。
タスクの関数内で登録されているのなら、exit の代わりに
タスク終了の API でデストラクタが呼ばれるようにしないといけない。
-fno-use-cxa-atexit でコンパイルすれば、そもそもこの関数は呼ばれない。

dso_handle.c
ダイナミックローディングされたライブラリをアンロードするときも
デストラクタが呼ばれる。その際に、(おそらく)ダミー的に本体の
オブジェクトにも dso を識別するための変数が要求される。
ダイナミックローディングを使っていないのに、上の cxa_atexit の
第3引数で必要とされるため、自動的に要求されるようだ。
-fno-use-cxa-atexit で回避可能。