是否可以测试中止例程不返回?

emb*_*edc 6 c c++ linux testing gcc

我必须测试一个提供其自己的abort_routine()函数的库(在内部调用abort(),但是实现可能会改变)。

此abort_routine()的要求之一是它可能不会返回。

我想知道是否可以测试此要求?

更新: 我不使用gtest,只是llvm的亮起之类的东西:返回0,返回1,assert(false)。

PSk*_*cik 6

这是一个很好的用例fork,我自己在测试中使用它。

您可以简单地fork()在子级(_exit()子级)中运行该函数,获取结果,如果通过指示了该进程的信号SIGABRT,则该子级中止,否则未终止。

示例代码:

#include <sys/wait.h>
#include <unistd.h>
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>

int fork_and_reap(int *Ws, void Fn(void *), void *Arg)
{
    pid_t pid; if (0>(pid=fork())) return -1;
    if(0==pid) (void)Fn(Arg), _exit(0);
    else for(;;){
        if(0>waitpid(pid,Ws,WUNTRACED)){
            if(EINTR==errno) continue;
            else abort();
        }else if(!WIFEXITED(*Ws)&&!WIFSIGNALED(*Ws)){ //shouldn't have stopped
            if(0>kill(pid,SIGTERM) ||0>kill(pid,SIGCONT)) abort();
        }else break;
    }
    return 0;
}
void aborting(void *A){ (void)A; abort(); }
void not_aborting(void *A){ (void)A; }

int main()
{
    int ws;
    if(0<=fork_and_reap(&ws, aborting, 0) && WIFSIGNALED(ws) && WTERMSIG(SIGABRT)) puts("aborted"); else puts("didn't abort");
    if(0<=fork_and_reap(&ws, not_aborting, 0) && WIFSIGNALED(ws) && WTERMSIG(SIGABRT)) puts("aborted"); else puts("didn't abort");
}
Run Code Online (Sandbox Code Playgroud)


Fir*_*cer 1

作为一般解决方案,您可以通过将其作为单独的进程运行来测试它,例如:

int main()
{
    abort_routine();
    printf("Didn't abort\n");
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

当您将其作为子进程运行时,您将能够看到它是否中止(打印一些中止输出,非零退出)或不中止(打印该输出并以零退出)。

这大致就是 gtest 中“死亡测试”的工作原理,https://github.com/google/googletest/blob/master/googletest/docs/advanced.md#how-it-works

在幕后,ASSERT_EXIT() 生成一个新进程并在该进程中执行死亡测试语句。具体发生的细节取决于平台