重新启动Windows进程,保留进程ID和句柄

时间:2017-08-10 08:10:39

标签: c visual-studio winapi exec win32-process

我创建了一个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调试器的连接?

2 个答案:

答案 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;
}