よくわからないエンジニア

よく分からないエンジニア(無音鈴鹿)の日々の記録

よくわからないエンジニア

CentOS7 GNU GLOBALを導入する

急遽、ソースコードを読む必要が発生してしまった。理由は前回のmod_dosdetector記事に由来する。

www.unknownengineer.net

色々ググったおかげで、なんとなくmod_dosdetectorに設定する値は分かるものの、mod_setenvifとか何のために設定として記述しているのかが全然分からない事に気が付いた。普段であれば、知ったような顔して適当な記事を書くのだが、珍しくやる気を出してソースコードを読んでみた。
そして結果的に挫折して今に至る。

原因として、コードを読んでいると、関数なり構造体なりがたくさん出てきて、これらが何処で定義されているのかわからずに、結局何をやっているのか分からなくなってしまう。
せめて少しでもコードリーディングの助けになれば、とWebを徘徊していると、なんか有用そうなものを見つけたので、早速導入してみる。

目次

GNU GLOBALの導入

GNU GLOBALはソースコード解析ツールらしいです。他のを使った事が無いので、比較のしようがありません。
とりあえず、今記事を書きながら入れてみて、使ってみようと思います。公式サイトから落っことしてきて、インストールします。

# cd /usr/local/src
# wget http://tamacom.com/global/global-6.5.6.tar.gz
# tar xvfz global-6.5.6.tar.gz
# ./configure --prefix=/usr/local/global
# make
# make install

なんの苦労もなくインストール出来ました。

コマンドラインで使う

とりあえずコマンドラインから使います。いつもの癖でprefix指定したので、まずは/usr/local/binの下に使うコマンドのリンク貼ります。

# ln -s /usr/local/global/bin/global /usr/local/bin/
# ln -s /usr/local/global/bin/gtags /usr/local/bin/

今回はmod_setenvifのソースが読みたいので、httpdのソースファイルを解析します。

# cd /usr/local/src/httpd-2.4.25/
# gtags -v
#  ls G*
GPATH  GRTAGS  GTAGS

3つのディレクトリが出来ていれば、解析完了です。
まずは、ソースコード内にsetenvifが記述されているファイルを探します。-gオプションを使うと。。

# global -g setenvif
modules/http/http_request.c
modules/metadata/mod_setenvif.c
modules/ssl/mod_ssl.c
os/netware/modules.c

ふむふむ。次は、setenvif.cで定義されている関数一覧を表示します。

# global -f modules/metadata/mod_setenvif.c
APR_WANT_STRFUNC   87 modules/metadata/mod_setenvif.c #define APR_WANT_STRFUNC
special            97 modules/metadata/mod_setenvif.c enum special {
SPECIAL_NOT        98 modules/metadata/mod_setenvif.c     SPECIAL_NOT,
SPECIAL_REMOTE_ADDR   99 modules/metadata/mod_setenvif.c     SPECIAL_REMOTE_ADDR,
SPECIAL_REMOTE_HOST  100 modules/metadata/mod_setenvif.c     SPECIAL_REMOTE_HOST,
SPECIAL_REQUEST_URI  101 modules/metadata/mod_setenvif.c     SPECIAL_REQUEST_URI,
SPECIAL_REQUEST_METHOD  102 modules/metadata/mod_setenvif.c     SPECIAL_REQUEST_METHOD,
SPECIAL_REQUEST_PROTOCOL  103 modules/metadata/mod_setenvif.c     SPECIAL_REQUEST_PROTOCOL,
SPECIAL_SERVER_ADDR  104 modules/metadata/mod_setenvif.c     SPECIAL_SERVER_ADDR
sei_entry         116 modules/metadata/mod_setenvif.c } sei_entry;
sei_cfg_rec       120 modules/metadata/mod_setenvif.c } sei_cfg_rec;
create_setenvif_config  133 modules/metadata/mod_setenvif.c static void *create_setenvif_config(apr_pool_t *p)
create_setenvif_config_svr  141 modules/metadata/mod_setenvif.c static void *create_setenvif_config_svr(apr_pool_t *p, server_rec *dummy)
create_setenvif_config_dir  146 modules/metadata/mod_setenvif.c static void *create_setenvif_config_dir(apr_pool_t *p, char *dummy)
merge_setenvif_config  151 modules/metadata/mod_setenvif.c static void *merge_setenvif_config(apr_pool_t *p, void *basev, void *overridesv)
ICASE_MAGIC       165 modules/metadata/mod_setenvif.c #define ICASE_MAGIC  ((void *)(&setenvif_module))
SEI_MAGIC_HEIRLOOM  166 modules/metadata/mod_setenvif.c #define SEI_MAGIC_HEIRLOOM "setenvif-phase-flag"
is_header_regex   170 modules/metadata/mod_setenvif.c static int is_header_regex(apr_pool_t *p, const char* name)
non_regex_pattern  190 modules/metadata/mod_setenvif.c static const char *non_regex_pattern(apr_pool_t *p, const char *s)
add_envvars       249 modules/metadata/mod_setenvif.c static const char *add_envvars(cmd_parms *cmd, const char *args, sei_entry *new)
add_setenvif_core  282 modules/metadata/mod_setenvif.c static const char *add_setenvif_core(cmd_parms *cmd, void *mconfig,
add_setenvif      404 modules/metadata/mod_setenvif.c static const char *add_setenvif(cmd_parms *cmd, void *mconfig,
add_setenvifexpr  418 modules/metadata/mod_setenvif.c static const char *add_setenvifexpr(cmd_parms *cmd, void *mconfig,
add_browser       461 modules/metadata/mod_setenvif.c static const char *add_browser(cmd_parms *cmd, void *mconfig, const char *args)
match_headers     491 modules/metadata/mod_setenvif.c static int match_headers(request_rec *r)
register_hooks    629 modules/metadata/mod_setenvif.c static void register_hooks(apr_pool_t *p)

他にも、指定した関数がどのソースで定義しているか検索出来たり、どこで参照されているかも確認出来ます。
詳しくは–helpで確認出来ます。

Vimで使う

普段使いはvimなので、とりあえずvimで使えるようにします。サイトの説明を読んでみると、

3.5.2 Preparation

First, do the preparation of global. See section Preparation.

Second, copy ‘gtags.vim’ to your plug-in directory or source it from your vimrc.

    $ cp /usr/local/share/gtags/gtags.vim $HOME/.vim/plugin

どうやら、gtabs.vimをプラグインの置き場所コピーすればオッケーっぽい。自分のvimがどこからプラグインを読み込んでいるか調べると。。

runtimepath=~/.vim,/usr/share/vim/vimfiles,/usr/share/vim/vim74,/usr/share/vim/vimfiles/after,~/.vim/after

自環境では上記から読み込んでいる模様。最初、/usr/share/vim/vim74の下にplugin/ディレクトリがあったので、こちらにgtags.vimをコピーする。

# cp -p /usr/local/global/share/gtags/gtags.vim /usr/share/vim/vim74/plugin/

再度ログインすると、gtags.vimが読み込めるようになります。
後は、ソースコードのディレクトリでvimを開き、:Gtags ** といった形で指定していきます。

# /usr/local/src/httpd-2.4.25
# vim 
(vim画面で)
:Gtags create_setenvif_config

これでcreate_setenvif_configの関数へ飛べます。こんな感じで使っていきます。詳しい使い方は以下のページの方が綺麗に纏めているので、そちらを参考に。。

www.machu.jp

まぁ、ソースコードが読みやすくなっても、読めるかどうかは別なんですけどね。。とりあえず頑張ってみます。