setjmp/longjmp検証 - サンプルコード

monasqの移植時に monalibcのsetjmp/longjmpでハングアップしたとの指摘を頂いているので検証用のコードを書いた。

まずはLinux上で動かす。

#include <setjmp.h>

int func_a(int value);
void func_b(int value);
void func_c(int value);

static jmp_buf env;

int func_a(int value)
{
    printf("%s\n", __func__);
    if (-1 == setjmp(env))
    {
        return -1;
    }
    func_b(value);
    return 0;
}

void func_b(int value)
{
    printf("%s\n", __func__);
    func_c(value);
}

void func_c(int value)
{
    printf("%s\n", __func__);
    if (1234 == value)
    {
        longjmp(env, -1);
    }
}

int main(int argc, char *argv[])
{
    printf("%s\n", func_a(0) ? "NG" : "OK");
    printf("%s\n", func_a(1234) ? "NG" : "OK");
    return 0;
}

setjmp/longjmpはスタックコンテキストを保存するのでこんなことが出来ますよってことで。