【发布时间】:2017-08-10 08:10:38
【问题描述】:
我创建了一个 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 的某种组合来重置模拟 - 但全局环境和相应的初始化程序分布在成千上万的原始文件中,并且其中大部分是静态的,因此无法手动处理此类重置(我也不允许编辑原始文件)。
所以问题是: 是否有一些 Windows API / 通用解决方法通过重置所有全局(和静态)变量来“就地”重新启动当前进程,以防万一在相同的地址空间内重新加载相同的进程映像,保留外部可观察的进程 ID、进程句柄和与 Visual Studio 调试器的连接?
【问题讨论】:
-
不,Windows 中几乎没有任何东西
标签: c visual-studio winapi exec win32-process