Y_Sakurai's bookmarks ;D
Ubuntu 12.04でemeraldがsegmentation faultを起こす場合の対処

前のVerぐらいから、リポジトリに載らなくなって寂しいemerald。
個人的には気に入ってるウィンドウデコレータなので、使いつづけたいのが本音。
というわけで、
http://ameblo.jp/newcomer-t/entry-11236483466.html
あたりを参考にさせてもらいつつ導入…してみたが、自分の環境では見事にsegfault。残念すぎる。

同じ症状の人は他にもいるようで、↑の元記事の
http://iamfuss.deviantart.com/journal/Install-emerald-for-Ubuntu-12-04-292806813
でも言われている。

折角なので、gdbの練習がてら、デバッグ/修正をやってみた。
gdbまともに使うのは初めてなので、試行錯誤も含めて備忘録としてまとめ。
本家に報告したいけど、どうやっていいか分からん…
野良パッケージを作っておいたので、欲しい人は自己責任でどうぞ。
http://miraimaker.com/archive/emerald_0.9.5-fix-for-ubuntu-12.04-1_amd64.deb

まずはソースコードの取得とmake install。
/usr/local/binにパス通してなくて、別に多少ごちゃついてもいいやって人は適宜configureの—prefix引数を変更すること。

$ git clone git://anongit.compiz.org/fusion/decorators/emerald
$ cd emerald
$ ./autogen.sh && make clean && make distclean && ./configure --prefix=/usr/local && make && sudo make install

で、emeraldのgitリポジトリがあるディレクトリ内でそのままgdbを走らせる。
元々GTKのデコレータとかが走ってる場合は、emerald —replaceとかやって強制終了。乱暴だなー。
そのままemeraldが動いた人はおめでとう。ダメな人はsegfaultで落ちるはず。
落ちたら、以下のコマンドでgdbに食わせつつ再実行。

$ gdb emerald

GNU gdb (Ubuntu/Linaro 7.4-2012.04-0ubuntu1) 7.4-2012.04
Copyright (C) 2012 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-linux-gnu".
For bug reporting instructions, please see:
<http://bugs.launchpad.net/gdb-linaro/>...
Reading symbols from /usr/local/bin/emerald...done.
(gdb)

この「分かってる奴だけ触っていいよ^^」的なコンソールにおののきながら、とりあえずrun。

(gdb) r
Starting program: /usr/local/bin/emerald
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
[New Thread 0x7fffef558700 (LWP 28023)]
[New Thread 0x7fffedce6700 (LWP 28024)]

Program received signal SIGSEGV, Segmentation fault.
decor_quads_to_property (data=0x20, n=<optimized out>, pixmap=46137490, frame=0x7fffffffd9b0, border=0x7fffffffd9b0, max_frame=0x7fffffffd9b0,
    max_border=0x7fffffffd9b0, min_width=0, min_height=0, quad=0x7fffffffc9a0, nQuad=8, frame_type=16777215, frame_state=0, frame_actions=0)
    at /usr/include/x86_64-linux-gnu/bits/string3.h:52
52        return __builtin___memcpy_chk (__dest, __src, __len, __bos0 (__dest));
(gdb)

見事にコケました。
なんかぱっと見、string3.hの52行目で落ちてるんだけど、先に答え言うと、これは標準?ライブラリのmemcpy関数呼び出しで死んでるらしい。
んで、decor_quads_to_property関数の中でそれが起きてると。
…とりあえずバックトレースを眺めてみよう。

(gdb) bt
#0  decor_quads_to_property (data=0x20, n=<optimized out>, pixmap=46137490, frame=0x7fffffffd9b0, border=0x7fffffffd9b0, max_frame=0x7fffffffd9b0,
    max_border=0x7fffffffd9b0, min_width=0, min_height=0, quad=0x7fffffffc9a0, nQuad=8, frame_type=16777215, frame_state=0, frame_actions=0)
    at /usr/include/x86_64-linux-gnu/bits/string3.h:52
