我创建了一个Windows可执行文件,作为某个嵌入式设备的模拟器(所有业务逻辑与原始设备完全相同,只有硬件相关的东西被存根)。
此模拟需要不时重置,在“正常”用例中,它会执行类似的操作:
//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()
存根中的实际应用中,从原始代码中的多个位置调用。
问题是Windows上_execv
的行为与Linux上的execv
不完全相同:
当我在Visual Studio中调试此应用程序时,_execv
不会用“重新启动”的图像替换当前的过程映像。相反,它只是创建一个带有新ID的新进程并终止当前进程,导致它从Visual Studio中分离出来,因此,要保留我需要一次又一次地重新连接到该新进程的所有断点(在单个调试会话中有几十次重新启动) )。
目前我使用__debugbreak()作为解决方法。 其他选项是通过重新初始化全局环境并使用setjmp / longjmp的某种组合来重置模拟 - 但是全局环境和相应的初始化器通过原始文件的thousends传播,并且大多数是静态的,因此不可能手动处理这样的重置(我也不允许编辑原始文件)。
所以问题是:是否有一些Windows API /通用解决方法通过重置所有全局(和静态)变量导致当前进程“就地”重新启动,如果有可能的话在同一地址空间内重新加载相同的过程映像,保留向外可观察的进程ID,进程句柄和与visual studio调试器的连接?
答案 0 :(得分:0)
我担心简单的答案是Windows上没有这样的功能。
答案 1 :(得分:0)
Windows不支持您的要求。您必须重新构建main()
代码才能在循环中运行,例如:
//some global environment
...
int main(int argc, char* argv[])
{
__debugbreak();
do
{
//... (re)initialize simulated device
//... do some stuff
}
while (restart needed);
//... do some other testing stuff
return 0;
}