我目前正在开发一个单元测试框架,用户可以在其中创建测试用例并在框架中注册。
我还想确保,如果任何用户测试代码导致崩溃,它不应该使整个框架崩溃,而应该被标记为失败。为了实现这项工作,我编写了以下代码,以便我可以在沙盒功能中运行用户代码
bool SandBox(void *(*fn)(void *),void *arg, void *rc)
{
#ifdef WIN32
__try
{
if (rc)
rc = fn(arg);
else
fn(arg);
return true;
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
return false;
}
#else
#endif
}
这在 Windows 上完美运行,但我希望我的框架是可移植的,为了实现这一点,我想确保 posix 环境具有类似的功能。
我知道 C 信号处理程序可以拦截操作系统信号,但将信号处理机制转换为 SEH 框架存在某些我无法解决的挑战
- 即使我的程序收到信号,如何继续执行?
- 如何将执行控制从失败位置跳转到可用于错误处理的块(类似于 except)?
- 如何清理资源?
我正在考虑在具有自己的信号处理程序的单独线程上运行用户测试代码的另一种可能性,并从信号处理程序终止线程,但再次不确定这是否可行。
因此,在我进一步思考之前,如果社区知道有更好的解决方案来解决这个问题/情况,我希望得到社区的帮助。
正如你所说,你可以通过捕获 SIGSEGVsignal()
or sigaction()
.
继续并不是真正可取的,因为这将是未定义的行为,即您的内存可能会被损坏,这可能会让其他测试用例也失败(甚至过早终止整个过程)。
是否可以将测试用例作为子流程一一运行?这样,您可以检查退出状态,并检测它是否完全终止、出现错误或由于信号而终止。
在单独的线程中运行测试用例会遇到同样的问题:测试用例和驱动测试用例的代码之间没有内存保护。
建议的方法是:
fork()
创建一个子进程。
在子进程中,您execve()
你的测试用例。这可以是相同的二进制文件,具有不同的参数来选择特定的测试用例)。
在父进程中,您调用waitpid()
等待测试用例的终止。您从以下位置收到了 pidfork()
调用父进程。
使用 WIFEXITED、WEXITSTATUS、WIFSIGNALED、WTERMSIG 宏评估子流程状态。
如果您的测试用例需要超时,您还可以安装 SIGCHLD 的处理程序。如果超时先到,kill()
子进程。请注意,您只能从信号处理程序中调用某些函数。
进一步说明:execve()
并不是真正需要的。您可以继续并直接调用您指定的测试用例。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)