#1  0x000000000040d59e in update_default_decorations (screen=<optimized out>, fs_inact=0x61a070, fs_act=<optimized out>) at main.c:2437
#2  0x00000000004116e1 in update_settings (ws=0x6188b0) at main.c:5339
#3  0x0000000000406bd7 in main (argc=1, argv=0x7fffffffdb88) at main.c:5633
(gdb)

#1を見ると、main.cの2437行目で呼んでるみたい。
emerald/src/main.cを見ると、確かに呼んでいる。
どうも、引数がおかしそうな感じだなー。
…ところでdecor_quads_to_property関数ってどこで定義されてんの?
gdbで詳細を見てみよう。

(gdb) info symbol decor_quads_to_property
decor_quads_to_property in section .text of /usr/lib/libdecoration.so.0
(gdb)

…libdecoration.soとやらで定義されてるらしい。
emeraldのソースにはそんなの無かったっぽいしなぁ…別のパッケージ?

$ aptitude search libdecoration
i   libdecoration0                                                          - Compiz window decoration library
p   libdecoration0:i386                                                     - Compiz window decoration library
i   libdecoration0-dev                                                      - Compiz window decoration library - development files
p   libdecoration0-dev:i386                                                 - Compiz window decoration library - development files

あったあった。じゃ、libdecoration0のソースを取得して眺めてみよう。
ソース取得時に結構なファイルをカレントディレクトリに残すから、専用のディレクトリを作成して…

$ cd ~/
$ mkdir src
$ cd src
$ apt-get source libdecoration0

なんと、compizのソースが全部落ちてきた。
パッケージ概要にも書かれている通り、compizのウィンドウ装飾で使われるライブラリだから、一緒に開発されてるのかな。
面倒だけど、とりあえず当該ソースを探してみる。

$ cd compiz-0.9.7.6
$ find -name libdecoration*
./libdecoration

$ cd libdecoration
$ ls
CMakeLists.txt  config.h.libdecoration.in  decoration.c  libdecoration.pc.in

