簡體   English   中英

是否有可能測試中止例程不會返回?

[英]Is it possible to test that an abort-routine doesn't return?

我必須測試一個提供自己的abort_routine()函數的庫(在內部調用abort(),但實現可能會改變)。

這個abort_routine()的一個要求是它可能不會返回。

我想知道是否有可能測試這個要求?

更新:我沒有使用gtest,只有llvm點亮了這樣的東西:返回0,返回1,斷言(假)。

這是fork一個很好的用例,我在我的測試中自己使用它。

你可以簡單地fork() ,在子_exit()運行函數,在子_exit()運行_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");
}

作為一般解決方案,您可以通過將其作為單獨的進程運行來測試它,例如:

int main()
{
    abort_routine();
    printf("Didn't abort\n");
    return 0;
}

如果它中止(打印一些中止輸出,非零退出)或不打印(打印輸出並退出零),您將能夠看到作為子進程運行它的時間。

這大致與gtest中的“死亡測試”有關, https://github.com/google/googletest/blob/master/googletest/docs/advanced.md#how-it-works

在引擎蓋下,ASSERT_EXIT()產生一個新進程並在該進程中執行死亡測試語句。 這種情況發生的具體細節取決於平台

請參閱_Noreturn關鍵字:

_Noreturn關鍵字出現在函數聲明中,並指定函數不會通過執行return語句或到達函數體的末尾返回(它可以通過執行longjmp返回)。如果聲明_Noreturn的函數返回,則行為是undefined。 如果可以檢測到,則建議使用編譯器診斷 。“

如果聲明了一個函數,編譯器應該給出一條診斷消息。 所以你不需要測試它,但可以檢查編譯器消息並進行代碼審查

https://en.cppreference.com/w/c/language/_Noreturn

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM