JRuby実行中にjdbでアタッチしてrubyプログラムのbacktrace

in JDB, Ruby
by ginriki | 1 月 12th, 2010 

Ruby自身のデバッガだと、任意のタイミングでアタッチしてbacktrace見るといったことができない(はず)なので、もっと低レベルのデバッガを利用して、それを実現する方法についてメモ。今回はJRubyに対してjdbでアタッチ&backtraceする方法についてのメモです。
なお、CRubyの場合は、以前の記事とか、さらにその先のリンク先を見れば良いです。
ちなみに、今回試したJRubyのversionは以下の通り。OSはCentOS 5.3です。

$ jruby --version
jruby 1.3.1 (ruby 1.8.6p287) (2009-06-15 2fd6c3d) (Java HotSpot(TM) Client VM 1.6.0_16) [i386-java]


jdbによるbacktrace



まず、アタッチ対象例のRubyコードとして以下を用意。

sample.rb

RUBY:
  1. def foo
  2.   p "abc"
  3.   bar
  4. end
  5.  
  6. def bar
  7.   p "foge"
  8.   sleep(1000)
  9. end
  10.  
  11. abc

そして、デバッガattach用のポートを開けて起動します1

$ jruby -J-Xdebug -J-Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=n sample.rb

barメソッド内のsleepの実行をしているうちに、別のターミナルを開いてjdbでアタッチし、スレッドを停止させます。

$ jdb -attach 8000
> suspend
すべてのスレッドが中断されました

そして、backtraceを表示させます。以下の方法で大体表示できます(いい加減なやり方ですが)。

> threads
グループ system:
  (java.lang.ref.Reference$ReferenceHandler)0x9db Reference Handler 状況待機中
  (java.lang.ref.Finalizer$FinalizerThread)0x9da  Finalizer         状況待機中
  (java.lang.Thread)0x9d9                         Signal Dispatcher 実行中
グループ main:
  (java.lang.Thread)0x1                           main              状況待機中
> thread 0x1
main[1] where
  [1] java.lang.Object.wait (ネイティブ メソッド)
  [2] org.jruby.RubyThread.sleep (RubyThread.java:718)
  [3] org.jruby.RubyKernel.sleep (RubyKernel.java:725)
  [4] org.jruby.RubyKernel$s_method_0_1$RUBYINVOKER$sleep.call (null)
  [5] org.jruby.internal.runtime.methods.JavaMethod$JavaMethodN.call (JavaMethod.java:620)
  ...(以下略)
main[1] up 4
main[5] locals
メソッド引数:
context = instance of org.jruby.runtime.ThreadContext(id=2527)
self = instance of org.jruby.RubyObject(id=2528)
clazz = instance of org.jruby.MetaClass(id=2529)
name = "sleep"
arg0 = instance of org.jruby.RubyFixnum(id=2531)
block = instance of org.jruby.runtime.Block(id=2532)
ローカル変数:
main[5] dump context.frameIndex
 context.frameIndex = 2 #frameStackの上限(たぶん)
main[5] dump context.file + ":" + context.line
 context.file + ":" + context.line = "sample.rb:7" #現在位置
main[5] dump context.frameStack[2].fileName + ": " + context.frameStack[2].name + ":" + context.frameStack[2].line
 ...(省略)... = "sample.rb: bar:2" #1つ前のスタックフレーム
main[5] dump context.frameStack[1].fileName + ": " + context.frameStack[1].name + ":" + context.frameStack[1].line
 ...(省略)... = "sample.rb: foo:10" #2つ前のスタックフレーム
main[5] dump context.frameStack[0].fileName + ": " + context.frameStack[0].name + ":" + context.frameStack[0].line
 ...(省略)... = ": null:0" #トップレベル

以上になります。

  1. ここの「Debugger」の項目を参考にオプション設定しました。 []

autoloadで自動読み込みされないファイルをユーザアクセス毎に再読み込みする