decoration.cがそれっぽいので、中を見てみると、中にdecor_quads_to_property関数を発見!
さて、定義を見てみよう。

 157 void
 158 decor_quads_to_property (long		 *data,
 159 		unsigned int    n,
 160 		Pixmap		 pixmap,
 161 		decor_extents_t *frame,
 162 		decor_extents_t *border,
 163 		decor_extents_t *max_frame,
 164 		decor_extents_t *max_border,
 165 		int		 min_width,
 166 		int		 min_height,
 167 		decor_quad_t    *quad,
 168 		int		 nQuad,
 169 		unsigned int	 frame_type,
 170 		unsigned int    frame_state,
 171 		unsigned int    frame_actions)
 172 {

へー…全然わからん。
とりあえず、さっきgdbで見た引数の内容と照らし合わせてみると…

decor_quads_to_property (data=0x20, n=<optimized out>, pixmap=46137490, frame=0x7fffffffd9b0, border=0x7fffffffd9b0, max_frame=0x7fffffffd9b0,
    max_border=0x7fffffffd9b0, min_width=0, min_height=0, quad=0x7fffffffc9a0, nQuad=8, frame_type=16777215, frame_state=0, frame_actions=0)

…なんか最初の引数からしておかしい。
関数定義ではポインタを渡さないといけないはずなのに、渡してるのはどうみても値だよね?
で、decor_quads_to_propertyの開幕で、

 175     data += PROP_HEADER_SIZE + n * (BASE_PROP_SIZE + QUAD_PROP_SIZE * N_QUADS_MAX);
 176
 177     memcpy (data++, &pixmap, sizeof (Pixmap));

…とかやってる。
えーと、dataが0x20で、それに多少足したり掛けたりしたとこで、どうみても正常なアドレスになりそうもない。んでmemcpyに失敗。
原因はこれっぽいなぁ。
…で、dataにはどういうアドレスが入るといいのか。元のemerald/src/main.cで、dataにアドレスを代入しているところを見てみよう。

$ grep "data =" main.c -n
419:    long    *data = NULL;
443:    data = malloc (sizeof (long) * (2 + size * 6));
475:    long* data = NULL;
507:    data = decor_alloc_property (1, WINDOW_DECORATION_TYPE_PIXMAP);
1933:    long* data = NULL;
1944:   data = decor_alloc_property (1, WINDOW_DECORATION_TYPE_PIXMAP);
2349:    long *data = NULL;
2375:   data = decor_alloc_property (1, WINDOW_DECORATION_TYPE_PIXMAP);
2942:    data = NULL;
2959:       data = NULL;

なるほど、基本はdecor_alloc_property関数でポインタを取得するらしい。
さっき止まったのは2437行目だから、一番近そうな2375行目をターゲットにしよう。
gdbをもう一回立ち上げて、ブレークポイントを張る。2375行目と、コケる直前の2435行目に。

(gdb) b 2375
Breakpoint 1 at 0x40d2b8: file main.c, line 2375.
(gdb) b 2435
Breakpoint 2 at 0x40d500: file main.c, line 2435.
(gdb) r
Starting program: /usr/local/bin/emerald
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
[New Thread 0x7fffef558700 (LWP 29141)]
[New Thread 0x7fffedce6700 (LWP 29142)]

Breakpoint 2, update_default_decorations (screen=<optimized out>, fs_inact=0x61a070, fs_act=<optimized out>) at main.c:2435
2435            (*d.draw) (&d);

あらら、2375行目は通らないで、2435行目に来てしまった。
p dataとかやって中を見ても、当然代入はされてない。
他にdataに値を代入してるところは、このupdate_default_decorations関数にはなさそうだし…2375行目を通らない理由を探してみよう。

  2367      if (ws->shadow_pixmap)
  2368      {
...略...
  2374
  2375          data = decor_alloc_property (1, WINDOW_DECORATION_TYPE_PIXMAP);
  2376
...略...
  2387      }
  2388      else
  2389          XDeleteProperty(xdisplay, xroot, bareAtom);

なんか、ws->shadow_pixmapとやらがセットされてないと通らないらしい。
実際、gdbでp ws->shadow_pixmapとかすると0x0が返ってくる。
面倒なので、強引にdataをセットしてみよう。decor_alloc_propertyの引数はよくわからんけど、さっきのgrepで見た感じは大体全部一緒っぽいし。
さっきの2375行目を、if文の前に持ってきて…

diff --git a/src/main.c b/src/main.c
index 520738c..0462ddf 100644
--- a/src/main.c
+++ b/src/main.c
@@ -2363,6 +2363,7 @@ update_default_decorations(GdkScreen * screen, frame_settings * fs_act,

     bareAtom = XInternAtom(xdisplay, DECOR_BARE_ATOM_NAME, FALSE);
     activeAtom = XInternAtom(xdisplay, DECOR_ACTIVE_ATOM_NAME, FALSE);
+       data = decor_alloc_property (1, WINDOW_DECORATION_TYPE_PIXMAP);

     if (ws-&gt;shadow_pixmap)
     {
@@ -2372,7 +2373,6 @@ update_default_decorations(GdkScreen * screen, frame_settings * fs_act,

        nQuad = set_shadow_quads(quads, width, height, ws);

-       data = decor_alloc_property (1, WINDOW_DECORATION_TYPE_PIXMAP);

        decor_quads_to_property(data, 0, GDK_PIXMAP_XID(ws-&gt;shadow_pixmap),
                                &ws-&gt;shadow_extents, &ws-&gt;shadow_extents, &ws-&gt;shadow_extents, &ws-&gt;shadow_extents,

それじゃ、試しにmakeして再実行。

$ make clean && make && sudo make install
$ emerald --replace

おー、動いた動いた!すごい適当な修正だけど、まぁいいか。

ローカル環境でメール送信テストを行なう際は、正規表現で全てのドメイン(除くテストメール配信先)をmydestinationにセットすると、間違って変なとこに送っちゃうことがなくていいよね。

4歳の子供が知っておく(知らされる)べき5つのこと

1.常に、完全にかつ無条件に愛されているということ

2.安全であるということ
人前や多様な状況で自分を安全な状態に保つ方法
人々について、自分の直感を信頼してよいということ
正しいと感じないことは、たとえ誰から要求されても、けしてする必要がないということ
個人としての諸権利を有していること、そして家族がそれらを支えてくれているということ

3.笑い方、ふざけ方、おちゃらけ方、そして想像力の使い方
空をオレンジ色に、猫を6本足に描いても全く問題ないということ

4.自らの興味関心が何か、そしてそれらを自由に追求してよいということ
もしも、子供が数を学ぶのに関心がなくても、知らず知らずのうちにあっという間に学んでしまいます。かわりにロケットやお絵かき、恐竜、泥遊びに熱中させてあげましょう。

5.世界は魅惑的で、自分もその一部であるということ
自分が素晴らしく、華々しく、独創的で、思いやりのある、奇跡のような存在だということ
外で一日中、ヒナギクの鎖や泥のパイや妖精の家をつくるのは、音声学の訓練と同じくらい、いやもっと価値があるということ

親が知っておくべき5つのこと

1.すべての子供は歩き方、話し方、読み方、代数学を自分のペースで学ぶということ、そして、そのペースは結果の良し悪しに影響しないということ

2.高い学力のための唯一最大の前兆は子供に読み聞かせてあげること
フラッシュカードでもワークブックでも高級な幼稚園でも点滅するおもちゃでもコンピュータでもなく、日夜時間をとって素晴らしい本を読み聞かせてあげましょう。

3.クラスで一番の成績になることと幸せになることは関係がないということ
私たちは自分の子供に「強み」を与えようと夢中になりすぎて、私たちと同じマルチタスクでストレスに満ちた生活を与えてしまっています。私たちが子供に与えられる最大の強みは、気取らない気ままな子供時代です。

4.子供が、本や自然や美術品、それらを探検する自由のある環境にいるにふさわしいということ

5.子供がもっと私たちを必要としているということ
私たちは、自分のことをしなきゃと言うのがとても上手になり、他の誰かに子供の世話をさせる言い訳に使いがちです。
たしかに、私たちは皆、静かな入浴タイム、友達と過ごす時間、平静さを取り戻すための休憩、たまの親としてではない人生が必要です。
私たちは、子育て雑誌が、子供に一日10分を使い、月に一回土曜日を家族で過ごす日と決めることを勧める時代に生きています。こんなのはまともではありま せん!子供たちは任天堂やコンピュータ、課外活動、バレエの稽古、グループで遊ぶこと、サッカーの練習以上に私たちのことを必要としているのです。
子供たちは、座って話を聞いてくれる父親を、工作を一緒に手伝ってくれる母親を、物語を読み聞かせてくれる、馬鹿みたいなことを一緒にしてくれる両親を、必要としているのです。
子供たちは、春の夜に私たちと一緒に散歩をしたいし、時速1メートルのよちよち歩きにも気にしないでほしいのです。
たとえいつもの2倍の時間と手間がかかるとしても、子供に夕食の支度を手伝ってもらうのは価値があります。
子供たちは、私たちにとって、かけがえのない、愛おしい存在であると、伝え知らされなければいけないのです。

姉のために

4歳の子供とその親が知るべき5つのこと: とみー (via branch)

子供として、5つとも知らなかった。いまだに世界が怖くて仕方がありません。

(via interglacial)

2010-12-23

(via quote-over100notes-jp)

母ちゃんは知ってたし、おいらに教えてくれた

(via leedsichthys)

「仕様自体はころころ変わるが、メタロジックはかわらないことが多い。」ということは理解すべきです。その区別を理解することが必要です。それがわからないと個別の仕様に振り回されて、切ることができない。んで、なんか極端にふれてしまって、んで、曰く、受託は駄目だ、全部アジャイルだ・・・そうではありません。

いわゆる仕様と業務例外について - 急がば回れ、選ぶなら近道 (via ishinao)

強く同意。起業して学んだことのひとつ。仕様はHow、5Wから目をそらすと取引に負ける。

(via miyanaga)

勉強になる

(via extumb)

ポール・グラハムの本「ハッカーと画家」を読んで、この人に興味が湧いたので。

この人の発言には、個人的にはあまり同意できかねる主張もあるんだけど(汚くてもすぐ作れて動くコードを…とか)、それは「今までの業務経験と自分の役割から来るものかな」とか「自分はそう思えるレベルまで到達してないんだな」とか、そういうのもあると思う。

もちろん、お客は常に正しい。 良いデザインはユーザーに対してもたらす効用によって測られる、という意味においてはね。 皆を飽きさせる小説を書いたり、座り心地が最悪な椅子を作ったりしたら、 それは単にダメな仕事だ。たとえその小説だか椅子だかが 最新の理論に基づいて作られていたとしたって何の足しにもなりゃしない。

それでも、ユーザーにうまく使ってもらえるものを作るというのは、 ユーザーの言う通りに作るということとは違う。 ユーザーは全ての選択肢を知っているわけじゃないし、 本当に欲しいものが何かということについてはよく間違う。

開発者が、たまにお客さんと直に話をしたがる理由はここにある。

「それ、何のために必要なの?結局何が必要なの?」

「つまり、お客さんの満たしたいニーズって、何?」

「いつまでにどれだけの機能が必要?予算はどこまで出せる?」

システムを知らない、下手すれば普段の自分の業務すら完全に理解していないお客さんから、上記のような情報を引き出すのって、どうしても直に話さないと難しいと思うんだよね。

開発者とお客さんを遠ざけるのは、やっぱり良くないと思う。すぐ怒鳴ったりとか、話し合いができないお客さんもまれにいるけど…

志気の問題は、 低いレベルのユーザーのために何かをデザインするのが難しいことのもう一つの 理由でもある。自分で気に入らない何かに対して興味を持ち続けるのはとても難しい。 良いものを作りたいなら、いつも「うーむ、こいつは素晴らしいぞ」と 思い続けていなくちゃ。「なんてひどいがらくただ。馬鹿どもは気に入るだろうがな」 なんて考えるんじゃなく。

あるいは、「なんてひどいがらくただ…でも、こうすればちょっと良くなるんじゃない?」と思えるかどうか、かな。

実際、納期やら政治的理由やら仕様漏れやらで残念なことになってるシステムを直すときは、そう思える。

もっとも、普段直すことばかりやってて、「自分からスクラッチする」ということができなくなってるのがヤバイとこだけど。元々ものぐさな性格だからなー…

現実には、良いデザインを得るにはユーザーに近付き、そして常にユーザーの側に 居なくてはならない。実際のユーザーに合わせて常に考えを調整しなければならない。 特に最初の段階がそうだ。ジェーン・オーステンの小説が良いわけは、 彼女はまず作品を家族に読んで聞かせたからだ。だから彼女は自己満足的な 芸術ぶった風景の描写や、もったいぶった哲学的考察に堕ちることが決して無かった。

これは開発に限らず、ナルシストな自分がよくやりがちなミスだ。

誰にでも分かり、平易で、でも本質を適切に押さえた説明。できれば苦労はしないけど、ゴールとして置く必要はある。

科学者の間にどんなストーリーがあろうと、 芸術の分野での真の協調作業はほとんど見出せないと言えるだろう。 委員会によるデザインは悪いデザインと同義語だ。なぜそうなのだろう。 この限界を破る方法はあるのだろうか。

私はその方法は無いという考えの方に惹かれる。良いデザインには独裁者が必要なんだ。 ひとつの理由は、良いデザインは完全に一つにまとまったものでなければならない ということだろう。デザインは単に人間のためのものであるというだけでなく、 個々の人間のためのものだ。デザインが一人の人間の頭に収まる考えを 表わしているのなら、それはユーザーの頭にもきっと収まるだろう。

良いデザインには独裁者は必要かもしれない。

オープンソースでよく言われる「寛容な独裁者」にも通じるところがあるんだろうか。

でも、個人的には「良い取り巻き」もあると思う。必要かどうか、は場合によるかもしれないけど。

「良い取り巻き」が良質な情報を活発に発信しあう流れがあって、はじめて「独裁者」は「良いデザイン」に辿り着き、それを採用する、というのが協調作業とは言えないかな。

EXPLAIN結果でpossible_keysがあるのにtype=ALLが出るのが気になってたけど、そーゆーことね。

MySQL では利用可能な場合でもインデックスが使用されない場合があることに注意してください。この一例として、インデックスの使用によって、MySQL がテーブルの 30% を超えるレコードにアクセスする必要が生じる場合が挙げられます(この場合は、必要なシークが大幅に減少するため、テーブルスキャンのほうが高速になる可能性が高くなります)。

pineappledesign:

ResearchGate という研究者向けSNSがある.自分のpublicationを登録していくのだけれど,このときcoauthorを登録すると,その人のアカウントにもpublicationが登録される.

似たような研究者向けSNSに(内部的には違うようだが)日本のResearchMap.jpがある.といっても,ResearchGateのほうはなかなか辛口で,研究者の推定インパクトが自動的に表示される.

もし将来,IFだけでなくて学生の評判とかページランクとかエッジランクとかいろいろミックスされてくると,かなり面白い(恐ろしい)評価システムになるだろう.

プログラマへの誤解

pineappledesign:

プログラムを書かない人がプログラムを読んだときにする良くある間違いは,ああこんなプログラムなら自分にも書けそうだと思うことだ.プログラムは何百万とある可能性からたったひとつ(は言い過ぎにしてもわずかながら)の正しい方法を残したものであり,この捨てる能力こそがプログラマの実力だから.

同感。

プログラマは、迫りくる納期や少ないドキュメントといった、乏しい情報や厳しい制約の中から、出来る限りの最適解を探し出す必要がある。それも割と多くのシーンで。

「本当にこの挙動で仕様を満たしているのか、利用者は満足するのか」

「データが増えた場合、ここの処理が極端に遅くならないか」

「残りの部分を実装するのにかかる時間はどれぐらいか」

「将来の仕様変更を見越して、ここはDBに格納すべきじゃないか」

そんな見通しの難しい予測や不安を抱えて、メソッドの切り直しやロジックの改修といった、細かいけど後戻りの難しい決断を何度も繰り返す。

そんなことをずっとやってると、時折もの凄い不安に襲われることがあるな…

悩みが多いというのはプログラマだけに限った話じゃないとは思うけど、この業界に心を病む人が多い理由は、そういうのもあるんじゃないかと思った今日この頃。

デスマーチがなくならない理由の一つは、デスマーチをどうにかしてしまう人たちがいるから。というかその手の人たちの中には緊急事態になると実に生き生きとしだし、炎上をエンジョイというか、プロジェクトが燃えてるなら俺も燃えるぜというか、非常事態になってから「こんなこともあろうかと思って用意しておいたのさ」と新兵器を投入するマッドサイエンティストのような振る舞いになる人たちもいる。

それでプロジェクトが何とかなるまではいいとして、問題はその後。そこで関係者に「俺たちはこんな過酷な条件でプロジェクトを終えた」というプロジェクトX的な勘違いが生まれると、まあまずまともな反省はされないんじゃないかな。そしてその勘違いが生まれる原因の一旦が、そのデスマーチ請負人みたいな人の武勇伝だったりする。

というかプロジェクトが炎上とかの大失敗からは、何でもいいから次に繋げるための何かを見出すべきで、そうでもしないと燃え損じゃねえか。

色々と考えさせられる

2012-02 :: return0 blog (via do-nothing)

いい素材だ…

おお、ついにJOIN対応したのか!

いちいち|cwとか打つの面倒だったので導入したが、思いの外便利だった。

yoyoyonoyo:

「ゆっくり・・・」/「いちむー」のイラスト [pixiv]

結構ややこしいんよね