Automatisation d'une application externe en Python

Automatisation d'une application externe en Python - Python - Programmation

Marsh Posté le 26-10-2009 à 09:22:46    

Bonjour,
 
je dois rendre accessible, via un module Python, GDB qui m'est fournit sous forme de '.exe'. Le but étant de pouvoir lancer une commande GDB, lire immédiatement le résultat, à n'importe quel moment d'un script dans le même process GDB. Après de multiple essais et recherches, je suis dans l'impasse.
 
J'ai trouvé comment exécuter des commandes et récupérer le résultat lorsque mon process est terminé, ce qui ne m'interesse pas au final car j'ai besoin de récupérer le résultat au fur et à mesure.
J'ai trouvé une super solution: pexpect, sauf que ça fonctionne sous linux et que je suis sous windows xp.
 
J'utilise la classe Popen de subprocess.
 
J'ai tenté l'utilisation de communicate:

Code :
  1. gdbProcess = Popen('P:/3_WORK/CPIOM/Soft/gdb.exe', shell = True, stdin = PIPE, stdout = PIPE)
  2. out,err = gdbProcess.communicate('help\r\n')
  3. print out


Ce code me donne déjà une erreur à la fin de l'exécution de la commande que je lis dans le pipe de sortie qui est:
"(gdb) Exception condition detected on fd 0
error detected on stdin"
A partir de là, mon process GDB a été fermé donc pas de possibilité de lui renvoyer une commande. Pourriez-vous m'éclairer?
 
Ma deuxième solution est d'utiliser les pipes d'entrée et sortie comme des fichiers. Sauf que le process n'étant pas fini, il n'y a pas de EOF dans stdout. Faut-il que je me contente de bidouiller ce que je peux lire dans stdout afin de récupérer seulement ce qui m'interesse, ou existe-t-il des manières plus élégantes et surtout plus propres de le faire?
De plus, je ne veux pas relire en permanence ce que j'ai déjà lu, il y a une possibilité de netoyer stdout ou vaut-il mieux utiliser la position de la dernière lecture dans le pipe?
 
J'ai l'habitude de programmer mais pas en Python donc si vous pouviez éclaircir ce sujet et me renseigner sur les divers exceptions qui peuvent être lever dans ce genre de manipulation.
 
Merci d'avance.

Reply

Marsh Posté le 26-10-2009 à 09:22:46   

Reply

Marsh Posté le 26-10-2009 à 14:10:55    

Bon, a force de recherche, j'ai trouvé quelque chose. Je vous le poste, ça peut toujours servir à quelqu'un, vu que je n'avais pas trouver de post similaire sur les forum.
 

Code :
  1. from subprocess import *
  2. GDB_PROMPT = '(gdb) '
  3. def read_until_prompt(gdbProcess):
  4.     buf = ''
  5.     while(True):
  6.         ch = gdbProcess.stdout.read(1)
  7.         if not ch:
  8.             return buf
  9.         buf += ch
  10.         if len(buf) < len(GDB_PROMPT):
  11.             continue
  12.         if buf.endswith(GDB_PROMPT):
  13.             outlen = len(buf) - len(GDB_PROMPT)
  14.             return buf[:outlen]
  15.        
  16. def send_cmd(gdbProcess, cmd):
  17.     cmd_line = cmd + '\n'
  18.     gdbProcess.stdin.write(cmd_line)
  19. def communicate(gdbProcess, cmd):
  20.     send_cmd(gdbProcess, cmd)
  21.     output = read_until_prompt(gdbProcess)
  22.     return output
  23. GDB_CMDLINE = 'P:/3_WORK/Soft/gdb.exe'
  24. gdbProc = Popen(GDB_CMDLINE , 0, shell=True, stdin=PIPE, stdout=PIPE, stderr=STDOUT)
  25. read_until_prompt(gdbProc)
  26. out = communicate(gdbProc, 'file P:/3_WORK/CPIOM/Soft/test')
  27. print out
  28. out = communicate(gdbProc, 'start')
  29. print out
  30. out = communicate(gdbProc, 's')
  31. print out
  32. out = communicate(gdbProc, 's')
  33. print out
  34. out = communicate(gdbProc, 's')
  35. print out
  36. out = communicate(gdbProc, 'c')
  37. print out
  38. #fermeture de gdb
  39. communicate(gdbProc, 'quit')

Reply

Marsh Posté le 17-11-2009 à 12:22:25    

Tiens.. j'avais presque la réponse à ma question de tout à l'heure sous les yeux...
 
Bref sympa d'avoir posté en tout cas, et j'ai donc essayé ce que tu as posté, mais ça me donne une nouvelle erreur à la ligne "gdbProcess.stdin.write(cmd_line)" de la fonction send_cmd :

Code :
  1. def send_cmd(gdbProcess, cmd):
  2.     cmd_line = cmd + '\n'
  3.     gdbProcess.stdin.write(cmd_line)


sur XP j'ai le message "IOError: [Errno 22] Invalid argument", et j'ai essayé sur Linux au cas où, et ça bloque au même endroit mais cette fois avec l'erreur "IOError: [Errno 32] Broken pipe"
 
Tout ça ne me rassure pas, et je commence à penser à un plan B, en attendant peut-être le cas où l'un de vous aurait une idée/explications(voire solution !) à ce problème de gestion de pipe...
 
Merci !

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed