问题
I have created a windows executable that serves as a simulaator for some embedded device (all the business logic is exactly the same as on original device and only HW related stuff is stubbed).
This simulation needs to reset from time to time, and in "normal" use case it does something like that:
//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;
}
Note: code above is to just illustrate main idea, in real application that execv
call is actually located in HW_Reset()
stub, that is called from multiple places in original code.
The problem is that _execv
on Windows does not behave exactly as execv
on Linux:
when I debug this application in Visual Studio the _execv
does not replace current process image with "restarted" image. Instead it just creates a new process with new ID and terminates current process, causing detaching it from Visual Studio, so, to preserve all the breakpoints I need to reattach to that new process again and again (there are dozens of restarts in single debug session).
Currently I use __debugbreak() as a workaround. Other option is to reset simulation by reinitializing global environment and using some combination of setjmp/longjmp - but global environment and corresponding initializers are spread through thousends of original files, and most of them are static, so it is not possible to handle such reset manually (also I'm not allowed to edit original files).
So the question is: is there some Windows API / generic workaround that causes current process to restart "inplace" by resetting all the global (and static) variables, like in case if it was possible to reload the same process image inside the same address space, preserving outwardly observable process ID, process handle and connection to visual studio debugger?
回答1:
I'm afraid that the simple answer is that no such functionality exists on Windows.
回答2:
Windows does not support what you are asking for. You will have to restructure your main()
code to run in a loop instead, eg:
//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;
}
来源:https://stackoverflow.com/questions/45607959/restart-windows-process-inplace-preserving-process-id-and-handles