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

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

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

調べてみると、Vine Linuxのsrpmを使うと楽ということなので、srpmからrpmbuildします。だれかCentOS用hyperestraierのyumリポジトリ作ってくれませんか?(他力本願)

まず、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のユーザマニュアルを参照してください。

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

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

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

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

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

[code]
define dump_rb_bt_from_core
set $t = ruby_frame
while $t
printf “[0x%08x] “, $t
if $t->node.nd_file
printf “(%s:%d)\n”, $t->node.nd_file, ($t->node.flags >> 19) & ((1 << (sizeof(NODE*) * 8 - 19)) - 1) else printf "(UNKNOWN)\n" end set $t = $t->prev
end
end

document dump_rb_bt_from_core
dumps the current frame stack from core file. usage: dump_rb_bt_from_core
end
[/code]

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

VALUE do_segv(VALUE self){
*(char*)(0x0) = 0;
return Qnil;
}

void Init_segv(){
VALUE module;
module = rb_define_module(“Segv”);
rb_define_module_function(module, “do_segv”, &do_segv, 0);
}
[/C]
で、後は適当にextconf.rbを作って、segv.soを作ります。

次にsegv.soを呼び出すRubyスクリプト(test.rb)。
[RUBY]
require ‘segv’

def test1(a)
test2(a)
end

def test2(b)
Segv::do_segv
end

test1(1)
[/RUBY]

さて、サンプルプログラムの用意ができたので、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ドライバを入れる

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

ただ、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のサポート外になってしまうので、いじるときは自己責任でお願いします。

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

半年ほど前に、ハンディGPSのGarmin Oregon 300を買いました日本語版は高いので、英語版をYahooオークションで45,000円程度で買いました。Amazon.comが使えればもっと安く買えたのですが、日本から電気機器類を注文できないようです。
私の主な用途は旅行などの移動経路を記録することですが、地図情報をちゃんと入れておけば道に迷った時も重宝します。

今回は記録した移動経路と移動経路上で撮った写真をgoogle mapに表示する方法について説明します。
・・・といっても、フリーソフトの轍 Wadachiを使えば簡単に表示できますはWindows専用ソフトのようです。MacやLinuxの人はごめんなさい。

基本的な使い方は上のリンク先の「標準的な作業の流れ」を見てもらえればよいです。
ロンドン旅行したときの移動経路ログと写真を轍で編集してGoogle mapで表示したものを下記に貼りました表示時刻が日本時間になっているので注意。ロンドン時間では-9時間してください。。移動経路は日付ごとに色分けしてあります。

ロンドン移動経路[gpxview=all]

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

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

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

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

Oregon 300は、移動経路のログをGPX形式で保存しますOregon 300の設定にもよりますが、通常、10秒ごとに現在位置をtrkタグとして書き込むようになっています。。下記説明も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タグが下記のように表示されるので、それをブログに貼りつければよいです。


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

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

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

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

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

プロセスのユーザ空間(=デバッギのユーザ空間)に対してデバッガプロセスがプローブする場合は以前、デバッガについて書いた記事もどうぞ。

  1. デバッガプロセスがptrace辺りを使ってデバッギのメモリ空間上の指定アドレス上にあるアセンブリ命令をint 3に書き変えてint 3はIA-32とかIntel architectureの場合の話です
  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の関係で色々対策が必要なんだねデバッギプロセスにプローブする場合に必要なマルチスレッド対策とどの程度一緒なのかは、まだよくわからない。。int 3を実行した後、例外ベクタにジャンプしてからどういう手順で処理してるかについてイメージがわかないから、今度ソース読んでみようかな。

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

crashコマンド使ってみた

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

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

解析にあたってkernelのデバッグ情報がいるので、debuginfoのRPMをインストールします最初、yumでinstallしたら、なぜか2.6.18-92.1.6.el5.centos.plusが入りました。kernelバージョンと合ってないので、rpmコマンドで入れなおし。

 $ 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を統合したやつだそうでCrash WhitepaperのAbstract参照、GDBになじんでる私には結構使いやすいです。
