<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>ものぐさ備忘録</title>
	<atom:link href="http://www.ginriki.net/wd/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.ginriki.net/wd</link>
	<description>ソフトウェア関係の話を中心とした備忘録的日記</description>
	<lastBuildDate>Sun, 16 Jan 2011 20:07:53 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.5</generator>
	<language>ja</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>VPNサーバ(PPTPサーバ)付きのルータ設定・調査メモ</title>
		<link>http://www.ginriki.net/wd/2011/01/17/232/</link>
		<comments>http://www.ginriki.net/wd/2011/01/17/232/#comments</comments>
		<pubDate>Sun, 16 Jan 2011 19:43:00 +0000</pubDate>
		<dc:creator>ginriki</dc:creator>
				<category><![CDATA[PPTP]]></category>
		<category><![CDATA[VPN]]></category>

		<guid isPermaLink="false">http://www.ginriki.net/wd/?p=232</guid>
		<description><![CDATA[少し前に、ルータ(WZR-HP-AG300H)を買って自宅外からVPN接続してます。設定がWebブラウザから簡単にできますし、VPNサーバ用のマシンをルータと別に用意する必要もないので、結構便利です。
私の主な使い方は、 [...]]]></description>
			<content:encoded><![CDATA[<p>少し前に、ルータ(<a href="http://www.amazon.co.jp/BUFFALO-USB%E3%83%9D%E3%83%BC%E3%83%88%E6%90%AD%E8%BC%89-%E7%84%A1%E7%B7%9ALAN%E3%83%AB%E3%83%BC%E3%82%BF%E3%83%BC-AirStation-WZR-HP-AG300H/dp/B003RIU3XQ%3FSubscriptionId%3DAKIAJCPLMOWTU2MWO7FQ%26tag%3Dgikogeek-22%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3DB003RIU3XQ">WZR-HP-AG300H</a>)を買って自宅外からVPN接続してます。設定がWebブラウザから簡単にできますし、VPNサーバ用のマシンをルータと別に用意する必要もないので、結構便利です。</p>
<p>私の主な使い方は、</p>
<ul>
<li>Android端末からVPN接続し、<a href="http://jp.androlib.com/android.application.org-mult-daap-CzpF.aspx">DAAP Media Player</a>で自宅のメディアサーバー<sup>1</sup>の曲を聴く。</li>
<li>PCからVPN接続+Wake on Lan（WoL)<sup>2</sup>で、自宅サーバを立ち上げてログイン。</li>
</ul>
<p>の２つです。</p>
<p>せっかくなので、設定メモを残しておきます。<br/><br/></p>
<h1>VPNサーバ/クライアントの設定</h1>
<p><br/></p>
<p>このルータのVPNサーバの方式はPPTPです。設定手順はルータのマニュアルが詳しいです。</p>
<ul>
<li><a href="http://buffalo.jp/download/manual/html/air1200/">http://buffalo.jp/download/manual/html/air1200/</a></li>
</ul>
<p>ちなみに、私はDDNSにDynDNSを使ってます。</p>
<p>マニュアルに見当たらなかった注意点として、クライアント側のPCに付与されるIPがプライベートIPで、クライアント側ルータでNATが行われる場合は、クライアント側ルータのPPTP(VPN)パススルー/マルチパススルーを有効にしないと、PPTPサーバ・クライアント間で接続できない点があります。</p>
<p>最近のルータなら、たいていルータの設定項目で有効にできます。ルータによっては、GREパケットを通すようにNAT設定する必要があったりします。<sup>3</sup></p>
<p>ただ、パススルー設定ができない環境（公衆無線LANとか)から自宅マシンにつなぎたいときもあります。<br />
私の場合、Android端末から3G回線でVPN接続→WoL実施→マシン起動を行った上で、手元のPCから起動したマシンにsshログイン（とポートフォワーディング）で対応してます。</br></p>
<h1>ポート（サービス）チェック処理をtcpdumpして見る</h1>
<p><br/><br />
無事VPN接続したあと、http://<ルータのプライベートIP>/hosts.html にアクセスすると、<a href="http://buffalo.jp/download/manual/html/air1200/">WoLやhttpサーバなどのサービス一覧</a>が表示されます。</p>
<p>httpサーバが動いているかどうかのポートチェックが、どのタイミングで行われるのか気になったので、tcpdumpでLAN内を監視したところ、以下に対してチェックしているようです。。</p>
<ul>
<li>ブロードキャストやルータ宛てのARP Requestを送った送り元IP</li>
<li>ブロードキャストやルータ宛てのARP Replyを送った送り元IP</li>
</ul>
<p>用は、ルータに届いたARPの送り元IPに対して、ARPが届いた直後にポートチェックしているようです</p>
<p>以下は、あるマシン(desktop-ubuntu.local)がプロードキャストARP(Target IP:192.168.1.7)を送った時のtcpdump出力（をちょっと省略したもの）です。ルータ(192.168.1.1)がftpやwwwなどのポートをチェックしているのがわかります。</p>
<pre>
ethertype ARP (0x0806), length 42: Request who-has 192.168.1.7 (Broadcast) tell desktop-ubuntu.local
ethertype IPv4 (0x0800), length 74: 192.168.1.1.1584 > desktop-ubuntu.local.ftp
ethertype IPv4 (0x0800), length 74: 192.168.1.1.1183 > desktop-ubuntu.local.www
ethertype ARP (0x0806), length 60: Reply 192.168.1.7 is-at aa:bb:cc:cf:80:99
ethertype IPv4 (0x0800), length 74: 192.168.1.1.1943 > desktop-ubuntu.local.8000
ethertype IPv4 (0x0800), length 74: 192.168.1.1.3765 > desktop-ubuntu.local.http-alt
ethertype IPv4 (0x0800), length 74: 192.168.1.1.3896 > desktop-ubuntu.local.3389
ethertype IPv4 (0x0800), length 92: 192.168.1.1.1141 > desktop-ubuntu.local.netbios-ns: NBT UDP PACKET(137)
</pre>
<p>メモは、これで終わりです。<br />
VPN越しで自宅に溜めこんだ電子書籍を見るとかにも使えそうなので、色々試す価値がありそうです。</p>
<p>VPN越しで動画を見ようとしている方もいらっしゃいました。<sup>4</sup></p>
<ul>
<li><a href=http://www.geocities.jp/endlessmydesire/tver.html>http://www.geocities.jp/endlessmydesire/tver.html</a></li>
</ul>
<table class="amazonBanner amazonTable" summary="BUFFALO 節電+USBポート搭載 11n/a&amp;n/g対応 ハイパワー 無線LANルーター AirStation WZR-HP-AG300H">
	<tbody>
		<tr>
			<td rowspan="4" class="amazonImageTable"><a href="http://ecx.images-amazon.com/images/I/31oeItlsybL.jpg" title="BUFFALO 節電+USBポート搭載 11n/a&amp;n/g対応 ハイパワー 無線LANルーター AirStation WZR-HP-AG300H"><img src="http://ecx.images-amazon.com/images/I/31oeItlsybL._SL160_.jpg" alt="BUFFALO 節電+USBポート搭載 11n/a&amp;n/g対応 ハイパワー 無線LANルーター AirStation WZR-HP-AG300H" style="border:none ! important; width:100px;" /></a></td> 
			<td style="height:31px;" class="amazonName"><a href="http://www.amazon.co.jp/BUFFALO-USB%E3%83%9D%E3%83%BC%E3%83%88%E6%90%AD%E8%BC%89-%E7%84%A1%E7%B7%9ALAN%E3%83%AB%E3%83%BC%E3%82%BF%E3%83%BC-AirStation-WZR-HP-AG300H/dp/B003RIU3XQ%3FSubscriptionId%3DAKIAJCPLMOWTU2MWO7FQ%26tag%3Dgikogeek-22%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3DB003RIU3XQ" title="BUFFALO 節電+USBポート搭載 11n/a&amp;n/g対応 ハイパワー 無線LANルーター AirStation WZR-HP-AG300H">BUFFALO 節電+USBポート搭載 11n/a&amp;n/g対応 ハイパワー 無線LANルーター AirStation WZR-HP-AG300H</a></td>
		</tr>
		<tr>
			<td style="height:31px;"><a href="http://www.amazon.co.jp/review/product/B003RIU3XQ%3FSubscriptionId%3DAKIAJCPLMOWTU2MWO7FQ%26tag%3Dgikogeek-22%26linkCode%3Dxm2%26camp%3D2025%26creative%3D5143%26creativeASIN%3DB003RIU3XQ" title="BUFFALO 節電+USBポート搭載 11n/a&amp;n/g対応 ハイパワー 無線LANルーター AirStation WZR-HP-AG300H" class="bold">レビューを見る </a></td>
		</tr>
		<tr>
			<td style="height:31px;"><a href="http://www.amazon.co.jp/gp/registry/wishlist/add-item.html%3Fasin.0%3DB003RIU3XQ%26SubscriptionId%3DAKIAJCPLMOWTU2MWO7FQ%26tag%3Dgikogeek-22%26linkCode%3Dxm2%26camp%3D2025%26creative%3D5143%26creativeASIN%3DB003RIU3XQ" title="BUFFALO 節電+USBポート搭載 11n/a&amp;n/g対応 ハイパワー 無線LANルーター AirStation WZR-HP-AG300H">欲しいものリストに追加</a></td>
		</tr>
		<tr>
			<td style="height:31px;"><span class="amazonPrice">価格:6980円 在庫あり。</span><span class="amazonCopy"><small>powered by <a href="http://www.amazon.co.jp/">Amazon.co.jp</a></small></span></td>
		</tr>
	</tbody>
