Перезапустите процесс 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;
}
Другие вопросы по тегам