web-dev-qa-db-fra.com

Pourquoi et comment le mode QuickEdit dans l'invite de commandes gèle-t-il les applications?

J'ai récemment rencontré un problème avec l'invite de commande sous Windows où le mode QuickEdit était activé et où cliquer sur la fenêtre permettait de sélectionner du texte et de suspendre un programme en cours d'exécution. C'est apparemment un comportement connu - j'ai trouvé quelques questions à ce sujet:

Comment l'application est-elle "suspendue"/"suspendue"? Le processus est-il similaire au signal SIGSTOP sur * nix? (Je suis également intéressé à comprendre pourquoi cette fonctionnalité existe-t-elle en premier lieu? Cela semble peu intuitif et dangereux.)

43
Whymarrh

C'est très bien par conception. Il n’existe aucun moyen raisonnable pour un utilisateur de sélectionner du texte lorsque votre programme continue à faire défiler le contenu de la fenêtre de la console. Ainsi, le programme hôte de la console arrête simplement de lire votre sortie stdout/stderr et votre programme se bloque jusqu'à ce que l'utilisateur ait terminé l'opération. Cela peut être changé, vous devrez appeler Get + SetConsoleMode () et désactiver l’option ENABLE_QUICK_EDIT_MODE.

Notez que ce "blocage" n'est pas fondamentalement différent des pauses d'exécution que vous obtenez lorsque votre programme génère une sortie stdout à un taux beaucoup plus élevé que celui que l'hôte de la console peut utiliser. Bien que ces retards soient finis.

Et ce n’est pas le seul moyen pour l’utilisateur d’arrêter votre programme, il peut aussi simplement appuyer sur Ctrl + S. Appuyez sur Ctrl + Q pour le reprendre. Si vous êtes assez âgé, vous pourriez reconnaître ces codes de contrôle en tant que Xon/Xoff , caractères de prise de contact pour un terminal. C’est ce qu’est une console, une simple émulation de terminal telle qu’elle était utilisée dans les années 1970. Cela peut aussi être changé, vous devrez cesser de vous fier à l'entrée de la console avec tampon intégrée et basculer vers ReadConsole () . Ou bien, en désactivant l'option de la console ENABLE_LINE_INPUT, vous ne devez pas savoir quels sont les effets secondaires qui ont eu lieu depuis que vous n'avez mentionné aucune langue d'exécution, vous devez essayer.

Et bien sûr, terminer votre programme est très facile. Vous obtenez EOF sur stdin lorsque l'utilisateur tape Ctrl + Z, cela devrait mettre fin à votre programme. Et il y a Ctrl + C et Ctrl + Break pour une résiliation instantanée, peu importe ce que votre programme fait. Vous pouvez obtenir une notification pour ceux-ci avec SetConsoleCtrlHandler () mais vous ne pouvez pas la bloquer.

Si le comportement par défaut est dangerous et met en danger la santé d'un humain, je vous suggère fortement de faire appel à un consultant. Et ne saura pas qui a écrit cette réponse.

46
Hans Passant

Pour répondre à la question, j'ai récemment débogué le même problème dans un script python et capturé une trace de pile à l'aide de windbg.

 

L'appel à WriteConsole mène finalement au syscall NtDeviceIoControlFile et le noyau ne revient pas tant qu'une pression sur une touche n'est pas effectuée ou que le mode QuickEdit n'est pas modifié. Ainsi, si vous n'écrivez jamais sur la console, votre processus est protégé du gel en mode QuickEdit. Et votre utilisateur n'aura jamais besoin de copier quoi que ce soit. Alors attendez encore ce qu'est le mode QuickEdit?

0
SargeATM