</table>
<ol class="footnotes"><li id="footnote_0_232" class="footnote">WZR-HP-AG300H自体にメディアサーバ機能があります(別途USB HDD必須)。私は別のNASをメディアサーバにしてるのでよくわかりません。</li><li id="footnote_1_232" class="footnote">WoLもWebブラウザからボタン一つで実施できます。なお、WoLを使う場合、起動対象マシンのBIOS設定などでWoL(Lan Bootとも言う)を有効にする必要があります。</li><li id="footnote_2_232" class="footnote">GREパケットを通す＝PPTPパススルー有効という理解で良いはず。マルチパススルーする場合は、もっと細かい処理が行われます。詳しく知りたい人は、以下ページの第4回 「PPTPを使用したリモートアクセスVPNの仕組み」を見てください。<a href="http://www.tatsuyababa.com/NW-VPN/">http://www.tatsuyababa.com/NW-VPN/</a></li><li id="footnote_3_232" class="footnote">私の場合、slingboxでネット越しにテレビを見る環境を構築済みなので、それで満足してます。<br />
</li></ol>]]></content:encoded>
			<wfw:commentRss>http://www.ginriki.net/wd/2011/01/17/232/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>NetBeans on windowsでLinux上のrubyプログラムをリモートデバッグするためのproxy</title>
		<link>http://www.ginriki.net/wd/2010/09/27/204/</link>
		<comments>http://www.ginriki.net/wd/2010/09/27/204/#comments</comments>
		<pubDate>Sun, 26 Sep 2010 21:38:37 +0000</pubDate>
		<dc:creator>ginriki</dc:creator>
				<category><![CDATA[NetBeans]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[debugger]]></category>

		<guid isPermaLink="false">http://www.ginriki.net/wd/?p=204</guid>
		<description><![CDATA[NetBeansのリモートデバッグについて、以前の記事で、以下のように書きましたが、
注意点としては、リモートと同じフルパス上にソースコードを置く必要がある点です。リモート先で、/var/www/railsprjにRoR [...]]]></description>
			<content:encoded><![CDATA[<p>NetBeansのリモートデバッグについて、<a href="http://www.ginriki.net/wd/2010/07/12/172/">以前の記事</a>で、以下のように書きましたが、</p>
<blockquote><p>注意点としては、リモートと同じフルパス上にソースコードを置く必要がある点です。リモート先で、/var/www/railsprjにRoRのプロジェクトコードが置いてあるなら、ローカルでも/var/www/railsprjにプロジェクトコードを置く必要があります。</p></blockquote>
<p>このままだと、Windows上のNetBeansでLinux上のRailsがリモートデバッグできません。<br />
そこで、NetBeansとFast Debugger(ruby-debug-ide)の間に挟むproxyを用意して、proxyの中でファイルパス変換することでリモートデバッグできるようにしました。<sup>1</sup></p>
<p>せっかくなので、以下にproxyのソースコードを置いておきます(MIT Licenseにしときました)。</p>
<ul>
<li><a href="http://www.ginriki.net/wd/wp-content/uploads/src/ruby-debug-ide-proxy.rb">ruby-debug-ide-proxy.rb</a></li>
</ul>
<p>以下の構成で、基本的な機能(変数チェック、ステップ実行、breakpointセット辺り)が動作するのは確認しました。<br />
Railsがデバッグできるかどうかは、まだ試してません。</p>
<pre>
[NetBeans (Debuger GUI)] on Windows
  ↓↑
[proxy] on Windows/Linux
  ↓↑
[ruby process (+ruby-debug-ide)]  on Linux

・CRuby 1.8.7 および JRuby 1.5.1でproxy動作確認した。
</pre>
<p>なお、実際にデバッグするときは、NetBeansが動くマシン上にもデバッグ対象のソースコードを置かないとソースコードデバッグできません。<br />
例えば、ソースコードは以下のように配置します。</p>
<pre>
・ruby-debug-ide側
/home/user/script
|---test.rb
\---lib
      \---somelib.rb

・NetBeans側
C:\win_script
|---test.rb
\---lib
      \---somelib.rb
</pre>
<p><BR/></p>
<h1>proxyを使ったデバッグの仕方</h1>
<p><BR/></p>
<p>以下の手順でproxyの起動やNetBeansからproxyへの接続を行えば、後は普通にデバッグできます。</p>
<ol>
<li>ruby-debug-ide付きでRuby process起動(<a href="http://www.ginriki.net/wd/2010/07/12/172/">以前の記事参照</a>)</li>
<li>proxy起動（Linux上で起動するか、NetBeans on Windows上で起動するかはお好みで)。</li>
<li>NetBeansでproxyへの接続。</li>
</ol>
<p>1, 2の手順はどちらが先でもＯＫです。<br />
1は以前の記事と同じなので、2, 3の説明だけ書きます。</p>
<h3>2. proxy起動 </h3>
<p>proxyスクリプトをオプション指定して起動するだけです。proxyスクリプトのオプションは以下の通り。</p>
<pre>
Usage: ruby-debug-ide-proxy.rb -t <rdb_host> [-p listen_port] [--rdbprefix prefix] [--ideprefix prefix] [-d]

Example: ruby-debug-ide-proxy.rb -t localhost --rdbprefix "/home/user/script" --ideprefix "C:\\win_script" -d
</pre>
<p>Exampleの例を説明すると、</p>
<ul>
<li> localhostのruby-debug-ideに接続して(接続先portは1234。指定するときはlocalhost:6000のようにする。)、</li>
<li>proxyを経由してNetBeansにデバッグデータ(XML)を送るときは、/home/user/script &#8211;> C:\\win_script　への変換を行い、</li>
<li>proxyを経由してNetBeansからデバッグコマンド(breakpointセットなど)を指示するときは、C:\\win_script &#8211;> /home/user/scriptへの変換を行い、</li>
<li>proxy実行時は、DEBUGログを出力する</li>
</ul>
<p>という指定になります。</p>
<h3>3. NetBeansからproxyへの接続</h3>
<p>NetBeansのメニューから「デバッグ -> デバッガを接続」を選択し、proxyが動作するホスト名やポート番号を指定して接続してください。<br />
NetBeansからproxyに接続した時、proxyからruby-debug-ideへの接続が自動的に行われます。</p>
<p>正しくデバッガ接続できた場合、以下のようなログがproxyプログラムの端末に出力されます。</p>
<pre>
I, [2010-09-27T03:43:21.124000 #2240]  INFO -- : proxy will replace /home/user/script with C:\win_script
I, [2010-09-27T03:43:21.468000 #2240]  INFO -- : proxy listens on 0.0.0.0:7000
I, [2010-09-27T03:43:24.530000 #2240]  INFO -- : proxy connects to 192.168.1.7:1234
I, [2010-09-27T03:43:24.530000 #2240]  INFO -- : debug start
</pre>
<p>後は、普通にNetBeansのデバッガGUIが使えます。<br />
例えば、デバッガGUIからbreakpointをセットすると、以下のログがproxy端末上に出ます。(-dを指定して起動した場合のみ）</p>
<pre>
D, [2010-09-27T03:43:24.546000 #2240] DEBUG -- : (ide -> proxy) b C:\win_script\test.rb:5
D, [2010-09-27T03:43:24.546000 #2240] DEBUG -- : (proxy -> rdb) b /home/user/script/test.rb:5
D, [2010-09-27T03:43:24.562000 #2240] DEBUG -- : (rdb -> proxy) <breakpointAdded no="1" location="/home/user/script/test.rb:5"/>
D, [2010-09-27T03:43:24.624000 #2240] DEBUG -- : (proxy -> ide) <breakpointAdded no='1' location='C:/win_script/test.rb:5'/>
</pre>
<p>手順は以上です。</p>
<p>Ruby/Railsの場合、デバッガはプログラムの動作理解に使うものというのが私の認識です<sup>2</sup>。なので、Ruby/Rails全般に慣れていない人がデバッガ利用者だと思うので、手順はもう少し簡潔にしたいですが、そうするにはIDE内を修正するしかないかな・・・。</p>
<ol class="footnotes"><li id="footnote_0_204" class="footnote">本当は、NetBeansのIDE内部でファイルパス変換するように修正するべきだと思いますが、面倒だったのでproxyにしました。</li><li id="footnote_1_204" class="footnote">デバッグは、printfデバッグの方が効率がいいと思ってます。</li></ol>]]></content:encoded>
			<wfw:commentRss>http://www.ginriki.net/wd/2010/09/27/204/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>NetBeansからRuby on Rails(RoR)のリモートデバッグ</title>
		<link>http://www.ginriki.net/wd/2010/07/12/172/</link>
		<comments>http://www.ginriki.net/wd/2010/07/12/172/#comments</comments>
		<pubDate>Sun, 11 Jul 2010 15:39:07 +0000</pubDate>
		<dc:creator>ginriki</dc:creator>
				<category><![CDATA[NetBeans]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[debugger]]></category>
		<category><![CDATA[RoR]]></category>

		<guid isPermaLink="false">http://www.ginriki.net/wd/?p=172</guid>
		<description><![CDATA[NetBeansには、rubyのデバッガフロントエンドが同梱されています。
今回は、それを使ってRuby on Rails(以下RoR)のリモートデバッグをするためのメモです。
個人的には、RoRが動いてるマシンにssh [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://ja.netbeans.org/">NetBeans</a>には、rubyのデバッガフロントエンドが同梱されています。<br />
今回は、それを使ってRuby on Rails(以下RoR)のリモートデバッグをするためのメモです。</p>
<p>個人的には、RoRが動いてるマシンにsshでログインした後、emacsと<a href="http://www.freedom.ne.jp/toki/ruby.html">rubydb3x.el</a>を使う方がメリットがある<sup>1</sup>と思いますが、emacsの場合デバッガ用GUIはありません。GUIに慣れてる人はNetBeansの方が楽なので、そういう人向けにまとめます。</p>
<p>なお、NetBeansをインストールしたローカルマシンで、RoRも動かす場合のデバッグ方法は、<a href="http://wiki.netbeans.org/RubyDebugging">NetBeansのwiki</a>を参照してください。</p>
<p>まあ、ローカルマシン上でデバッグする場合も、リモートマシンと接続してデバッグする場合もやり方はほとんど変わりません。</p>
<p>どちらの場合も、デバッギプロセス（と同じプロセス上で動くruby-debug-ide)がTCP(デフォルトだと1234)をListenし、Netbeansからそこに接続してデバッグを開始します。Netbeansから接続するデバッギプロセスがlocalhostにいるか、リモート先のホストにいるかの違いしかないです。<br />
接続後、Netbeansからruby-debug-ideへbreakpointをしかける場所などを指示します。</p>
<p>デバッグ方法そのものは、ローカル・リモートともに一緒ですが、リモートのホストに対してローカルのNetBeansを接続してデバッグするには、リモート先のホストで以下の作業が必要です。</p>
<ol>
<li>rubyインストール (解説略)</li>
<li>RubyGemsインストール (解説略)</li>
<li>RoRインストール・プロジェクト作成 (解説略)</li>
<li>ruby-debug-ideインストール</li>
<li>リモート先のRoRプロジェクトのソースコードを、ローカルにも展開</li>
<li>ruby-debug-ide付きでRoRプロジェクトのWebサーバ起動</li>
</ol>
<p>4, 5, 6の手順は、あまりネット上で見かけないので順に解説します。</p>
<h3>ruby-debug-ideインストール</h3>
<p>Linuxだと、gemで簡単にインストールできます。(gcc, ruby-develをインストールしておけば。)<br />
Fedora8だと以下で終わりでした。</p>
<pre>
$ gem install ruby-debug
$ gem install ruby-debug-ide
</pre>
<p>Windows（のmswin版ruby）の場合、コンパイル環境の用意が面倒なので、コンパイル済みgemをダウンロードした上でインストールします。<sup>2</sup></p>
<pre>&gt; gem install -l linecache-0.43-mswin32.gem
&gt; gem install -l ruby-debug-base-0.10.3-mswin32.gem
&gt; del ruby-debug-base-0.10.3-mswin32.gem
&gt; gem install ruby-debug
&gt; gem install ruby-debug-ide -v 0.4.6</pre>
<p>コンパイル済みgem (linecache, ruby-debug-base)は以下２つのリンク先から<br />
それぞれダウンロードしてください。</p>
<ul>
<li><a href="http://rubyforge.org/frs/?group_id=5040&#038;release_id=22842">linecache</a></li>
<li><a href="http://rubyforge.org/frs/?group_id=1900&#038;release_id=28306">ruby-debug-base</a></li>
</ul>
<h3>リモート先のRoRプロジェクトのソースコードを、ローカルにも展開</h3>
<p>ローカルにもソースコードを置かないと、breakpointで止まった時にNetbeansにソースコードが読み込まれません。<br />
注意点としては、リモートと同じフルパス上にソースコードを置く必要がある点です。リモート先で、/var/www/railsprjにRoRのプロジェクトコードが置いてあるなら、ローカルでも/var/www/railsprjにプロジェクトコードを置く必要があります。<sup>3</sup></p>
<p>この辺の挙動理解には、<a href=http://wiki.netbeans.org/RubyDebugging#Checking_debugger_engine_functionality">NetBeans wikiのChecking debugger engine functionality</a>とか、<a href="http://debug-commons.rubyforge.org/protocol-spec.html">ruby-debug-ide protocol</a>とかを参考にして、実際にruby-debug-ideとtelnetで会話するといいです。</p>
<h3>ruby-debug-ide付きでRuby on RailsプロジェクトのWebサーバ起動</h3>
<p>以下な感じでRoR Webサーバ起動します。(-dも付けると、NetBeansとの通信時の処理が良く見えます。)</p>
<pre>
$ rdebug-ide --stop script/server -h 0.0.0.0
Fast Debugger (ruby-debug-ide 0.4.6) listens on 0.0.0.0:1234
</pre>
<h3>NetBeansからruby-debug-ideに接続</h3>
<p>NetBeans IDEのメニュー -> デバッグ -> 接続をクリックし、ダイアログにリモート先ホスト名とポート番号(1234)を指定して接続します。<br />
&#8211;stopを指定してあるので、RoRの処理先頭でstopするはずです。<br />
あとは、IDEからbreakpoint指定するなり、なんなり自由に操作します。<br />
watch変数として、paramsを追加しておくといい感じです。</p>
<ol class="footnotes"><li id="footnote_0_172" class="footnote">sshのポート(TCP 22)が開いてることは普通にありますが、デバッガ・デバッギ通信用のポートがfirewallで遮断されることは良くあります。</li><li id="footnote_1_172" class="footnote">最近だと、Visual C++は無料で手に入りますがmswin版rubyをコンパイルしたVisual C++と同じバージョンをインストールする必要しないと「MSC version unmatch」エラーが出てめんどくさいです。<a href="http://rubyforge.org/tracker/index.php?func=detail&#038;aid=16774&#038;group_id=1900&#038;atid=7436">http://rubyforge.org/tracker/index.php?func=detail&#038;aid=16774&#038;group_id=1900&#038;atid=7436</a></li><li id="footnote_2_172" class="footnote">WindowsとLinuxだとフルパスを一致させることが不可能なので、例えば、Windows上のNetBeansからLinux上のRoRがデバッグができないという点でかなりアレな仕様です。誰もやってないなら修正パッチ作るかな。</li></ol>]]></content:encoded>
			<wfw:commentRss>http://www.ginriki.net/wd/2010/07/12/172/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>バッチファイル作成ノウハウ</title>
		<link>http://www.ginriki.net/wd/2010/06/21/162/</link>
		<comments>http://www.ginriki.net/wd/2010/06/21/162/#comments</comments>
		<pubDate>Sun, 20 Jun 2010 18:32:26 +0000</pubDate>
		<dc:creator>ginriki</dc:creator>
				<category><![CDATA[Windows]]></category>
		<category><![CDATA[bat]]></category>

		<guid isPermaLink="false">http://www.ginriki.net/wd/?p=162</guid>
		<description><![CDATA[Windowsのバッチファイルを作る機会があったので、その時のノウハウメモ。
サービスの状態確認
サービスの起動・停止状態の出力させるには、sc.exe queryが使える。(ただし、Windows XP／Windows [...]]]></description>
			<content:encoded><![CDATA[<p>Windowsのバッチファイルを作る機会があったので、その時のノウハウメモ。</p>
<h3>サービスの状態確認</h3>
<p>サービスの起動・停止状態の出力させるには、sc.exe queryが使える。(ただし、Windows XP／Windows Server 2003以降)<br />
後は、findstr (Windows用のgrep)と合わせて使えばいい。</p>
<p>たとえば、タスクスケジューラが起動しているかどうかの確認バッチファイルを<br />
作ると以下の通り。</p>
<pre>@echo off

sc.exe query Schedule | findstr STATE | findstr RUNNING &gt; nul
if %ERRORLEVEL% == 1 echo Scheduler isn't running
if %ERRORLEVEL% == 0 echo Scheduler running</pre>
<p>実行結果（タスクスケジューラ起動時）は以下の通り。</p>
<pre>C:\&gt;service_check.bat
Scheduler running</pre>
<p>上のバッチファイルのコツは、</p>
<ul>
<li>無駄なecho表示を消すこと(@echo off)</li>
<li>findstrの出力をnull deviceに出力させること( &gt; nul)</li>
<li>findstrのマッチ結果を%ERRORLEVEL%で調べること</li>
</ul>
<p>ちなみに、nulというnull device名の歴史をたどると、古い順に、</p>
<p>PIP &gt; CP/M &gt; MS-DOS &gt; Windows</p>
<p>という流れで受け継がれてます。<sup>1</sup></p>
<h3>バッチファイル内の特殊記号</h3>
<p>バッチファイル上で、特殊記号として扱われるものがいくつかあります。<br />
例えば、括弧()が特殊記号です。このような記号を普通の文字として扱いたいときは、^を特殊記号の前に付ける必要があります。</p>
<p>例は以下の通り。</p>
<pre>
@echo off
if 1 == 1 (
  echo foo ^(bar^) baz
)
</pre>
<pre>
C:\>with_hat.bat
foo (bar) baz
</pre>
<p>ちなみに^を抜くと、if文の終端(=echoの終わり)がbarの直後と判断されてしまい、<br />
その後のbazをコマンドとみなして実行するためエラーになります。</p>
<pre>
C:\>no_hat.bat
baz の使い方が誤っています。
</pre>
<p>他の特殊記号については、<a href="http://wiki.livedoor.jp/niloufar/d/%A5%B3%A5%DE%A5%F3%A5%C9%A5%D7%A5%ED%A5%F3%A5%D7%A5%C8%A4%F2%BB%C8%A4%A6">このWiki</a>を参照してください。</p>
<ol class="footnotes"><li id="footnote_0_162" class="footnote">PIPの<a href="http://ja.wikipedia.org/wiki/Peripheral_Interchange_Program">Wikipediaページ</a>とか、MSDNの<a href="http://msdn.microsoft.com/en-us/library/Aa365247">予約ファイル名の説明</a>とか参照。</li></ol>]]></content:encoded>
			<wfw:commentRss>http://www.ginriki.net/wd/2010/06/21/162/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>色々なtarフォーマットの確認方法</title>
		<link>http://www.ginriki.net/wd/2010/06/14/136/</link>
		<comments>http://www.ginriki.net/wd/2010/06/14/136/#comments</comments>
		<pubDate>Sun, 13 Jun 2010 17:01:09 +0000</pubDate>
		<dc:creator>ginriki</dc:creator>
				<category><![CDATA[CentOS]]></category>
		<category><![CDATA[tar]]></category>

		<guid isPermaLink="false">http://www.ginriki.net/wd/?p=136</guid>
		<description><![CDATA[tarファイルには、いくつかのフォーマットがあるのだけど、何らかのコマンドで作成したtarファイルが
どのフォーマットで作られているか判断するやり方が見当たらないのでメモしとく。
なお、メジャーなフォーマットは以下]]></description>
			<content:encoded><![CDATA[<p>tarファイルには、いくつかのフォーマットがあるのだけど、何らかのコマンドで作成したtarファイルが<br />
どのフォーマットで作られているか判断するやり方が見当たらないのでメモしとく。</p>
<p>なお、メジャーなフォーマットは以下らしい<sup>1</sup>。</p>
<ul>
<li>POSIX.1-1988 ustar format</li>
<li>GNU tar format</li>
<li>POSIX.1-2001 pax format</li>
</ul>
<p>利用者から見たフォーマット間の大きな違いは、ustar形式のtarフォーマットの場合、tarでまとめる各ファイルのファイル名が256文字制限だったり、各ファイルのサイズ制限が8GBになってること。残りの２つのフォーマットは制限なし。その代わり、他と比べてustar形式は歴史がある形式なので、対応しているツールも多い。</p>
<p>ちなみに、普通のlinux上のtarプログラム(=GNU tar)がデフォルトで使うtarフォーマットは&#8211;helpを付ければわかる。<br />
以下のように、最近のtarプログラムならgnuフォーマットのはず。</p>
<pre>
# tar --help
[...略]
*This* tar defaults to:
--format=gnu -f- -b20 --quoting-style=escape --rmt-command=/sbin/rmt
</pre>
<p><br/></p>
<h1>・tarファイルのフォーマットの見分け方</h1>
<p>hexdumpコマンドでtarファイルを出力し、tarファイル内にアーカイブされた各ファイルのtarヘッダ（とpaxヘッダ)で見分けます。<sup>2</sup></p>
<p>hexdump -C <tar file>で出力された情報のなかで、<br />
それぞれのフォーマットごとに特徴的なヘッダ部分は以下。</p>
<ul>
<li>ustar format
<pre>
00000100  ...(省略)...  |.ustar.00root...|
</pre>
</li>
<li> GNU tar format
<pre>
00000100  ...(省略)...  |.ustar  .root...|
</pre>
</li>
<li>pax format
<pre>
00000000  ...(省略)...  |./PaxHeaders.108|
</pre>
</li>
</ul>
<p>以下、各フォーマットの確認例です。</p>
<pre>
# echo "hello" > foo.txt
# tar --format=gnu -cvf test.gnu.tar foo.txt
# tar --format=ustar -cvf test.ustar.tar foo.txt
# tar --format=pax -cvf test.pax.tar foo.txt

# hexdump -C test.ustar.tar
00000000  66 6f 6f 2e 74 78 74 00  00 00 00 00 00 00 00 00  |foo.txt.........|
00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00000060  00 00 00 00 30 30 30 30  36 34 34 00 30 30 30 30  |....0000644.0000|
00000070  30 30 30 00 30 30 30 30  30 30 30 00 30 30 30 30  |000.0000000.0000|
00000080  30 30 30 30 30 30 36 00  31 31 34 30 35 31 37 34  |0000006.11405174|
00000090  33 30 34 00 30 31 32 33  37 33 00 20 30 00 00 00  |304.012373. 0...|
000000a0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00000100  00 75 73 74 61 72 00 30  30 72 6f 6f 74 00 00 00  |.ustar.00root...|
00000110  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000120  00 00 00 00 00 00 00 00  00 72 6f 6f 74 00 00 00  |.........root...|
00000130  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000140  00 00 00 00 00 00 00 00  00 30 30 30 30 30 30 30  |.........0000000|
00000150  00 30 30 30 30 30 30 30  00 00 00 00 00 00 00 00  |.0000000........|
00000160  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00000200  68 65 6c 6c 6f 0a 00 00  00 00 00 00 00 00 00 00  |hello...........|
00000210  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00002800

# hexdump -C test.gnu.tar
00000000  66 6f 6f 2e 74 78 74 00  00 00 00 00 00 00 00 00  |foo.txt.........|
00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00000060  00 00 00 00 30 30 30 30  36 34 34 00 30 30 30 30  |....0000644.0000|
00000070  30 30 30 00 30 30 30 30  30 30 30 00 30 30 30 30  |000.0000000.0000|
00000080  30 30 30 30 30 30 36 00  31 31 34 30 35 31 37 34  |0000006.11405174|
00000090  33 30 34 00 30 31 31 30  37 33 00 20 30 00 00 00  |304.011073. 0...|
000000a0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00000100  00 75 73 74 61 72 20 20  00 72 6f 6f 74 00 00 00  |.ustar  .root...|
00000110  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000120  00 00 00 00 00 00 00 00  00 72 6f 6f 74 00 00 00  |.........root...|
00000130  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00000200  68 65 6c 6c 6f 0a 00 00  00 00 00 00 00 00 00 00  |hello...........|
00000210  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00002800

# hexdump -C test.pax.tar
00000000  2e 2f 50 61 78 48 65 61  64 65 72 73 2e 31 30 38  |./PaxHeaders.108|
00000010  31 2f 66 6f 6f 2e 74 78  74 00 00 00 00 00 00 00  |1/foo.txt.......|
00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00000060  00 00 00 00 30 30 30 30  36 34 34 00 30 30 30 30  |....0000644.0000|
00000070  30 30 30 00 30 30 30 30  30 30 30 00 30 30 30 30  |000.0000000.0000|
00000080  30 30 30 30 30 35 30 00  31 31 34 30 35 31 37 34  |0000050.11405174|
00000090  34 30 31 00 30 31 33 34  34 31 00 20 78 00 00 00  |401.013441. x...|
000000a0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00000100  00 75 73 74 61 72 00 30  30 00 00 00 00 00 00 00  |.ustar.00.......|
00000110  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00000140  00 00 00 00 00 00 00 00  00 30 30 30 30 30 30 30  |.........0000000|
00000150  00 30 30 30 30 30 30 30  00 00 00 00 00 00 00 00  |.0000000........|
00000160  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00000200  32 30 20 61 74 69 6d 65  3d 31 32 37 36 34 34 32  |20 atime=1276442|
00000210  38 37 30 0a 32 30 20 63  74 69 6d 65 3d 31 32 37  |870.20 ctime=127|
00000220  36 34 34 32 38 32 30 0a  00 00 00 00 00 00 00 00  |6442820.........|
00000230  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00000400  66 6f 6f 2e 74 78 74 00  00 00 00 00 00 00 00 00  |foo.txt.........|
00000410  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00000460  00 00 00 00 30 30 30 30  36 34 34 00 30 30 30 30  |....0000644.0000|
00000470  30 30 30 00 30 30 30 30  30 30 30 00 30 30 30 30  |000.0000000.0000|
00000480  30 30 30 30 30 30 36 00  31 31 34 30 35 31 37 34  |0000006.11405174|
00000490  33 30 34 00 30 31 32 33  37 33 00 20 30 00 00 00  |304.012373. 0...|
000004a0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00000500  00 75 73 74 61 72 00 30  30 72 6f 6f 74 00 00 00  |.ustar.00root...|
00000510  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000520  00 00 00 00 00 00 00 00  00 72 6f 6f 74 00 00 00  |.........root...|
00000530  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000540  00 00 00 00 00 00 00 00  00 30 30 30 30 30 30 30  |.........0000000|
00000550  00 30 30 30 30 30 30 30  00 00 00 00 00 00 00 00  |.0000000........|
00000560  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00000600  68 65 6c 6c 6f 0a 00 00  00 00 00 00 00 00 00 00  |hello...........|
00000610  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00002800
</pre>
<ol class="footnotes"><li id="footnote_0_136" class="footnote"><a href="http://pythonjp.sourceforge.jp/dev/library/tarfile.html">Pythonのtarfileライブラリのマニュアル</a>参照。</li><li id="footnote_1_136" class="footnote">ヘッダの概説は<a href=http://www.jp.freebsd.org/cgi/mroff.cgi?sect=5&#038;cmd=&#038;lc=1&#038;subdir=man&#038;dir=jpman-6.0.0/man&#038;subdir=man&#038;man=tar">FreeBSDのtarマニュアル</a>がわかりやすいです。もっと知りたい場合は各tar形式の仕様書を見た方が良いです。</li></ol>]]></content:encoded>
			<wfw:commentRss>http://www.ginriki.net/wd/2010/06/14/136/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ruby/Jrubyの実行時フックの低レベルAPI</title>
		<link>http://www.ginriki.net/wd/2010/04/08/129/</link>
		<comments>http://www.ginriki.net/wd/2010/04/08/129/#comments</comments>
		<pubDate>Wed, 07 Apr 2010 19:23:03 +0000</pubDate>
		<dc:creator>ginriki</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[ruby jruby]]></category>

		<guid isPermaLink="false">http://www.ginriki.net/wd/?p=129</guid>
		<description><![CDATA[メモ。
RubyやJRubyには、特定の条件(コード行が変化したとか、メソッドを呼び出したなど）を満たした時に呼び出されるフック処理を定義することができます。
Ruby-1.8の低レベルなフック追加API(=C言語API [...]]]></description>
			<content:encoded><![CDATA[<p>メモ。</p>
<p>RubyやJRubyには、特定の条件(コード行が変化したとか、メソッドを呼び出したなど）を満たした時に呼び出されるフック処理を定義することができます。</p>
<p>Ruby-1.8の低レベルなフック追加API(=C言語API)は、<br />
<a href="http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/thread.c?revision=27238&#038;view=markup">thread.c</a>のrb_add_event_hook関数。シグネチャは以下。</p>
<ul>
<li>
void rb_add_event_hook(rb_event_hook_func_t func, rb_event_flag_t events, VALUE data);
</li>
</ul>
<p>JRuby-1.4.0で上記関数にほぼ対応するのは、<a href="http://github.com/jruby/jruby/blob/master/src/org/jruby/Ruby.java">Ruby.java</a>の<br />
Ruby.addEventHookメソッド。シグネチャは以下。</p>
<ul>
<li>
public void addEventHook(EventHook hook)
</li>
</ul>
<p>引数の型であるEventHookやその継承クラスは以下参照。</p>
<ul>
<li>
public abstract class EventHook (<a href="http://github.com/jruby/jruby/blob/master/src/org/jruby/runtime/EventHook.java">runtime/EventHook.java</a>)
</li>
<li>
public class CallTraceFuncHook extends EventHook (<a href="http://github.com/jruby/jruby/blob/master/src/org/jruby/Ruby.java">Ruby.java</a>)
</li>
</ul>
<p>フックAPIの挙動についての仕様書って、どこにもない感じだなあ。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ginriki.net/wd/2010/04/08/129/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>JRuby実行中にjdbでアタッチしてrubyプログラムのbacktrace</title>
		<link>http://www.ginriki.net/wd/2010/01/12/114/</link>
		<comments>http://www.ginriki.net/wd/2010/01/12/114/#comments</comments>
		<pubDate>Mon, 11 Jan 2010 22:02:46 +0000</pubDate>
		<dc:creator>ginriki</dc:creator>
				<category><![CDATA[JDB]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[backtrace]]></category>
		<category><![CDATA[JRuby]]></category>

		<guid isPermaLink="false">http://www.ginriki.net/wd/?p=114</guid>
		<description><![CDATA[Ruby自身のデバッガだと、任意のタイミングでアタッチしてbacktrace見るといったことができない（はず）なので、もっと低レベルのデバッガを利用して、それを実現する方法についてメモ。今回はJRubyに対してjdbでア [...]]]></description>
			<content:encoded><![CDATA[<p>Ruby自身のデバッガだと、任意のタイミングでアタッチしてbacktrace見るといったことができない（はず）なので、もっと低レベルのデバッガを利用して、それを実現する方法についてメモ。今回はJRubyに対してjdbでアタッチ＆backtraceする方法についてのメモです。<br />
なお、CRubyの場合は、<a href="http://www.ginriki.net/wd/2009/11/09/80/">以前の記事</a>とか、さらにその先のリンク先を見れば良いです。<br />
ちなみに、今回試したJRubyのversionは以下の通り。OSはCentOS 5.3です。</p>
<pre>
$ 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]
</pre>
<p><br/></p>
<h2>jdbによるbacktrace</h2>
<p><br/><br />
まず、アタッチ対象例のRubyコードとして以下を用意。</p>
<p>sample.rb</p>
<div class="igBar"><span id="lruby-2"><a href="#" onclick="javascript:showPlainTxt('ruby-2'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">RUBY:</span>
<div id="ruby-2">
<div class="ruby">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#9966CC; font-weight:bold;">def</span> foo</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; <span style="color:#CC0066; font-weight:bold;">p</span> <span style="color:#996600;">"abc"</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; bar</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#9966CC; font-weight:bold;">end</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#9966CC; font-weight:bold;">def</span> bar</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; <span style="color:#CC0066; font-weight:bold;">p</span> <span style="color:#996600;">"foge"</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; <span style="color:#CC0066; font-weight:bold;">sleep</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006666;color:#800000;">1000</span><span style="color:#006600; font-weight:bold;">&#41;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#9966CC; font-weight:bold;">end</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">abc </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>そして、デバッガattach用のポートを開けて起動します<sup>1</sup>。</p>
<pre>
$ jruby -J-Xdebug -J-Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=n sample.rb
</pre>
<p>barメソッド内のsleepの実行をしているうちに、別のターミナルを開いてjdbでアタッチし、スレッドを停止させます。</p>
<pre>
$ jdb -attach 8000
> suspend
すべてのスレッドが中断されました
</pre>
<p>そして、backtraceを表示させます。以下の方法で大体表示できます(いい加減なやり方ですが)。</p>
<pre>
> 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" #１つ前のスタックフレーム
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"　#トップレベル
</pre>
<p>以上になります。</p>
<ol class="footnotes"><li id="footnote_0_114" class="footnote"><a href="http://wiki.github.com/datamapper/do/jruby">ここ</a>の「Debugger」の項目を参考にオプション設定しました。</li></ol>]]></content:encoded>
			<wfw:commentRss>http://www.ginriki.net/wd/2010/01/12/114/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>autoloadで自動読み込みされないファイルをユーザアクセス毎に再読み込みする</title>
		<link>http://www.ginriki.net/wd/2009/12/31/102/</link>
		<comments>http://www.ginriki.net/wd/2009/12/31/102/#comments</comments>
		<pubDate>Wed, 30 Dec 2009 15:35:07 +0000</pubDate>
		<dc:creator>ginriki</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://www.ginriki.net/wd/?p=102</guid>
		<description><![CDATA[今回はRuby on Railsについてメモ。
autoloadで自動読み込みされないファイル1をcontrollerの中などでrequireを使って読み込んだ場合、そのファイルはdevelopmentモード時でもユーザ [...]]]></description>
			<content:encoded><![CDATA[<p>今回はRuby on Railsについてメモ。</p>
<p>autoloadで自動読み込みされないファイル<sup>1</sup>をcontrollerの中などでrequireを使って読み込んだ場合、そのファイルはdevelopmentモード時でもユーザアクセス毎に再読み込みされません。そのため、ファイルを編集してもwebサーバを再起動しないと変更が反映されないので、デバッグがやりづらくて困ってました。</p>
<p>解決策がないかと思って、ググってみたところ、以下のページに解決策が書いてありました。<br />
<a href="http://www.pistolfly.jp/weblog/2007/06/require-dependency.html">http://www.pistolfly.jp/weblog/2007/06/require-dependency.html</a></p>
<p>requireじゃなくて、require_dependencyでファイル読み込みすれば良いということでした。<br />
require_dependencyの挙動については、上のリンク先を参照してください。<br />
この辺り(autoload周辺)って、Ruby on Rails公式なドキュメントが見当たらないですねえ。・・・実装を読めってことか。</p>
<p>以下、問題のコード例と解決方法。(ruby 1.8.5, rails 2.3.3, WEBrick 1.3.1で実験しました。)</p>
<p>ファイル読み込みの対象となるファイルを用意します。</p>
<p>&#060;rails_project&#062;/lib/hoge_fuga.rb</p>
<div class="igBar"><span id="lruby-6"><a href="#" onclick="javascript:showPlainTxt('ruby-6'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">RUBY:</span>
<div id="ruby-6">
<div class="ruby">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#9966CC; font-weight:bold;">class</span> Hoge</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; <span style="color:#9966CC; font-weight:bold;">def</span> hoge</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#0000FF; font-weight:bold;">return</span> <span style="color:#996600;">"abc"</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; <span style="color:#9966CC; font-weight:bold;">end</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#9966CC; font-weight:bold;">end</span> </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>上のファイルを読み込むcontrollerを用意します。<br />
このとき、requireの代わりにrequire_dependencyでファイルを読み込みます。</p>
<p>&#060;rails_project&#062;/app/controllers/test_controller.rb</p>
<div class="igBar"><span id="lruby-7"><a href="#" onclick="javascript:showPlainTxt('ruby-7'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">RUBY:</span>
<div id="ruby-7">
<div class="ruby">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#008000; font-style:italic;">#require 'hoge_fuga'</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">require_dependency 'hoge_fuga'</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#9966CC; font-weight:bold;">class</span> TestController &lt;ApplicationController</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; <span style="color:#9966CC; font-weight:bold;">def</span> hoge</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; a = Hoge.<span style="color:#9900CC;">new</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; render<span style="color:#006600; font-weight:bold;">&#40;</span>:text =&gt; a.<span style="color:#9900CC;">hoge</span><span style="color:#006600; font-weight:bold;">&#41;</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; <span style="color:#9966CC; font-weight:bold;">end</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#9966CC; font-weight:bold;">end</span> </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>んで、Webサーバを起動。</p>
<pre>
$ cd &#060;rails_project&#062;
$ ruby script/server
</pre>
<p>で、ブラウザからtest/hogeにアクセスすると、ブラウザ上にabcが出力されます。<br />
この状況で、&#060;rails_project&#062;/lib/hoge_fuga.rbを以下のように書き換えてみます。</p>
<div class="igBar"><span id="lruby-8"><a href="#" onclick="javascript:showPlainTxt('ruby-8'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">RUBY:</span>
<div id="ruby-8">
<div class="ruby">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#9966CC; font-weight:bold;">class</span> Hoge</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; <span style="color:#9966CC; font-weight:bold;">def</span> hoge</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#0000FF; font-weight:bold;">return</span> <span style="color:#996600;">"123"</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; <span style="color:#9966CC; font-weight:bold;">end</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#9966CC; font-weight:bold;">end</span> </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>変更を保存した後、ブラウザからtest/hogeにアクセスすると、ブラウザ上に123が出力されます。<br />
確かに、Webサーバを再起動しなくても、&#060;rails_project&#062;/lib/hoge_fuga.rbが再読み込みされてますね。</p>
<p>これでデバッグがしやすくなるなあ。</p>
<ol class="footnotes"><li id="footnote_0_102" class="footnote">Railsの場合、クラス定義と定義が記述されたファイルの名前が対応づいてないとautoloadで自動読み込みされません（たぶん）。例えば、FooBarというクラスの定義はfoo_bar.rbというファイルの中で行われてないとautoloadにされません。</li></ol>]]></content:encoded>
			<wfw:commentRss>http://www.ginriki.net/wd/2009/12/31/102/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Hyper Estraierで文書検索 (+ CentOS用rpm作成)</title>
		<link>http://www.ginriki.net/wd/2009/12/07/94/</link>
		<comments>http://www.ginriki.net/wd/2009/12/07/94/#comments</comments>
		<pubDate>Sun, 06 Dec 2009 20:55:42 +0000</pubDate>
		<dc:creator>ginriki</dc:creator>
				<category><![CDATA[CentOS]]></category>
		<category><![CDATA[Hyper Estraier]]></category>

		<guid isPermaLink="false">http://www.ginriki.net/wd/?p=94</guid>
		<description><![CDATA[扱う文章の数が膨大になって管理しづらくなってきたので、Hyper Estraierの導入を検討しました。せっかくなので導入手順をメモ。
ちなみに、自分のローカルマシン(Windows)内の文書を管理したいだけなら、Hyp [...]]]></description>
			<content:encoded><![CDATA[<p>扱う文章の数が膨大になって管理しづらくなってきたので、<a href="http://hyperestraier.sourceforge.net/index.ja.html">Hyper Estraier</a>の導入を検討しました。せっかくなので導入手順をメモ。<br />
ちなみに、自分のローカルマシン(Windows)内の文書を管理したいだけなら、Hyper Estraierをエンジンに積んだ<a href="http://freemind.s57.xrea.com/desktophe/">DesktopHE</a>を使えば十分と思います。<sup>1</sup></p>
<p>FedoraやVine LinuxだとEstraierのrpmパッケージが公式に存在するので、yumとかapt-getでインストールすればいいのですが、CentOSにはrpmパッケージがありません。</p>
<p>調べてみると、<a href="http://tel.cocolog-nifty.com/blog/2008/11/centos5hypere-1.html">Vine Linuxのsrpmを使うと楽</a>ということなので、srpmからrpmbuildします。<sup>2</sup></p>
<p>まず、<a href="http://www.ring.gr.jp/pub/linux/Vine/VineSeed/SRPMS.plus/">Vine LinuxのSRPMリポジトリ</a>からqdbm,mecab,mecab-ipadic,hyperestraierをダウンロードします。<br />
その後、以下のようにrpmbuild &#038; install (rpmbuildなどは、yum install rpm-buildなどで入れておくこと)。</p>
<pre>
# 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
</pre>
<p>これでインストールは完了。</p>
<p>インデックスの作成方法は以下ページ参照。</p>
<ul>
<li><a href="http://hyperestraier.sourceforge.net/intro-ja.html#deployment">ローカルマシンの特定のディレクトリ以下の文書をインデックス化する場合(estcmd gather)</a></li>
<li><a href="http://www.avant-tokyo.com/solaris/hyper_estraier_estwaver.html">Webサーバの文書をcrawlする場合 (estwaver)</a></li>
</ul>
<p>/home/user/doc以下の文書をインデックス化して、/var/estraier/indexにインデックス作成する場合のコマンド例は以下。</p>
<pre>
$ estcmd gather -il ja -sd /var/estraier/index /home/user/doc
</pre>
<p>後は、検索用のWebページを用意すれば終わり。CentOSの場合は以下の通り。</p>
<pre>
# yum install httpd
# service httpd start
# cp /usr/libexec/estseek.cgi /var/www/cgi-bin/.
# /usr/share/hyperestraier/estseek.* /var/www/cgi-bin/.
</pre>
<p>上記を実行した後、/var/www/cgi-bin/estseek.confのindexnameの項目を編集します。</p>
<pre>
indexname: /var/estraier/index
...省略
</pre>
<p>手元のブラウザから、estseek.cgiへアクセスすると検索ページが見れます。<br />
もしこの時、「Error: the index is missing or broken.」とか出てくるようなら、indexファイルへのアクセス権がapacheにないせいかもしれません。<br />
estseek.conf内の項目の意味は、<a href="http://hyperestraier.sourceforge.net/uguide-ja.html#estseek">Hyper Estraierのユーザマニュアル</a>を参照してください。</p>
<ol class="footnotes"><li id="footnote_0_94" class="footnote">でも、index作成がなんか遅い気がする。まあ、気のせいかも</li><li id="footnote_1_94" class="footnote">だれかCentOS用hyperestraierのyumリポジトリ作ってくれませんか？(他力本願)</li></ol>]]></content:encoded>
			<wfw:commentRss>http://www.ginriki.net/wd/2009/12/07/94/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>rubyプロセスのコアファイルからバックトレースする。（おまけ: python）</title>
		<link>http://www.ginriki.net/wd/2009/11/09/80/</link>
		<comments>http://www.ginriki.net/wd/2009/11/09/80/#comments</comments>
		<pubDate>Sun, 08 Nov 2009 22:00:34 +0000</pubDate>
		<dc:creator>ginriki</dc:creator>
				<category><![CDATA[FFI]]></category>
		<category><![CDATA[GDB]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[gdbscript]]></category>

		<guid isPermaLink="false">http://www.ginriki.net/wd/?p=80</guid>
		<description><![CDATA[某所で、「rubyプロセスがSEGVとかした時のコアファイルから、rubyスクリプトのバックトレースは取れるの？」って聞かれたので、ちょっと調べてみました。
結論としては、「rubyメソッドの呼び出し位置(ファイル名,  [...]]]></description>
			<content:encoded><![CDATA[<p>某所で、「rubyプロセスがSEGVとかした時のコアファイルから、rubyスクリプトのバックトレースは取れるの？」って聞かれたので、ちょっと調べてみました。</p>
<p>結論としては、「rubyメソッドの呼び出し位置(ファイル名, 行番号)は取れるけど、呼び出し時の実引数を見るのは難しい」っていう感じです。<br />
rubyのスタックフレームは、当然、rubyプロセスのメモリ上に構築されるので、スタックフレームのデータ構造さえわかれば、ある程度は表示できます。</p>
<p>ただ、コアファイルを出力したrubyプロセスはすでに存在しないので、ruby実装に使われているC関数をデバッガで（正確にはrubyプロセス上で）実行することができません。<br />
そのため、オブジェクトのinspectなどを実行することが難しく、実引数のオブジェクトが何か調べることが困難です。ということで、今回はスタックフレームを表示させる方法を以下で説明します。</p>
<p>rubyスタックフレームを表示するGDBスクリプトは以下になります(rb_dump.gdb)。<br />
(moriyoshiさんのブログ「<a href="http://d.hatena.ne.jp/moriyoshi/20070927/1190910311"> GDBで実行中のスクリプト言語のスタックフレームをダンプしてみる試み</a>」のコードをほとんどそのまま使わせていただきました。ありがとうございます。)</p>
<div class="igBar"><span id="lcode-12"><a href="#" onclick="javascript:showPlainTxt('code-12'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">CODE:</span>
<div id="code-12">
<div class="code">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">define dump_rb_bt_from_core</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; set $t = ruby_frame</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; while $t</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; printf <span style="color:#CC0000;">"[0x%08x] "</span>, $t</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; if $t-&gt;<span style="">node</span>.<span style="">nd_file</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; printf <span style="color:#CC0000;">"(%s:%d)<span style="color:#000099; font-weight:bold;">\n</span>"</span>, $t-&gt;<span style="">node</span>.<span style="">nd_file</span>, <span style="color:#006600; font-weight:bold;">&#40;</span>$t-&gt;<span style="">node</span>.<span style="">flags</span>&gt;&gt; <span style="color:#800000;color:#800000;">19</span><span style="color:#006600; font-weight:bold;">&#41;</span> &amp; <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#800000;color:#800000;">1</span> &lt;&lt;<span style="color:#006600; font-weight:bold;">&#40;</span>sizeof<span style="color:#006600; font-weight:bold;">&#40;</span>NODE*<span style="color:#006600; font-weight:bold;">&#41;</span> * <span style="color:#800000;color:#800000;">8</span> - <span style="color:#800000;color:#800000;">19</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span> - <span style="color:#800000;color:#800000;">1</span><span style="color:#006600; font-weight:bold;">&#41;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; else</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; printf <span style="color:#CC0000;">"(UNKNOWN)<span style="color:#000099; font-weight:bold;">\n</span>"</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; end</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; set $t = $t-&gt;<span style="">prev</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; end</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">end</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">document dump_rb_bt_from_core</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; dumps the current frame stack from core file. <span style="">usage</span>: dump_rb_bt_from_core</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">end </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>今回はサンプルプログラムとして、0アドレスにアクセスするC拡張ライブラリを実行するrubyスクリプトを用意します。<br />
まず、C拡張ライブラリ(segv.c)、</p>
<div class="igBar"><span id="lc-13"><a href="#" onclick="javascript:showPlainTxt('c-13'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">C:</span>
<div id="c-13">
<div class="c">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #339933;">#include &quot;ruby.h&quot;</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">VALUE do_segv<span style="color: #66cc66;">&#40;</span>VALUE self<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#123;</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; *<span style="color: #66cc66;">&#40;</span><span style="color: #993333;">char</span>*<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#40;</span>0x0<span style="color: #66cc66;">&#41;</span> = <span style="color: #cc66cc;color:#800000;">0</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">return</span> Qnil;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #66cc66;">&#125;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #993333;">void</span> Init_segv<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#123;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; VALUE module;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; module = rb_define_module<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">"Segv"</span><span style="color: #66cc66;">&#41;</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; rb_define_module_function<span style="color: #66cc66;">&#40;</span>module, <span style="color: #ff0000;">"do_segv"</span>, &amp;do_segv, <span style="color: #cc66cc;color:#800000;">0</span><span style="color: #66cc66;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #66cc66;">&#125;</span> </div>
</li>
</ol>
</div>
</div>
</div>
<p>
で、後は適当にextconf.rbを作って、segv.soを作ります。</p>
<p>次にsegv.soを呼び出すRubyスクリプト(test.rb)。</p>
<div class="igBar"><span id="lruby-14"><a href="#" onclick="javascript:showPlainTxt('ruby-14'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">RUBY:</span>
<div id="ruby-14">
<div class="ruby">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#CC0066; font-weight:bold;">require</span> 'segv'</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#9966CC; font-weight:bold;">def</span> test1<span style="color:#006600; font-weight:bold;">&#40;</span>a<span style="color:#006600; font-weight:bold;">&#41;</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; test2<span style="color:#006600; font-weight:bold;">&#40;</span>a<span style="color:#006600; font-weight:bold;">&#41;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#9966CC; font-weight:bold;">end</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#9966CC; font-weight:bold;">def</span> test2<span style="color:#006600; font-weight:bold;">&#40;</span>b<span style="color:#006600; font-weight:bold;">&#41;</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; Segv::do_segv</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#9966CC; font-weight:bold;">end</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">test1<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006666;color:#800000;">1</span><span style="color:#006600; font-weight:bold;">&#41;</span> </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>さて、サンプルプログラムの用意ができたので、SEGVさせてみます。</p>
<pre>
$ ulimit -c unlimited
$ ruby test.rb
test.rb:8: [BUG] Segmentation fault
ruby 1.8.5 (2006-08-25) [i386-linux]

アボートしました (core dumped)
</pre>
<p>これでコアファイルが出力されたので、それをGDBで解析します。</p>
<p>今回はCentOS 5.3のyumでインストールしたrubyから出力されたコアファイルなので、<br />
GDBで解析するには、<a href="http://debuginfo.centos.org/">ここ</a>からrubyのdebuginfoをインストールしておく必要があります。</p>
<pre>
$ 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
</pre>
<p>それでは、GDBでコアファイルからrubyのバックトレースをさせてみます。</p>
<pre>
$ 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=<value optimized out>) at error.c:214
#4  0x00cbd80b in sigsegv (sig=<value optimized out>) 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
</pre>
<p>以上になります。</p>
<p>pythonもコアファイルからスタックフレームが取れるか調べてみましたが、<br />
<a href="http://wiki.python.org/moin/DebuggingWithGdb">DebuggingWithGDB</a>のgdbinitスクリプトを読む限り、<br />
rubyと同様に実行していたpythonスクリプトのファイル名と行番号は取れそうです。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ginriki.net/wd/2009/11/09/80/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