by ginriki | 12 月 31st, 2009 

今回はRuby on Railsについてメモ。

autoloadで自動読み込みされないファイル1をcontrollerの中などでrequireを使って読み込んだ場合、そのファイルはdevelopmentモード時でもユーザアクセス毎に再読み込みされません。そのため、ファイルを編集してもwebサーバを再起動しないと変更が反映されないので、デバッグがやりづらくて困ってました。

解決策がないかと思って、ググってみたところ、以下のページに解決策が書いてありました。
http://www.pistolfly.jp/weblog/2007/06/require-dependency.html

requireじゃなくて、require_dependencyでファイル読み込みすれば良いということでした。
require_dependencyの挙動については、上のリンク先を参照してください。
この辺り(autoload周辺)って、Ruby on Rails公式なドキュメントが見当たらないですねえ。・・・実装を読めってことか。

以下、問題のコード例と解決方法。(ruby 1.8.5, rails 2.3.3, WEBrick 1.3.1で実験しました。)

ファイル読み込みの対象となるファイルを用意します。

<rails_project>/lib/hoge_fuga.rb

RUBY:
  1. class Hoge
  2.   def hoge
  3.     return "abc"
  4.   end
  5. end

上のファイルを読み込むcontrollerを用意します。
このとき、requireの代わりにrequire_dependencyでファイルを読み込みます。

<rails_project>/app/controllers/test_controller.rb

RUBY:
  1. #require 'hoge_fuga'
  2. require_dependency 'hoge_fuga'
  3.  
  4. class TestController <ApplicationController
  5.   def hoge
  6.     a = Hoge.new
  7.     render(:text => a.hoge)
  8.   end
  9. end

んで、Webサーバを起動。

$ cd <rails_project>
$ ruby script/server

で、ブラウザからtest/hogeにアクセスすると、ブラウザ上にabcが出力されます。
この状況で、<rails_project>/lib/hoge_fuga.rbを以下のように書き換えてみます。

RUBY:
  1. class Hoge
  2.   def hoge
  3.     return "123"
  4.   end
  5. end

変更を保存した後、ブラウザからtest/hogeにアクセスすると、ブラウザ上に123が出力されます。
確かに、Webサーバを再起動しなくても、<rails_project>/lib/hoge_fuga.rbが再読み込みされてますね。

これでデバッグがしやすくなるなあ。

  1. Railsの場合、クラス定義と定義が記述されたファイルの名前が対応づいてないとautoloadで自動読み込みされません(たぶん)。例えば、FooBarというクラスの定義はfoo_bar.rbというファイルの中で行われてないとautoloadにされません。 []

Hyper Estraierで文書検索 (+ CentOS用rpm作成)

by ginriki | 12 月 7th, 2009 

扱う文章の数が膨大になって管理しづらくなってきたので、Hyper Estraierの導入を検討しました。せっかくなので導入手順をメモ。
ちなみに、自分のローカルマシン(Windows)内の文書を管理したいだけなら、Hyper Estraierをエンジンに積んだDesktopHEを使えば十分と思います。1

FedoraやVine LinuxだとEstraierのrpmパッケージが公式に存在するので、yumとかapt-getでインストールすればいいのですが、CentOSにはrpmパッケージがありません。

調べてみると、Vine Linuxのsrpmを使うと楽ということなので、srpmからrpmbuildします。2

まず、Vine LinuxのSRPMリポジトリからqdbm,mecab,mecab-ipadic,hyperestraierをダウンロードします。
その後、以下のようにrpmbuild & install (rpmbuildなどは、yum install rpm-buildなどで入れておくこと)。

# rpmbuild --rebuild qdbm-1.8.77-1vl5.src.rpm
# rpm -ivh /usr/src/redhat/RPMS/[arch]/qdbm-1.8.77-1.i386.rpm qdbm-devel-1.8.77-1.i386.rpm

