Перезапустите процесс Windows на месте, сохраняя ID и дескрипторы процесса
Я создал исполняемый файл Windows, который служит имитатором для некоторого встроенного устройства (вся бизнес-логика точно такая же, как и на исходном устройстве, и только заглушки, связанные с HW).
Эта симуляция должна время от времени сбрасываться, и в "нормальном" случае она делает что-то вроде этого:
//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()
заглушка, которая вызывается из нескольких мест в исходном коде.
Проблема в том, что _execv
на винде не ведет себя точно так же execv
в Linux: когда я отлаживаю это приложение в Visual Studio, _execv
не заменяет текущее изображение процесса "перезагруженным" изображением. Вместо этого он просто создает новый процесс с новым идентификатором и завершает текущий процесс, вызывая отсоединение его от Visual Studio, поэтому, чтобы сохранить все точки останова, которые мне нужно снова и снова присоединять к этому новому процессу (существуют десятки перезапусков в одном сеансе отладки).
В настоящее время я использую __debugbreak() в качестве обходного пути. Другой вариант - сбросить симуляцию путем повторной инициализации глобальной среды и использования некоторой комбинации setjmp / longjmp - но глобальная среда и соответствующие инициализаторы распространяются через тысячи исходных файлов, и большинство из них являются статическими, поэтому невозможно выполнить такой сброс вручную (Также я не могу редактировать оригинальные файлы).
Таким образом, вопрос заключается в следующем: есть ли какой-нибудь Windows API / общий обходной путь, который заставляет текущий процесс перезапускать "на месте", сбрасывая все глобальные (и статические) переменные, как в случае, если было возможно перезагрузить один и тот же образ процесса внутри того же адреса пространство, сохраняющее внешне наблюдаемый идентификатор процесса, дескриптор процесса и подключение к отладчику Visual Studio?
2 ответа
Я боюсь, что простой ответ заключается в том, что такой функциональности нет в Windows.
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;
}