MB-Systemのmbeditコマンドがセグフォで落ちてハマった話

最近Qiitaはじめてそれとブログの使い分けを模索しております。ということでブログにはいろいろ試行錯誤した結果、Qiitaには完全に手順化されたり、検証された事実ベースで書いていこうかなと思います。ということで今日ははまったはなしとその対策。

MB-Systemというのは「Seafloor Mapping Software」ということらしいです。
研究で使うことになるツールの一つ。
これをFedora20にソースから入れたんだけどmbeditが起動せずにセグフォで落ちて困ってた。
configureの出力見てもちゃんと全部の機能Enabledになっているし、ldd mbeditしても特に共有ライブラリ解決できてないとか、変なの読み込んでいるとかなさそうだった...
しかたなくソースを読むことに。printfでどこでセグフォが起きているかの特定の作業。
幸いなことに起動時に落ちることからmainであたりをみていけば良い。do_mbedit_init関数を呼び出しているところでセグフォが起きているっぽいのでそちらをさらにしらべていく。どうやらフォント読み込んで適応しているところで落ちているっぽい。勘でロードのミスっていてないものを適応しようとして落ちているのかなーと思ってX Window Systemの登録されているフォント調べるためにxlsfontsで確認。案の定ない。yum searchしてそれっぽいパッケージあったのでインストール。ちゃんと動きました。
フォント関係もconfigureでチェックしてくれればいいと思うんだけど、難しいのかなぁ...

Fedora20でEMOBILEの無線LAN接続が不安定になった話

Fedora20でkernelをアップデートしたらEMOBILEのGL06Pの無線LAN接続が不安定になった。
原因はおそらくこれなので古いカーネルに差し戻したら(幸いカーネル自体は残っていたのでブートローダでkernelを変更するだけ)今までどおり使えるようになった。
他に困っている人がいるかもしれないのでメモ。
無線LANドライバが原因かなと思うけど他のルータにつないでもふつうに使えるのが謎い...

and演算子の短絡評価にはまった話

以下のコードで論理演算でなぜか右の関数funcが呼び出されてない><

    return a && func();

ってことになやまされ、とりあえず問題を分解するために

    auto f = func();
    return a && f;

としたら正常に動いた。
なんで?って思ってTwitterでつぶやいたら一瞬で反応がかえってきた。
どうやら短絡評価というらしい。
これはつまり評価の際「false && func()」の時点で答えはfuncの返す値にかかわらずfalseになってしまうのでここで評価をやめてfuncは永久に呼び出されないというもの。funcが重い処理だったりするときに便利だけどfuncがboolを返す以外の副作用をもってたりすると今回みたいに意図した結果を返さずハマる...評価させたいものはバラすか、あるいは左にもってくるかしないとダメということですね。