# rpmbuild --rebuild mecab-0.97-2vl5.src.rpm
# rpm -ivh /usr/src/redhat/RPMS/[arch]/mecab-0.97-2.i386.rpm mecab-devel-0.97-2.i386.rpm

# rpmbuild --rebuild mecab-ipadic-2.7.0.20070801-1vl5.src.rpm
# rpm -ivh /usr/src/redhat/RPMS/[arch]/mecab-ipadic-2.7.0.20070801-1.i386.rpm

# rpmbuild --rebuild hyperestraier-1.4.13-2vl5.src.rpm
# rpm -ivh /usr/src/redhat/RPMS/[arch]/hyperestraier-1.4.13-2.i386.rpm hyperestraier-perl-1.4.13-2.i386.rpm

これでインストールは完了。

インデックスの作成方法は以下ページ参照。

/home/user/doc以下の文書をインデックス化して、/var/estraier/indexにインデックス作成する場合のコマンド例は以下。

$ estcmd gather -il ja -sd /var/estraier/index /home/user/doc

後は、検索用のWebページを用意すれば終わり。CentOSの場合は以下の通り。

# yum install httpd
# service httpd start
# cp /usr/libexec/estseek.cgi /var/www/cgi-bin/.
# /usr/share/hyperestraier/estseek.* /var/www/cgi-bin/.

上記を実行した後、/var/www/cgi-bin/estseek.confのindexnameの項目を編集します。

indexname: /var/estraier/index
...省略

手元のブラウザから、estseek.cgiへアクセスすると検索ページが見れます。
もしこの時、「Error: the index is missing or broken.」とか出てくるようなら、indexファイルへのアクセス権がapacheにないせいかもしれません。
estseek.conf内の項目の意味は、Hyper Estraierのユーザマニュアルを参照してください。

  1. でも、index作成がなんか遅い気がする。まあ、気のせいかも []
  2. だれかCentOS用hyperestraierのyumリポジトリ作ってくれませんか?(他力本願) []

rubyプロセスのコアファイルからバックトレースする。(おまけ: python)

by ginriki | 11 月 9th, 2009 

某所で、「rubyプロセスがSEGVとかした時のコアファイルから、rubyスクリプトのバックトレースは取れるの?」って聞かれたので、ちょっと調べてみました。

結論としては、「rubyメソッドの呼び出し位置(ファイル名, 行番号)は取れるけど、呼び出し時の実引数を見るのは難しい」っていう感じです。
rubyのスタックフレームは、当然、rubyプロセスのメモリ上に構築されるので、スタックフレームのデータ構造さえわかれば、ある程度は表示できます。

ただ、コアファイルを出力したrubyプロセスはすでに存在しないので、ruby実装に使われているC関数をデバッガで(正確にはrubyプロセス上で)実行することができません。
そのため、オブジェクトのinspectなどを実行することが難しく、実引数のオブジェクトが何か調べることが困難です。ということで、今回はスタックフレームを表示させる方法を以下で説明します。

rubyスタックフレームを表示するGDBスクリプトは以下になります(rb_dump.gdb)。
(moriyoshiさんのブログ「 GDBで実行中のスクリプト言語のスタックフレームをダンプしてみる試み」のコードをほとんどそのまま使わせていただきました。ありがとうございます。)

CODE:
  1. define dump_rb_bt_from_core
  2.   set $t = ruby_frame
  3.   while $t
  4.     printf "[0x%08x] ", $t
  5.     if $t->node.nd_file
  6.       printf "(%s:%d)\n", $t->node.nd_file, ($t->node.flags>> 19) & ((1 <<(sizeof(NODE*) * 8 - 19)) - 1)
  7.     else
  8.       printf "(UNKNOWN)\n"
  9.     end
  10.     set $t = $t->prev
  11.   end
  12. end
  13.  
  14. document dump_rb_bt_from_core
  15.   dumps the current frame stack from core file. usage: dump_rb_bt_from_core
  16. end

