96 votes

python: est-il possible d'attacher une console à un processus en cours d'exécution

Je souhaite simplement connaître l'état du processus. Est-il possible d'associer une console au processus? Je peux donc appeler des fonctions à l'intérieur du processus et voir certaines des variables globales.

Il est préférable que le processus s'exécute sans être affecté (bien sûr, les performances peuvent baisser un peu)

64voto

RobM Points 2681

Cela va interrompre votre processus (sauf si vous démarrez dans un thread), mais vous pouvez utiliser l' code module pour démarrer une console Python:

import code
code.interact()

Cela va bloquer jusqu'à ce que l'utilisateur quitte la console interactive par l'exécution de l' exit().

L' code module est disponible dans au moins Python v2.6, et probablement d'autres.

J'ai tendance à utiliser cette approche en combinaison avec les signaux pour mon Linux de travail (pour Windows, voir ci-dessous). Je claque en haut de mes scripts Python:

import code
import signal
signal.signal(signal.SIGUSR2, lambda sig, frame: code.interact())

Et puis déclencher à partir d'un shell avec kill -SIGUSR2 <PID><PID> est l'ID de processus. Le processus s'arrête tout ce qu'il fait et présente une console:

Python 2.6.2 (r262:71600, Oct  9 2009, 17:53:52)
[GCC 3.4.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>>

Généralement à partir de là, je vais charger le composant côté serveur d'un débogueur distant comme l'excellent WinPDB.

Windows n'est pas POSIX-compatible OS, et ainsi de ne pas fournir les mêmes signaux que Linux. Cependant, Python v2.2 et au-dessus d'exposer un Windows-signal spécifique SIGBREAK (déclenché en appuyant sur CTRL+Pause/Break). Cela ne veut pas interférer avec la normale CTRL+C (SIGINT) de l'opération, et est donc une alternative pratique.

Donc un portable, mais un peu moche, la version ci-dessus est:

import code
import signal
signal.signal(
        vars(signal).get("SIGBREAK") or vars(signal).get("SIGUSR2"),
        lambda sig, frame: code.interact()
        )

Les avantages de cette approche:

  • Pas de modules externes (tous les standards de Python, des trucs)
  • À peine consomme toutes les ressources jusqu'à ce déclenchée (2x importation)

42voto

fmark Points 15028

Si vous avez accès au code source du programme-code, vous pouvez ajouter cette fonctionnalité relativement facilement.

Voir La Recette 576515: Debugging a running python process by interrupting and providing an interactive prompt (Python)

Pour citer:

Cela fournit le code afin de permettre à toute python programme qui l'utilise pour être interrompu au point actuel, et communiqué via un normal python console interactive. Cela permet à l' les habitants, globals et le programme associé l'état de l'enquête, ainsi que l'appel de fonctions arbitraires et des classes.

Pour l'utiliser, un processus doit importer la module d'appel et l'appel listen() à tout moment lors du démarrage. Pour interrompre cette processus, le script peut être exécuté directement, en donnant l'Id de processus du processus de débogage en tant que paramètre.


Une autre mise en œuvre de la peu près le même concept est fourni par rconsole. À partir de la documentation:

rconsole est un remote console Python avec l'auto-complétion, ce qui peut être utilisé pour inspecter et modifier les l'espace de noms de l'exécution d'un script.

Pour appeler un script à faire:

from rfoo.utils import rconsole
rconsole.spawn_server()

Joindre à partir d'un shell à faire:

$ rconsole

Note de sécurité: La rconsole auditeur commencé avec spawn_server() va accepter toutes les connexions locales et peut par conséquent, l'insécurité à l'utilisation partagée de la d'hébergement ou des environnements similaires!

5voto

MatToufoutu Points 5879

Pourquoi ne pas simplement utiliser le module pdb ? Il vous permet d'arrêter un script, d'inspecter les valeurs des éléments et d'exécuter le code ligne par ligne. Et puisqu'il repose sur l'interpréteur Python, il fournit également les fonctionnalités fournies par l'interpréteur classique. Pour l'utiliser, il suffit de mettre ces 2 lignes dans votre code, où vous souhaitez l'arrêter et l'inspecter:

 import pdb
pdb.set_trace()
 

4voto

Joshua Richardson Points 271

Une autre possibilité, sans ajouter de substance aux scripts python, est décrite ici:

https://wiki.python.org/moin/DebuggingWithGdb

Malheureusement, cette solution nécessite également de la prévoyance, du moins dans la mesure où vous devez utiliser une version de Python contenant des symboles de débogage.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X