Segmentation Fault

コアダンプの数だけ強くなれるよ、デスマと戦うエンジニアのように。

C言語で簡易関数トレース

シンプルなprintf()デバッグコンパイルスイッチでON/OFFできるように実装する。

trace.c

#include <stdio.h>

#ifdef DEBUG_ENABLE
#define ENTRANCE(fmt, ...) \
    printf("%s:%u:===> IN  %s(" fmt ")\n", __FILE__, __LINE__, __func__, ##__VA_ARGS__);
#else
#define ENTRANCE(fmt, ...)
#endif /* DEBUG_ENABLE */

#ifdef DEBUG_ENABLE
#define EXIT(fmt, ...) \
    printf("%s:%u:<=== OUT %s(" fmt ")\n", __FILE__, __LINE__, __func__, ##__VA_ARGS__);
#else
#define  EXIT(fmt, ...)
#endif /* DEBUG_ENABLE */

#ifdef DEBUG_ENABLE
#define LOG_DEBUG(fmt, ...) \
    printf("%s:%u:%s():  " fmt "\n", __FILE__, __LINE__, __func__, ##__VA_ARGS__);
#else
#define LOG_DEBUG(fmt, ...)
#endif /* DEBUG_ENABLE */

int function(int a)
{
    int ret = 0;
    ENTRANCE("a=%d", a);

    EXIT("ret=%d", ret);
    return ret;
}

int main(void)
{
    ENTRANCE();

    LOG_DEBUG("hello world");

    int a = 1;
    int b = 2;
    LOG_DEBUG("a + b = %d", a+b);

    function(a);

    EXIT();
    return 0;
}



実行例

$ gcc -DDEBUG_ENABLE trace.c
$
$ ./a.out
trace.c:35:===> IN  main()
trace.c:37:main():  hello world
trace.c:41:main():  a + b = 3
trace.c:27:===> IN  function(a=1)
trace.c:29:<=== OUT function(ret=0)
trace.c:45:<=== OUT main()
$




あくまで簡易的なのでソースコードの規模が大きくなるほど見にくくなる予感。

trace.c:35:===> IN  main()
trace.c:27:  ===> IN  function(a=1)
trace.c:29:  <=== OUT function(ret=0)
trace.c:45:<=== OUT main()

こんな感じで、関数のIN/OUTでスタックが深くなるにしたがって表示が右にシフトしていくような機能が欲しい。
後は、タイムスタンプとsyslogのようにログレベルを指定してログの出力量を調整できる機能を追加したい。