今回はサンプルプログラムとして、0アドレスにアクセスするC拡張ライブラリを実行するrubyスクリプトを用意します。
まず、C拡張ライブラリ(segv.c)、

C:
  1. #include "ruby.h"
  2.  
  3. VALUE do_segv(VALUE self){
  4.         *(char*)(0x0) = 0;
  5.         return Qnil;
  6. }
  7.  
  8. void Init_segv(){
  9.         VALUE module;
  10.         module = rb_define_module("Segv");
  11.         rb_define_module_function(module, "do_segv", &do_segv, 0);
  12. }

で、後は適当にextconf.rbを作って、segv.soを作ります。

次にsegv.soを呼び出すRubyスクリプト(test.rb)。

RUBY:
  1. require 'segv'
  2.  
  3. def test1(a)
  4.   test2(a)
  5. end
  6.  
  7. def test2(b)
  8.   Segv::do_segv
  9. end
  10.  
  11. test1(1)

さて、サンプルプログラムの用意ができたので、SEGVさせてみます。

$ ulimit -c unlimited
$ ruby test.rb
test.rb:8: [BUG] Segmentation fault
ruby 1.8.5 (2006-08-25) [i386-linux]

アボートしました (core dumped)

これでコアファイルが出力されたので、それをGDBで解析します。

今回はCentOS 5.3のyumでインストールしたrubyから出力されたコアファイルなので、
GDBで解析するには、ここからrubyのdebuginfoをインストールしておく必要があります。

$ wget http://debuginfo.centos.org/5/i386/ruby-debuginfo-1.8.5-5.el5_3.7.i386.rpm
# rpm -i ruby-debuginfo-1.8.5-5.el5_3.7.i386.rpm

それでは、GDBでコアファイルからrubyのバックトレースをさせてみます。

$ gdb ruby core.29443
GNU gdb Fedora (6.8-37.el5)
...
(gdb) backtrace   #通常のC関数レベルのバックトレース。
#0  0x00b3a402 in __kernel_vsyscall ()
#1  0x0056fdf0 in raise () from /lib/libc.so.6
#2  0x00571701 in abort () from /lib/libc.so.6
#3  0x00c514c2 in rb_bug (fmt=) at error.c:214
#4  0x00cbd80b in sigsegv (sig=) at signal.c:537
#5  [signal handler called]
#6  do_segv (self=3086662140) at segv.c:4
#7  0x00c54dd5 in call_cfunc (...) at eval.c:5657
#8  0x00c5c4ab in rb_call0 (...) at eval.c:5810

(gdb) source rb_dump.gdb      #この記事の最初に作ったGDBスクリプトをロード
(gdb) dump_rb_bt_from_core  # rubyバックトレース
[0xbfc1da20] (test.rb:8)
[0xbfc1e0e0] (test.rb:4)
[0xbfc1e7c0] (test.rb:11)
[0x00d0f960] Cannot access memory at address 0x4

以上になります。

pythonもコアファイルからスタックフレームが取れるか調べてみましたが、
DebuggingWithGDBのgdbinitスクリプトを読む限り、
rubyと同様に実行していたpythonスクリプトのファイル名と行番号は取れそうです。

CentOS 5にAspire Timeline (3810T)の有線LANドライバを入れる

by ginriki | 11 月 4th, 2009 

今年(2009年)の夏に、Aspire Timeline(3810T)を買いました。
元々Windows Vistaが入っていましたが、ついでにCentOS 5.31を入れてデュアルブートできるようにしました。

ただ、CentOS 5.3には (たぶん、CentOS 5.4にも) Aspire Timelineの有線LANドライバが入ってないので、ドライバを探してきて入れました。

ドライバは、http://partner.atheros.com/Drivers.aspxのAR81Family Linux Driverになります。私がダウンロードしたときは、AR81Family-linux-v1.0.0.10.tar.gzっていうバージョンでした。

