我创建了一个 Windows 可执行文件,用作某些嵌入式设备的模拟器(所有业务逻辑与原始设备上的完全相同,只有与硬件相关的内容被 stub )。
此模拟需要不时重置,在“正常”用例中,它会执行类似的操作:
//some global environment
...
int main(int argc, char* argv[])
{
__debugbreak();
//... do some stuff
//if( restart needed ){
printf("before _execv");
_execv(argv[0], argv); //"reset" simulated device
//}
//... do some other testing stuff
return 0;
}
注意:上面的代码只是为了说明主要思想,在实际应用中,execv
调用实际上位于HW_Reset()
stub 中,从多个地方调用原始代码。
问题是 Windows 上的 _execv
的行为与 Linux 上的 execv
不完全相同:
当我在 Visual Studio 中调试此应用程序时,_execv
不会用“重新启动”图像替换当前进程图像。相反,它只是使用新 ID 创建一个新进程并终止当前进程,导致它与 Visual Studio 分离,因此,为了保留我需要一次又一次重新附加到该新进程的所有断点(在单个调试 session 中有数十次重新启动) )。
目前我使用 __debugbreak() 作为解决方法。 其他选项是通过重新初始化全局环境并使用 setjmp/longjmp 的某种组合来重置模拟 - 但全局环境和相应的初始化程序分布在数千个原始文件中,并且其中大多数是静态的,因此不可能手动处理此类重置(而且我也不允许编辑原始文件)。
所以问题是:是否有一些 Windows API/通用解决方法可以通过重置所有全局(和静态)变量来导致当前进程“就地”重新启动,就像可能的情况一样在同一地址空间内重新加载相同的进程镜像,保留外部可观察的进程 ID、进程句柄以及与 Visual Studio 调试器的连接?
最佳答案
恐怕简单的答案是 Windows 上不存在这样的功能。
关于c - 就地重新启动 Windows 进程,保留进程 ID 和句柄,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45607959/