2017-08-10 2 views
0

J'ai créé un exécutable Windows qui sert de simulateur pour certains périphériques intégrés (toute la logique métier est exactement la même que sur le périphérique d'origine et seuls les composants matériels sont stockés).Redémarrer le processus Windows en conservant l'ID du processus et les handles

Cette simulation a besoin pour remettre de temps en temps, et en cas d'utilisation « normale », il fait quelque chose comme ça:

//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: le code ci-dessus est d'illustrer simplement l'idée principale, en application réelle que execv L'appel est en fait situé dans HW_Reset() stub, qui est appelé à partir de plusieurs endroits dans le code original.

Le problème est que_execv sur Windows ne se comporte pas exactement comme execv sur Linux: quand je déboguer cette application dans Visual Studio le _execv ne remplace pas l'image du processus en cours avec l'image « redémarré ». Au lieu de cela, il crée simplement un nouveau processus avec un nouvel ID et termine le processus en cours, le détachant de Visual Studio, afin de conserver tous les points d'arrêt nécessaires à ce nouveau processus (il y a des dizaines de redémarrages en session de débogage)).

Actuellement, j'utilise __debugbreak() comme solution de contournement. L'autre option consiste à réinitialiser la simulation en réinitialisant l'environnement global et en utilisant une combinaison de setjmp/longjmp - mais l'environnement global et les initialiseurs correspondants se propagent par milliers de fichiers originaux, et la plupart d'entre eux sont statiques. manuellement (aussi je ne suis pas autorisé à modifier les fichiers originaux).

La question est donc: est-il une API Windows/solution générique qui provoque processus en cours pour redémarrer « inplace » en remettant à zéro tous les mondiaux (et statiques) variables, comme dans le cas s'il était possible de recharger le même traiter l'image à l'intérieur du même espace d'adressage, en préservant l'identificateur de processus observable vers l'extérieur, la poignée de processus et la connexion au débogueur Visual Studio?

+2

non, rien même près de ne pas exister dans les fenêtres – RbMm

Répondre

0

Je crains que la réponse simple est qu'aucune telle fonctionnalité n'existe sur Windows.

0

Windows ne prend pas en charge ce que vous demandez. Vous devrez restructurer votre main() code à exécuter dans une boucle au lieu, par exemple:

//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; 
} 
+0

dans ce cas « (ré) initialiser dispositif simulé » opération doit être effectuée manuellement , y compris (ré) initialisant la statique répartie dans ces "milliers de fichiers originaux" –

+0

@ Chajnik-U: mieux se débarrasser des globals et des statiques, les enfermer dans des objets, puis la réinitialisation peut simplement détruire les anciens objets et en créer de nouveaux . –