いつの間にか、リンク切れになってました(partner.atheros.comのサイト自体なくなったようです)。12/2時点では、ドライバはここにあります。(katty9015さん、情報ありがとうございます)
ファイル名もAR81Family-linux-v1.0.0.10.tar.gzからAR81Family-linux-v1.0.1.0.tar.gzに変わったので、以下の記事を読むときは注意してください。

USBメモリとかでAspire TimelineのCentOS上にAR81Family-linux-v1.0.0.10.tar.gzを入れた後は、以下のようにコンパイル/インストールすれば、有線LANが使えるようになります。

$ tar xzvf AR81Family-linux-v1.0.0.10.tar
$ cd src/
$ make
$ make install       # 要root権限
$ reboot             # 再起動


おまけ (Intel VTの有効化)

Aspire Timeline(3810T)のCPUはIntel VTに対応してるのですが、BIOSで有効化できないため、そのままだとIntel VTが使えません。
とはいえ、CentOSのXenでWindowsが起動できないのも味気ないです。
以下の2つのリンク先を参考にいじれば、BIOSでIntel VTを有効にできます。Acerのサポート外になってしまうので、いじるときは自己責任でお願いします。

  1. 2009/10に、CentOS 5.4がリリースされましたね []

GPSログと撮影時刻を元に移動経路と写真をGoogle mapへ表示

by ginriki | 7 月 20th, 2009 

半年ほど前に、ハンディGPSのGarmin Oregon 300を買いました1
私の主な用途は旅行などの移動経路を記録することですが、地図情報をちゃんと入れておけば道に迷った時も重宝します。

今回は記録した移動経路と移動経路上で撮った写真をgoogle mapに表示する方法について説明します。
・・・といっても、フリーソフトの轍 Wadachiを使えば簡単に表示できます2

基本的な使い方は上のリンク先の「標準的な作業の流れ」を見てもらえればよいです。

ロンドン旅行したときの移動経路ログと写真を轍で編集してGoogle mapで表示したものを下記に貼りました3。移動経路は日付ごとに色分けしてあります。

轍以外の移動経路ログ編集ツールとして使えるソフトとして下記があります。

個人的には、轍が一番使いやすいです。たぶん、写真の縮小画像を自動生成してWaypointとしてgoogle mapで表示する機能があるからだと思います。

この記事の残りで、轍のサイトに載っていない下記作業手順について書きます。

  • 移動経路ログファイルから一部のログを消す。
  • HTMLファイルを使わず、kmlのみでgoogle mapを表示する。上のgoogle mapはkmlのみを使用してます。

Oregon 300は、移動経路のログをGPX形式で保存します4。下記説明もGPX形式のログデータが対象です。まあ、他の形式でも同じだと思います。


移動経路ログファイルから一部のログを消す

ログファイル内の、ある地点のログからGoogle mapで表示したい場合などにこの作業が必要です。
表示を開始したい地点の時刻を調べるためにGoogle Earthを使い、その後、開始地点前のログデータを削除するためにGPSbabelを使いますGPXファイルはXMLで書かれてるので、テキストエディタで手作業で消してもいいですが、GPSBabelの方が楽だと思います。GPX以外のファイル形式にも対応してるし。
Google Earthを使う利点は、下記2点です。

  • 地図を表示しながら開始地点を探せる。
  • GPXファイルのtrkpt表示数に制限がないっぽい。Google mapだと、trkptやwptなど合わせて1000件(100件だったかな?規約に書いてある?)しか表示できませんが、Google Earthには制限がないようです。

一部ログを消す手順は下記の通りです。

  1. Google Earthを起動
  2. Google EarthのウインドウにGPXファイルをドラッグ&ドロップ
  3. 「トラック ポイントとルート ポイントにクリック可能なイメージを作成する」にチェックを付けてインポート。チェックしないと、各地点の時刻を調べることができません。
  4. 起点となるトラックポイントを探してクリック。すると下記ポップアップが出てくると思います。ここのtimeの値を後で使います。もうGoogle Earthは閉じてよいです。