[CODE]
$ crash
KERNEL: /usr/lib/debug/lib/modules/2.6.18-128.1.16.el5/vmlinux
DUMPFILE: /dev/crash
CPUS: 1
DATE: Mon Jul 13 02:17:05 2009
UPTIME: 06:52:42
LOAD AVERAGE: 0.16, 0.03, 0.01
TASKS: 86
NODENAME: localhost.localdomain
RELEASE: 2.6.18-128.1.16.el5
VERSION: #1 SMP Tue Jun 30 06:10:28 EDT 2009
MACHINE: i686 (1197 Mhz)
MEMORY: 758.9 MB
PID: 3848
COMMAND: “crash”
TASK: ef67c000 [THREAD_INFO: d9120000]
CPU: 0
STATE: TASK_RUNNING (ACTIVE)
crash> set 1
PID: 1
COMMAND: “init”
TASK: c16f5aa0 [THREAD_INFO: c16f6000]
CPU: 0
STATE: TASK_INTERRUPTIBLE
crash> p $tmp = jiffies
$1 = 24873000
crash> x modprobe_path
0xc0680be0 : das
crash> show convenience
$tmp = 24873000
$__ = void
$_ = (examine_i_type *) 0xc0680be0 “/sbin/modprobe”
crash> exit
[/CODE]
gdbスクリプトをsourceで読み込むこともできる。
まだ、まともな使い方は全然してないけど、Debug Hacksにいろいろ書いてあるので、それを読みながらやる予定。
[amazon ASIN=’4873114047′ TYPE=’banner’]

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

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

これは、whoisサーバを使えば調べられます判明したIPアドレスの範囲すべてがe-mobile接続時に割り当てられうるとは限りませんが

#とりあえず、接続した際に割り当てられた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

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

同一SQLに対する、mysqlのバージョンによる動作の違い

最近のmysqlで、ASで作ったエイリアス名に1重引用符を付けてORDER BY指定したときの動作が変わりました。
DBサーバを移行してmysqlのバージョンを新しくしたら、PHPコード内のSQL動作結果が変わっていてびっくりしました。

具体例は以下、
[SQL]
$ mysql -u root mysql # mysql-server: 5.0.27
mysql> SELECT COUNT(*) AS cnt FROM user
mysql> GROUP BY User ORDER BY cnt desc;
+—–+
| cnt |
+—–+
| 4 |
| 1 |
+—–+
2 rows in set (0.00 sec)

mysql> SELECT COUNT(*) AS cnt FROM user
mysql> GROUP BY User ORDER BY ‘cnt’ desc;
+—–+
| cnt |
+—–+
| 4 |
| 1 |
+—–+
2 rows in set (0.00 sec)
— cntも’cnt’も同じ動作
[/SQL]

[SQL]
$ mysql -u root mysql # mysql-server: 5.0.45
mysql> SELECT COUNT(*) AS cnt FROM user
mysql> GROUP BY User ORDER BY cnt desc;
+—–+
| cnt |
+—–+
| 4 |
| 1 |
+—–+
2 rows in set (0.00 sec)

mysql> SELECT COUNT(*) AS cnt FROM user
mysql> GROUP BY User ORDER BY ‘cnt’ desc;
+—–+
| cnt |
+—–+
| 1 |
| 4 |
+—–+
2 rows in set (0.00 sec)
— cntと’cnt’で違う動作
[/SQL]

ORDER BY ‘cnt’の ‘cnt’部分を文字列リテラルとみなすか、識別子とみなすかの差ですね。

IA-32のjmp, call命令でTrapするGDBスクリプト

jmp/call命令の実行直前までプログラムを進めるGDBスクリプトです。
こういう用途に使えるGDBコマンドがないようなので、自分で作りました。
必要な方はご自由に使ってください。
script.gdb

使い方は以下の通り、

$ gdb a.out
(gdb) source script.gdb
(gdb) break main
(gdb) run
# main関数でbreak

(gdb) run_until_call_jmp
# main関数内のcall or jmp命令直前で停止

jmp,call命令のop codeの調べ方

IA-32命令セットにおける、JMP, CALLのオペコードは下記の通りになりますIA-32 インテル アーキテクチャ・ソフトウェア・ディベロッパーズ・マニュアル 中巻より抜粋。http://www.intel.com/jp/download/index.htm

JMP命令のオペコード
callオペコード

cb、cw、cd、cpは、オペコードの後に続く1,2,4,6バイトの値です。
jmpやcall命令では、jmp/call先のアドレス値を表しています。

/2とか/3とかっていうのは、ModR/Mバイトのdigit(= op codeの一部) 上記マニュアルの2章(特に2.4~2.6)参照を表してます。
op codeの一部なので、当然、命令を判定する際にdigitのチェックが必要です。

digitは/0~/7まであり、ModR/Mバイトの下位3bitに対応します。

例えば32bitの絶対間接nearジャンプのオペコードは下記になります。

16進表記:  FF /4
2進表記 :  11111111 xxxxx100

xxxxxの部分の値によって、ジャンプ先のアドレス値として参照するレジスタ/メモリアドレスが変化します。
例えば、eaxレジスタに格納されたアドレス値へジャンプする場合は、xxxxx=11000 です。

こんな感じで命令のop codeを調べて実装したのが上記のGDBスクリプトです。
スクリプトを改造する時の参考にしてください。