2016-10-21 2 views
3

J'essaye d'automatiser l'instrumentation que je fais dans l'application, mais le problème est que je m'occupe d'applications qui ne se débranchent pas d'elles-mêmes après le traitement. Par exemple prendre n'importe quel pdfviewer/lecteur, Si j'ouvre un fichier le fichier est affiché et je peux voir que l'application a traité le fichier.Comment savoir que l'application a fini de traiter le fichier?

En traitant le fichier par l'application, ce que je veux dire est que le fichier a été affiché avec succès par l'application. L'application peut être n'importe quelle visionneuse de pdf de GUI pour le lecteur ex d'adobe, le xpdf, le foxitreader ou n'importe quelle visionneuse d'image pour ex gpicview, etc. Les formats de dossier peuvent être de n'importe quel type pas n'importe quel format de dossier spécifique.

Aussi je n'ai pas le code source d'une application, j'ai affaire à binaire de l'application.

Mais tout en automatisant le processus, je veux savoir quand l'application a traité le fichier. Ce que je peux d'abord penser, c'est qu'il y aurait des blocs de base qui disent qu'après avoir été exécuté, il a fini de traiter le fichier et de quitter mon instrumentation quand le bloc de base particulier a été exécuté.

Mais le problème ici est comment identifier ce bloc de base?

+1

Je pensais que pour les fichiers pdf volumineux, l'affichage n'utilisait que la lecture partielle des fichiers, la diffusion en continu des données si nécessaire lorsque l'utilisateur faisait défiler vers le bas ... Ce n'est pas fini. – Ped7g

Répondre

1

Probablement la chose la plus facile et la plus fiable que vous pouvez faire automatiquement pour les exécutables de boîte noire est de regarder leur utilisation du processeur. Une fois le chargement terminé, tous leurs threads doivent être inactifs (la plupart du temps), peut-être se réveiller de temps en temps s'ils attendent des événements avec un timeout non infini. (Et à partir de divers événements GUI comme le mouvement de la souris).

Assurez-vous d'avoir attendu suffisamment longtemps pour détecter la différence entre les E/S bloquées sur le disque et celles bloquées en attente d'une entrée utilisateur. (Sur les systèmes d'exploitation Unix, c'est la différence entre sommeil et veille disque, comme le montre D vs S dans des choses comme la liste des processus de top.)

Si vous ne voulez pas compter sur le système d'exploitation pour détecter le sommeil du disque par rapport au sommeil normal, attendez quelques fois plus longtemps que le temps de service de demande d'E/S disque (~ = quelques fois la latence du disque, plus faible si le processus testé est le seul processus à effectuer des E/S) . Si le processus de boîte noire n'a utilisé aucun temps de processeur dans cet intervalle, vous pouvez supposer que le chargement est terminé et que le fichier est affiché à l'écran.

Bien sûr, comme le signale @ Ped7g, il n'a peut-être pas analysé le fichier entier. Il peut le charger paresseusement, à la demande, lorsque l'utilisateur fait défiler un fichier PDF volumineux par exemple. L'observation de l'heure du processeur devrait être un moyen raisonnable de détecter quand un processus a terminé la mise à jour après l'envoi par programmation d'une commande de mise en page.

Je pense que vous devriez pouvoir obtenir de bons résultats fiables. Vous avez peut-être besoin d'une heuristique qui prend en compte plusieurs entrées, telles que les performances d'E/S système ou les demandes d'E/S sur disque si vous souhaitez que le processus soit chargé sans attendre le pire des cas.


Comme indiqué dans les commentaires, la recherche du processus pour atteindre EOF sur un descripteur de fichier n'est pas fiable à cette fin (il pourrait mmapper il). Je vais laisser ceci ici au cas où c'est intéressant ou utile pour n'importe qui, mais pour votre usage vous voudrez peut-être l'ignorer complètement. Au mieux, vous pouvez l'utiliser comme une entrée de votre heuristique pour décider quand un processus est terminé.

Sur la plupart des systèmes d'exploitation, il existe des fonctions permettant aux processus de suivre d'autres processus.Sur Linux, le principal est l'API ptrace. Des commandes telles que strace l'utilisent pour suivre les appels système. Je crois que Windows a quelque chose de similaire, et je suppose que OS X aussi.

Vous pouvez donc rechercher l'appel système open() sur le PDF pour trouver le bon fd, puis rechercher les appels système mmap, read() et close(). Si read() renvoie 0, c'est à EOF. S'il est fermé sans mmap, le processus est terminé (à moins qu'il ne l'ouvre à nouveau, ou utilise dup() ou dup2() pour une raison quelconque).

Vous pouvez analyser la sortie de texte de strace ou utiliser l'API ptrace vous-même.


Sinon, sur Linux, vous pouvez regarder la position du fichier dans /proc/<PID>/fdinfo/<FD>. D'autres systèmes d'exploitation ont probablement des fonctions similaires pour voir la position de fichier des descripteurs de fichiers/descripteurs de fichiers ouverts.

Par exemple, il se trouve que evince affiche un fichier PDF. Dans `/ proc/

$ ll /proc/4241/fd 
... 
lr-x------ 1 peter peter 64 Oct 21 06:43 14 -> /f/p/docs/agner_fog.microarchitecture.pdf # is anyone really surprised this is the PDF I had open? :P 
... 
$ ls -lL /proc/4241/fd/14  # follow the symlink to see the file size 
-rw-rw-r-- 1 peter peter 2078709 Feb 4 2016 /proc/4241/fd/14 

$ m /proc/4241/fdinfo/14  # alias for less 
pos: 2078709 
flags: 0100000 
mnt_id: 49 

Cela confirme ma conjecture le Evince aura la position de fin de fichier quand il est fait la lecture du fichier. Vous devriez probablement attendre plusieurs millisecondes et vérifier à nouveau, au cas où le logiciel en cours de test boucle à nouveau sur le fichier.

+0

Est-il nécessaire que close ou EOF indique que l'application a terminé le traitement, Supposons que j'ai lu le fichier dans un tampon, puis pour afficher les données que j'utilise ce tampon. En traitant le fichier je ne veux pas dire que le fichier a été lu complètement. Ce que je veux dire, c'est qu'il a été affiché avec succès. – user2823667

+0

@ user2823667: Oui, c'est un bon point. Probablement une combinaison de cela et d'attendre qu'il arrête d'utiliser le temps CPU sont votre meilleur pari. Attendez simplement qu'il ait lu le fichier et qu'il n'ait pas utilisé une quantité importante de temps de processeur pour ~ 40ms ou quelque chose, en fonction de la latence d'E/S de votre disque. (Évitez les faux positifs en attente d'E/S). –

+0

@ user2823667: Si vous pouvez savoir si l'un de ses threads a utilisé tout leur temps, ou s'ils se sont juste réveillés pour gérer un événement GUI et se rendormir tout de suite, ce serait la chose à rechercher, je pense . –