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でチェックしてくれればいいと思うんだけど、難しいのかなぁ...
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のフォーマットがディストリビューションによって異なっていたり、そもそもなかったりするのでgrepやawkの部分注意。
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に対応しないかな...