もう忘れない。踏みぬいたバグの数だけ強くなれるよね(と信じたい

CentOS6.3+nginxでJenkinsを導入した時のメモ

とりあえず入れてみたので手順メモ。
構成としてはnginxをリバースproxyにして、/jenkinsにきたものをjenkinsに転送させている。

まずjenkinsを入れる。

$sudo wget -O /etc/yum.repos.d/jenkins.repo http://pkg.jenkins-ci.org/redhat/jenkins.repo
$sudo rpm --import http://pkg.jenkins-ci.org/redhat/jenkins-ci.org.key
$sudo yum install jenkins

また、jenkinsを動かすためにはjava-1.6.0とかがひつようなようなので入れる。

$sudo yum install java-1.6.0-openjdk

設定ファイルを編集。念の為バックアップをとっておく。

$sudo cp /etc/sysconfig/jenkins{,.bak}
$ sudo diff /etc/sysconfig/jenkins{,.bak}
133c133
< JENKINS_ARGS="--prefix=/jenkins --httpPort=${JENKINS_PORT} --ajp13Port=${JENKINS_AJP_PORT}"
---
> JENKINS_A||<RGS=""

つぎにnginxの設定。

$ sudo cp /usr/local/nginx/conf/<設定ファイル名>{,.bak}
$ sudo vim /usr/local/nginx/conf/<設定ファイル名>
$ sudo diff /usr/local/nginx/conf/<設定ファイル名>{,.bak}
13,16d12
<     	
< 	location /jenkins {
<       	    proxy_pass http://localhost:8080; 
<     	}

特に複雑な設定がいるわけではない(ちなみに実際の運用に使っているものには一応BASIC認証をかけた)

そして起動。

$sudo /etc/init.d/jenkins start
$ sudo /usr/local/nginx/sbin/nginx -s stop
$ sudo /usr/local/nginx/sbin/nginx

アクセスするとちゃんとうごいた。
とりあえずJenkinsちょっとつづ使っていこう。

iノード(inode)の使用量をディレクトリごとに表示するワンライナー

ファイルのメタ情報を格納するiノード(inode)というものがあるがこれが枯渇するとそれ以上ファイルが作れなくなってしまう。
iノードの数が少なくなってきた時どこが主にiノードを食っているのか確認したいことがあると思う。
が、特定ディレクトリのiノードを表示するコマンドは残念ながらない。
しかしiノードはファイル/ディレクトリに対して(ハードリンクをしない限り)ユニークに割り当てられるということを用いて大体の数を算出することができる。
以下がそのワンライナー。カレントディレクトリにあるディレクトリのiノードを表示してくれる。
使い方としてはdf -iでiノードが減少しているディスクをさがしそこのディレクトリに移動、肥大化しているディレクトリを調べる。
その肥大化しているディレクトリに移動...を繰り返して範囲を適切に狭めていく。

    for dir in `ll|grep ^d|grep -v "\./"|awk '{print $9}'`; do echo  `find ./$dir -true|wc -l` `pwd`/$dir; done | sort -nr

していることとしては

    ll|grep ^d|grep -v "\./"|awk '{print $9}'

でllの出力のうち先頭のパーミッションを解析してディレクトリのものをフィルタし、awkでディレクトリ名を取り出している。
ちなみにllのフォーマットがディストリビューションによって異なっていたり、そもそもなかったりするのでgrepawkの部分注意。
ls -lを使ったほうが無難かもしれない。

さてその結果の各行ごとに回しながら取り出して

    for dir in `ll|grep ^d|grep -v "\./"|awk '{print $9}'`

でdirに束縛する。

そして

    do echo `find ./$dir -true|wc -l` `pwd`/$dir

で./dir以下にあるファイルすべてを列挙しwc -lでその数を数えている。
あとは見やすいようにpwdとdirでそのディレクトリを表示している。
これだけでもいいがファイル数順(=iノードを消費している順)にならんだほうがみやすいのでsort -nrで並べ替える。

Kuinでlistに対するremoveとremove_ifを実装してみた

こんな感じ。
list操作と関数オブジェクトを受け取る関数の良いサンプルになってるんじゃないかと。

func remove(List : &list<int>, val : int)
	
	do List.Head()

  	while ( List .ChkEnd() <> true)
    if (List.Get() = val) 
		do List.Del()
	else
		do List.Next()
	end if
 	end while 
end func

func remove_if(List : &list<int>, pred : func<(int):bool>)
	
	do List.Head()

  	while ( List .ChkEnd() <> true)
    if (pred(List.Get())) 
		do List.Del()
	else
		do List.Next()
	end if
 	end while 
end func



func Main()
	var Data : list<int> :: #list<int>
	do Data.Add(2)
	do Data.Add(3)
	do Data.Add(5)
	do Data.Add(3)
	do Data.Add(4)
	do Data.Add(6)
	do Data.Add(7)
	do Data.Add(6)

	foreach datum(Data)
		do Dbg@Log(datum.ToStr())
	end foreach

	do Dbg@Log("==")



	do @remove(&Data, 3)

	foreach datum(Data)
		do Dbg@Log(datum.ToStr())
	end foreach

	do Dbg@Log("==")

	func lambda(x : int) : bool
		return x%2 = 0
	end func

	do @remove_if(&Data,lambda)

	foreach datum(Data)
		do Dbg@Log(datum.ToStr())
	end foreach




	do Kuin@Stop()
	
end func

Kuinにはテンプレートとかないのでとりあえずint型のみ。
アルゴリズム自体はC++のとたいして変わらないのでそんなに説明はいらないと思う。
おもしろいのはイテレータ(とはKuinではいわないけど、慣れていて使いやすい言葉なので便宜的に)を内部に持っているっぽいということ。
なのでHeadで先頭にイテレータをもってきてそれでNextとかでガリガリ。
Delで要素を削除してイテレータを前にすすめる。

remove_ifのほうはそれにプレディケータをうけとるようにしたような。こちらはたいして説明することないと思う。ただ、つかうときにラムダ式がないので名前付き関数作ってそれを渡すしかない...まあ、適当にスコープをきってあげれば普通につかえるんじゃないかと。

Kuinでポリモーフィズムできるか実験

昨日Kuin1.00がリリースされましたね。
ということで早速使ってみました。

と、その前にKuinってなんぞや?という人もいると思うので軽く説明。
ってか抜粋。

プログラミング言語Kuinは、「HSP並みに作りやすく、C++並みに実用的な言語」というコンセプト
で制作された、究極の言語です。 Kuinの主な特徴について以下に列挙します。
オブジェクト指向でありながら、可能な限りシンプルで解りやすい設計
・言語設計の美しさより、実用面での美しさを重視
・ポインタ、イテレータ、テンプレートなど、ややこしい概念はすべて排除(代替機能を用意)
・動的メモリは自動で解放されるので、解放処理が不要
・豊富な標準ライブラリ(3D描画なども簡単)
・コンパイル速度が爆速
・64bitネイティブ機械語を生成するので、実行速度も速い
・何もプログラムを書かなければ、自動でHello World!!になる

製作者はいわずとしれたくいなちゃん(@b2)

さて、ドキュメントにポリモーフィズムとかそこらへんのこと全然書かれていないので
使えるのかな?とか疑問に思ったので試してみた。
結論から言うと使えて以下の様な感じになる。

class Hoge()
	func method()
		do Dbg@Log("hoge")
		return 
	end func
end class

class Foo(@Hoge)
	+func method()
		do Dbg@Log("foo")
		return 
	end func
end class

func getInstance(id :int) : @Hoge
	if (id = 0)
		return #@Hoge
	else
		return #@Foo
	end if

end func

func Main()
	var a: @Hoge :: @getInstance(0)
	do a.method()
	do a :: @getInstance(1)
	do a.method()
	do Kuin@Stop()
end func

迷った点はグローバルスコープのものはすべて@で修飾しなくちゃいけないということでしょうか?
関数やクラスも@で修飾しないといけません。それさえ気をつければあとはドキュメントにしたがって
直感どおりかけます。
ぱっと見気持ち悪いですがなれるとスラスラかけて良い。
次作るゲームにはKuin使おうと思う。

はてなのハイライトはやくKuinに対応しないかな...