popup

  1. GPSBabelのgui版を起動。InputとしてGPXファイルを指定し、Outputのファイル名は好きなのを付ける。FormatはInput, Outputともに「GPX XML (.gpx)」です。設定例は下記画像の通り。

gpsbabel

  1. Filterボタンを押して、Google Earthで調べた時刻をTracksのStart atに設定する。設定例は下記画像。

  1. 「let's go」ボタンをクリックして変換すれば終了。後は、変換したGPXファイルを轍で読み込んで作業すればよいです。ちなみにコマンドラインでgpsbabelを実行する場合は下記のようにすればよい。
gpsbabel.exe -p "" -w -r -t -i gpx -f "MAR-17-09 062255 AM.gpx" -x track,start=20090316153053 -o gpx -F "MAR-17-09_in_london_test.gpx"


HTMLファイルを使わず、kmlのみでgoogle mapを表示する。

基本的には、轍で編集したデータをKMLでエクスポートして、KMLと轍が生成した縮小画像をWebサーバにアップロードすればよいです。
ただし、kml内の縮小画像への相対パスをフルパス(例: http://www.ginriki.net/~)にする必要があります。
適当に、テキストエディタなどで置換してください。私は下記のようにsedでやりました。

$ sed 's/tour_images\//http:\/\/www.ginriki.net\/wd\/wp-content\/uploads\/maps\/tour_images\//g' tour.kml  > tour2.kml

あとは、アップロードしたkmlのURLをgoogle mapの検索欄に入れれば、kmlがgoogle mapで表示されます。
google map右端の「リンク」というリンクをクリックすれば、ブログ埋め込み用htmlタグが下記のように表示されるので、それをブログに貼りつければよいです。


  1. 日本語版は高いので、英語版をYahooオークションで45,000円程度で買いました。Amazon.comが使えればもっと安く買えたのですが、日本から電気機器類を注文できないようです。 []
  2. はWindows専用ソフトのようです。MacやLinuxの人はごめんなさい。 []
  3. 表示時刻が日本時間になっているので注意。ロンドン時間では-9時間してください。 []
  4. Oregon 300の設定にもよりますが、通常、10秒ごとに現在位置をtrkタグとして書き込むようになっています。 []

ハンドルネームをginrikiに変えました

by ginriki | 7 月 20th, 2009 

そういえば、書くのを忘れてましたがハンドルネームをginriki(「じんりき」と読みます)に変更しました。
大学院を出て働き始めたので、それに合わせてハンドルネームも変えました。

ginrikiの由来は、書く気が起きたら書きます。大した話ではないです。

kprobes – カーネルへ動的にプローブ挿入

by ginriki | 7 月 13th, 2009 

Debug Hacksを読んでたら、kprobesっていうデバッグツールの話があった。
自分でモジュール作ってinsmodするだけで、カーネル再コンパイルなしで、ある実行地点でのカーネル内変数を調べるツールだそうで。

プロセスのユーザ空間(=デバッギのユーザ空間)に対してデバッガプロセスがプローブする場合は1

  1. デバッガプロセスがptrace辺りを使ってデバッギのメモリ空間上の指定アドレス上にあるアセンブリ命令をint 3に書き変えて2
  2. デバッギプロセス実行中にそのint 3命令実行して発生したSIGTRAPをデバッガプロセスがフック(=これも事前にptraceで設定する)して
  3. デバッガプロセスがptraceでデバッギプロセスのメモリ空間から値をread

っていう流れが普通だと思う。kprobes.cのコメントを見てみると、kprobesの場合もカーネルの指定命令アドレスにint 3を入れてるらしい。

/*
 * Called after single-stepping.  p->addr is the address of the
 * instruction whose first byte has been replaced by the "int 3"
 * instruction.  To avoid the SMP problems that can occur when we
 * temporarily put back the original opcode to single-step, we
 * single-stepped a copy of the instruction.  The address of this
 * copy is p->ainsn.insn. ...
 * ...
 */

ただ、SMPの関係で色々対策が必要なんだね3。int 3を実行した後、例外ベクタにジャンプしてからどういう手順で処理してるかについてイメージがわかないから、今度ソース読んでみようかな。

あと、kprobesだと見たい変数(とくにローカル変数などCPUアーキテクチャとデバッグ情報からアドレスを割り出す必要のあるもの)のアドレスを探すのが大変だけど、
kprobes+GDBでそこを解決しようとしてるのがtracepointsってやつらしい。ふむふむ。

  1. 以前、デバッガについて書いた記事もどうぞ。 []
  2. int 3はIA-32とかIntel architectureの場合の話です []
  3. デバッギプロセスにプローブする場合に必要なマルチスレッド対策とどの程度一緒なのかは、まだよくわからない。 []

crashコマンド使ってみた

by ginriki | 7 月 13th, 2009 

Kernelのコアダンプファイルを解析するのに、crashコマンドが便利だという話を聞いたので、練習として触ってみました。

手元にCentOS 5のマシンがあるので、それを使います。

解析にあたってkernelのデバッグ情報がいるので、debuginfoのRPMをインストールします1

 $ uname -a
Linux localhost.localdomain 2.6.18-128.1.16.el5 #1 SMP Tue Jun 30 06:10:28 EDT 2009 i686 i686 i386 GNU/Linux

 $ wget http://debuginfo.centos.org/5/i386/kernel-debuginfo-2.6.18-128.1.16.el5.i686.rpm
 $ wget http://debuginfo.centos.org/5/i386/kernel-debuginfo-common-2.6.18-128.1.16.el5.i686.rpm
 $ rpm -ivh kernel-debuginfo-common-2.6.18-128.1.16.el5.i686.rpm kernel-debuginfo-2.6.18-128.1.16.el5.i686.rpm

んで、crashコマンド実行。
SVR4 UNIXのcrashコマンドをベースにGDBを統合したやつだそうで2、GDBになじんでる私には結構使いやすいです。

CODE:
  1. $ crash
  2.       KERNEL: /usr/lib/debug/lib/modules/2.6.18-128.1.16.el5/vmlinux
  3.     DUMPFILE: /dev/crash
  4.         CPUS: 1
  5.         DATE: Mon Jul 13 02:17:05 2009
  6.       UPTIME: 06:52:42
  7. LOAD AVERAGE: 0.16, 0.03, 0.01
  8.        TASKS: 86
  9.     NODENAME: localhost.localdomain
  10.      RELEASE: 2.6.18-128.1.16.el5
  11.      VERSION: #1 SMP Tue Jun 30 06:10:28 EDT 2009
  12.      MACHINE: i686  (1197 Mhz)
  13.       MEMORY: 758.9 MB
  14.          PID: 3848
  15.      COMMAND: "crash"
  16.         TASK: ef67c000  [THREAD_INFO: d9120000]
  17.          CPU: 0
  18.        STATE: TASK_RUNNING (ACTIVE)
  19.  crash> set 1
  20.     PID: 1
  21. COMMAND: "init"
  22.    TASK: c16f5aa0  [THREAD_INFO: c16f6000]
  23.     CPU: 0
  24.   STATE: TASK_INTERRUPTIBLE
  25.  crash> p $tmp = jiffies
  26.   $1 = 24873000
  27.  crash> x modprobe_path
  28.   0xc0680be0 <modprobe_path>:     das
  29.  crash> show convenience
  30.    $tmp = 24873000
  31.    $__ = void
  32.    $_ = (examine_i_type *) 0xc0680be0 "/sbin/modprobe"
  33.  crash> exit

gdbスクリプトをsourceで読み込むこともできる。
まだ、まともな使い方は全然してないけど、Debug Hacksにいろいろ書いてあるので、それを読みながらやる予定。

Debug Hacks -デバッグを極めるテクニック&ツール Debug Hacks -デバッグを極めるテクニック&ツール
レビューを見る (3)
欲しいものリストに追加
価格:3360円 在庫あり。powered by Amazon.co.jp

  1. 最初、yumでinstallしたら、なぜか2.6.18-92.1.6.el5.centos.plusが入りました。kernelバージョンと合ってないので、rpmコマンドで入れなおし。 []
  2. Crash WhitepaperのAbstract参照 []

e-mobile接続時に割り当てられるIPアドレス範囲

by ginriki | 1 月 1st, 2009 

諸事情により、e-mobileのデータ通信カードが手元にあります。
データ通信カードを使ってインターネットに接続する際に割り当てられるIPは、接続毎に変化します。
この割り当てられるIPアドレスの範囲が気になったので調べてみることにしました。

これは、whoisサーバを使えば調べられます1

#とりあえず、接続した際に割り当てられたIPアドレス(114.48.45.211)で調べる
$ whois -h whois.apnic.net 114.48.45.211
% [whois.apnic.net node-2]
% Whois data copyright terms    http://www.apnic.net/db/dbcopyright.html

inetnum:      114.48.0.0 - 114.51.255.255
netname:      eMobile
...<略>

#netnameがわかったので、その名前で調べ直す
$ whois -h whois.apnic.net eMobile
% [whois.apnic.net node-2]
% Whois data copyright terms    http://www.apnic.net/db/dbcopyright.html

inetnum:      60.254.192.0 - 60.254.255.255
netname:      eMobile
...<略>

inetnum:      117.55.0.0 - 117.55.127.255
netname:      eMobile
...<略>

inetnum:      119.72.0.0 - 119.72.255.255
netname:      eMobile
...<略>

inetnum:      119.72.0.0 - 119.72.255.255
netname:      eMobile
...<略>

なお、inetnumやnetnameの仕様はこちらで規定されてます。

whoisプロトコルに関するメモ

whoisプロトコルの仕様は、RFC3912で規定されています。whoisサーバはTCP 43番ポートでListenするとか、データの区切りが<CR><LF>であることがRFC3912によって決められています。

RFC3912にはwhoisサーバとの通信例として下記が載っています。

clientがwhoisサーバ(whois.nic.mil)にSmithについて問い合わせた場合の通信例。

   client                           server at whois.nic.mil

   open TCP   ---- (SYN) ------------------------------>
              <---- (SYN+ACK) -------------------------
   send query ---- "Smith" -------------------->
   get answer <---- "Info about Smith" ---------
              <---- "More info about Smith" ----
   close      <---- (FIN) ------------------------------
              ----- (FIN) ----------------------------->

実際の所、RFC3912ではsend queryやget answerの部分でやりとりする情報について何も決められていません。

やり取りする情報はwhoisサーバによって変わります。
例えば、APNICのwhoisサーバの場合、各団体へ割り当てを行ったIPアドレス範囲の
問い合わせや応答に使われます。

APNICのwhoisサーバがどのような情報を返すかは下記リンク先を参照してください。
http://www.apnic.net/info/faq/apnic_faq/about_whois.html

なお、APNICの場合、IPアドレス範囲はinetnumという名称でしたが、
ARINのwhoisサーバの場合、NetRangeという名称になります。
http://www.felix-colibri.com/papers/web/whois/whois.html

このあたりは、各団体ごとに仕様がバラバラのようです。

  1. 判明したIPアドレスの範囲すべてがe-mobile接続時に割り当てられうるとは限りませんが []

ブログで紹介した商品

  • Image of デバッガの理論と実装 (ASCII SOFTWARE SCIENCE Language)