Varnishのコードリーディング用にCのマクロを展開する

  • 1
    Like
  • 0
    Comment
More than 1 year has passed since last update.

概要

Varnish-CacheのソースコードはCで書かれていますが、高度なマクロが使用されているため関数名でgrepしても呼び出している箇所が見つからないことがありました。

そこでマクロを展開したものをhnakamur/Varnish-Cacheのmacros-expandedブランチに置きました。

関数名でgrepしても呼び出している箇所が見つからない例

説明上はgrepと書いてますが、実際はmonochromegane/the_platinum_searcherを使用しています。いつもありがとうございます!

例えばvarnish/Varnish-Cache at 37d738evbf_stp_fetch を検索すると以下のようになりました。

$ pt vbf_stp_fetch
doc/graphviz/cache_fetch.dot:
55:             v_b_r:non_304:s -> vbf_stp_fetch
59:             vbf_stp_fetch [
63:                            label="{vbf_stp_fetch:|setup VFPs|<fetch>fetch|{fetch_fail?|error?|<ok>ok?}}"
65:             vbf_stp_fetch:ok:s -> FETCH_DONE

bin/varnishd/cache/cache_fetch.c:
538:vbf_stp_fetch(struct worker *wrk, struct busyobj *bo)

bin/varnishd/cache/cache_fetch.c にある vbf_stp_fetch の関数定義がヒットしてますが、呼び出している箇所がヒットしていません。

マクロ展開したソースで検索

hnakamur/Varnish-Cache at f055446で同じ検索をすると以下のようになります。

$ pt vbf_stp_fetch
doc/graphviz/cache_fetch.dot:
55:             v_b_r:non_304:s -> vbf_stp_fetch
59:             vbf_stp_fetch [
63:                            label="{vbf_stp_fetch:|setup VFPs|<fetch>fetch|{fetch_fail?|error?|<ok>ok?}}"
65:             vbf_stp_fetch:ok:s -> FETCH_DONE

bin/varnishd/cache/cache_fetch.c:
10178:vbf_stp_fetch(struct worker *wrk, struct busyobj *bo)
10558:case F_STP_FETCH: stp = vbf_stp_fetch (wrk, bo); break;

bin/varnishd/cache/cache_fetch.c 内で vbf_stp_fetch を呼び出す箇所もヒットしています。

呼び出し箇所の前後のコードはこんな感じです。

bin/varnishd/cache/cache_fetch.c#L10547-L10567

  switch(stp) {




# 1 "../../include/tbl/steps.h" 1
# 59 "../../include/tbl/steps.h"
case F_STP_MKBEREQ: stp = vbf_stp_mkbereq (wrk, bo); break;
case F_STP_RETRY: stp = vbf_stp_retry (wrk, bo); break;
case F_STP_STARTFETCH: stp = vbf_stp_startfetch (wrk, bo); break;
case F_STP_CONDFETCH: stp = vbf_stp_condfetch (wrk, bo); break;
case F_STP_FETCH: stp = vbf_stp_fetch (wrk, bo); break;
case F_STP_ERROR: stp = vbf_stp_error (wrk, bo); break;
case F_STP_FAIL: stp = vbf_stp_fail (wrk, bo); break;
case F_STP_DONE: stp = vbf_stp_done (); break;
# 930 "cache/cache_fetch.c" 2

  default:
   do { VAS_Fail(__func__, "cache/cache_fetch.c", 932, "Illegal fetch_step", VAS_WRONG); } while (0);
  }
 }

これは元のソースでは以下の部分に対応します。

bin/varnishd/cache/cache_fetch.c#L924-L933

        switch(stp) {
#define FETCH_STEP(l, U, arg)                       \
        case F_STP_##U:                     \
            stp = vbf_stp_##l arg;              \
            break;
#include "tbl/steps.h"
#undef FETCH_STEP
        default:
            WRONG("Illegal fetch_step");
        }

includeしている"tbl/steps.h"のうち上記のコードに関わる部分は以下の通りです。

include/tbl/steps.h#L58-L67

#ifdef FETCH_STEP
FETCH_STEP(mkbereq, MKBEREQ,    (wrk, bo))
FETCH_STEP(retry,   RETRY,      (wrk, bo))
FETCH_STEP(startfetch,  STARTFETCH, (wrk, bo))
FETCH_STEP(condfetch,   CONDFETCH,  (wrk, bo))
FETCH_STEP(fetch,   FETCH,      (wrk, bo))
FETCH_STEP(error,   ERROR,      (wrk, bo))
FETCH_STEP(fail,    FAIL,       (wrk, bo))
FETCH_STEP(done,    DONE,       ())
#endif

マクロ展開に使用したスクリプト

マクロ展開に使用したスクリプトはhnakamur/Varnish-Cache/expand-macros.sh at f055446に置いています。

基本的には Makefile.c から .o を作るルールのコマンドラインの gcc -cgcc -E に書き換えて Makefile.expand-macros を作り、それを実行しています。

.c から .o の個々のファイルのルールが有る場合と無い場合の扱いが雑で警告が出るのですが、書捨てスクリプトなので目的が達成できていれば良しということで。

おわりに

これでVarnishのコード内の検索が快適になりました。コードリーディングがはかどりますね!