[英]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。 如果可以檢測到,則建議使用編譯器診斷 。“
如果聲明了一個函數,編譯器應該給出一條診斷消息。 所以你不需要測試它,但可以檢查編譯器消息並進行代碼審查
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.