Monday, November 19, 2012

How to fix Android NDK Error: non-numeric second...

First of all, My English sucks ;)

Problem:

When I did ndk-build on terminal with a new android project and I got a follow message.

$ ndk-build
android-ndk-r8c/build/gmsl/__gmsl:512: *** non-numeric second argument to `wordlist' function: ''. Stop.

 
How To Fix:

Just simply add android:minSdkVersion tag to AndroidManifest.xml.

<uses-sdk android:minSdkVersion="3" />

What I did:

It seems something goes wrong so I decided remove project files one per one before hack the 512 line of __gmsl because I believe the ndk version "r8c" which I used.

Finally, I got the reason of build fail is 'AndroidManifest.xml'.

$ rm -f AndroidManifest.xml
$ ndk-build
Gdbserver : [arm-linux-androideabi-4.6] libs/armeabi/gdbserver
Gdbsetup : libs/armeabi/gdb.setup
Install : libhello.so => libs/armeabi/libhello.so

Then I tried do diff with sample codes which's shipped with Android NDK


$ android create project -t 2 -k com.myproject -a HelloActivity -p .
$ diff AndroidManifest /path/to/android-ndk/samples/hello-jni/AndroidManifest.xml
...
<uses-sdk android:minSdkVersion="3" />
...

DAMN!

Sunday, October 2, 2011

gnome3 「最近使った項目」を初期化

gnome3で最近使った項目(recent items)を初期化する。

$ cat /dev/null > ~/.local/share/recently-used.xbel

recently-used.xbelはFedoraなら上記のパスになる。
その中身を消してしまえばOK。xserverを再起動する必要はない。

gnome2とは違って、項目らをキャッシュしておくのではないらしい。

Sunday, September 18, 2011

ruby debugでActiveRecordをデバッグ

rails3からはruby-debugをサポートとしているが、場合によってはruby-debugを使えなかったりもする。個人環境であれば全く問題ないはずだろうが、たまにはデプロイサーバなどでデバックを行わざるを得ない。デプロイサーバなどで新しいライブラリやツールを導入するのはちょっと面倒なので、できれば標準ライブラリを使った方がスムーズに行けるだろう。そのため、今回は標準ライブラリdebugを使ったrailsデバッグに手をかけてみることにした。

※railsとruby-debugの公式文書はこちらに詳しく説明されている。
日本語文書もそこそこポスティングされているようだ。

大まかに言うと標準ライブラリのdebugとruby-debugはほぼ同じ(かも)。ただ、railsの起動そのものとは違うので、必要な環境設定ファイルなどを手動でロードさせるしかない。

まず、テスト環境を作る。
$ rails new debug -d sqlite3
$ cd debug/
$ rake db:create
$ rails g model Blank
$ rake db:migrate
新しいモデルまで作成できたら、問題を起こすコードを入れる。
# app/models/blank.rb
1:   class Blank < ActiveRecord::Base
2:     class << self
3:       def get_all
4:         self.all
5:         []
6:       end
7:     end
8:   end
ふざけたコードだが、よいとしよう。ごく単純なコードだが、行数が数十行程度だとしても分かりづらかったりする。ここでは、debugに慣れることだけ考えよう。

このコードで知りたいのは、get_allからなぜ空っぽの配列ばかりが返ってくるのかだ。ちなみにblank.rbそのものはBlankクラスとBlank::get_allを定義しているたけなので、これらを実行するコードも用意しておく。場所はどこでもよい。
# ../blank_get_all.rb
Blank.get_all
これで準備はOK。いよいよデバッグを開始する。
$ ruby -rdebug ../blank_get_all.rb
するとデバッグプロンプトが出てくる。基本的な操作方法はhまたはhelpで出せるので、知りたいコマンドがあればその都度調べておこう。

まず、正常にデバッガが立ち上がったのか確認して見る。
rdb:1) l
[-4, 5] in ../blank_get_all.rb
=> 1  Blank.get_all
よし、行けた。lはlistの略であり、表示したいラインの前後のコードを表示する。オプションとしてライン番号を指定できる。省略した場合は、現在のポイントが指しているラインを表示してくれる。

Blank.get_allが空っぽの配列を返すのは既に分かっていることだ。これだけじゃ、問題解決はできなさそうなので、もう少し詳しく調べてみよう。ただし、このままではBlankクラスが何なのかをデバッガは全く知らない。pコマンドでBlankを調べてみると、
(rdb:1) p Blank
......lib/ruby/1.9.1/debug.rb:130:in `eval':uninitialized constant Object::Blank
from .../lib/ruby/1.9.1/debug.rb:130:in `rescue in debug_eval'
from .../lib/ruby/1.9.1/debug.rb:127:in `debug_eval'
from .../lib/ruby/1.9.1/debug.rb:492:in `block in debug_command'
from .../lib/ruby/1.9.1/debug.rb:240:in `catch'
from .../lib/ruby/1.9.1/debug.rb:240:in `debug_command'
from .../lib/ruby/1.9.1/debug.rb:691:in `trace_func'
from .../lib/ruby/1.9.1/debug.rb:905:in `block in '
from ../blank_get_all.rb:1:in `
'
と怒られる。これはrails環境とBlankクラスがまだロードされていないせいであろう。だけど、少し面倒なだけで手動でロードしてしまえば全く問題ない。
(rdb:1) require './config/environment'
(rdb:1) p Rails.env
"development"
大体の場合はconfig/environmentを読み込むだけで済むはずだが、カスタマイズした環境設定ファイルがあった場合も同じように読み込めばいい。Rails.envがdevelopmentを返しているが、これもデバッガ内で切り替えられるので、気にしなくていい。

次はblank.rbを読み込む。
(rdb:1) p ActiveRecord
ActiveRecord
(rdb:1) require './app/models/blank.rb'
false     # 既にロードされているから
これでやっと準備が揃った。stepでBlank.get_allの中身を見てみよう。
(rdb:1) s
.../debug/app/models/blank.rb:5: self.all
(rdb:1) l
[0, 9] in .../debug/app/models/blank.rb
      1 class Blank << ActiveRecord::Base
      2
      3   class << self
      4     def get_all
=> 5       self.all
     6
     7       []
     8     end
     9   end
ここでもう一度stepコマンドで進んでみよう。(ActiveRecordの中身など見たくない場合は、nコマンドで次のラインに移動する)

(rdb:1) s
.../gems/activerecord-3.1.0/lib/active_record/base.rb:441:      delegate :find, :first, :first!, :last, :last!, :all, :exists?, :any?, :many?, :to => :scoped
(rdb:1) l
[436, 445] in .../gems/activerecord-3.1.0/lib/active_record/base.rb
   436
   437      class_attribute :_attr_readonly, :instance_writer => false
   438      self._attr_readonly = []
   439
   440      class << self # Class methods
=> 441        delegate :find, :first, :first!, :last, :last!, :all, :exists?, :any?, :many?, :to => :scoped
   442        delegate :destroy, :destroy_all, :delete, :delete_all, :update, :update_all, :to => :scoped
   443        delegate :find_each, :find_in_batches, :to => :scoped
   444        delegate :select, :group, :order, :except, :reorder, :limit, :offset, :joins, :where, :preload, :eager_load, :includes, :from, :lock, :readonly, :having, :create_with, :to => :scoped
   445        delegate :count, :average, :minimum, :maximum, :sum, :calculate, :to => :scoped 
(rdb:1) f
--> #1 /Users/lateau/.rvm/gems/ruby-1.9.2-head/gems/activerecord-3.1.0/lib/active_record/base.rb:441:in `all'
    #2 /Users/lateau/dev/testroom/ruby/debug/debug/app/models/blank.rb:5:in `get_all'
    #3 ../bundle_get_all.rb:1

フレーム3から1に移動しているのが分かる。多分、この先も何回もフレームを移動することになるだろう。ActiveRecordがどのような働きをしているかが知りたいなら、stepコマンドで1行ずつ確認してもよいだろうが、今回の目標ではない。ただstepでActiveRecordの中身をデバッグ中に確認できることだけ覚えておこう(octopusなどのdbmを調べる時に役立つ)。
(rdb:1) b ./app/models/blank.rb:5
Set breakpoint 1 at ./app/models/blank.rb:5
(rdb:1) b
Breakpoints:
1 ./app/models/blank.rb:5
ブレークポイントをかけた。これでblank.rbの5行目で必ず止まるはず。1行ずつ行くのはどうも面倒なので、continueコマンドを使う。5行目で止まったらnコマンドで次の行に移動する。

(rdb:1) n
.../debug/app/models/blank.rb:7:      []
「7行目を実行すると5行目の戻り値とは関係なく[]が返ってくる」というのが分かる。これでBlank::get_allが何故空っぽの配列ばかりを返すのかが分かった。分かったら、該当コードを直し、問題を解決する。


ここまで大雑把なdebugの使い方を説明した。説明できなかった部分もあるが、一通りのデバッグはこれで充分であろう。ちなみに、ActiveSupportはActiveRecordとほぼ同じ方法でデバッグできる。ActionContollerは少し面倒な部分があるので、次回時間があったら説明する。