我正在尝试使我正在应用程序中执行的检测自动化,但是问题是我正在处理在处理后不会自行退出的应用程序。例如,使用任何pdfviewer / reader,如果我打开一个文件,则显示该文件,并且我可以看到该应用程序已处理该文件。

通过应用程序处理文件,我的意思是该文件已被应用程序成功显示。

应用程序可以是用于adobe阅读器,xpdf,foxitreader的任何GUI pdf查看器,或用于gpicview等的任何图像查看器。文件格式可以是任何类型,而不是任何特定的文件格式。

我也没有应用程序的源代码,我正在处理应用程序的二进制文件。

但是,在使过程自动化的同时,我想知道应用程序何时处理了文件。我最初可以想到的是会有一些基本块,这些基本块表示执行完文件后,当特定的基本块执行完后退出文件。

但是这里的问题是如何识别该基本块?

最佳答案

对于黑盒可执行文件,您可以自动执行的最简单,最可靠的操作可能就是查看它们的CPU使用率。当它们完成加载后,所有线程应该(大部分)处于空闲状态,如果它们等待具有非无限超时的事件,则可能会偶尔唤醒。 (以及来自其他GUI事件,例如鼠标移动)。

确保等待足够长的时间,以检测磁盘I / O阻塞与等待用户输入阻塞之间的区别。 (在类Unix的操作系统上,这是“磁盘睡眠”和“睡眠”之间的区别,如DStop的进程列表中所示。)

如果您不想依靠操作系统来检测磁盘睡眠与常规睡眠,则只需等待比最大磁盘I / O请求服务时间长几倍的时间(〜=磁盘延迟的几倍,如果此过程更低被测试是唯一执行I / O的过程。如果黑匣子进程在该时间间隔内未使用任何CPU时间,则可以假定它已完成加载并在屏幕上显示文件。

当然,正如@ Ped7g指出的那样,它可能没有解析整个文件。例如,当用户滚动浏览大型PDF时,它可能会按需延迟加载。监视CPU时间应该是一种合理的方式,可以以编程方式向其发送下一页命令后,检测进程何时完成更新。

我认为您应该能够从中获得良好的可靠结果。如果您想可靠地确定某个进程已完成加载而不必等待最坏的情况,则可能需要考虑多种输入的启发式方法,例如系统I / O性能或未完成的磁盘IO请求。



正如评论中所讨论的,为此目的,寻找在文件描述符上达到EOF的过程并不可靠(这可能会使其失灵)。万一它对任何人都有趣或有用,我将在此保留,但是为了您的使用,您可能希望完全忽略它。充其量,您可以将其用作启发式的输入,以决定何时加载进程。

在大多数OS上,有一些用于进程跟踪其他进程的工具。在Linux上,主要的是ptrace API。像strace这样的命令使用它来跟踪系统调用。我相信Windows具有类似的功能,并且我认为OS X也可以。

因此,您可以在PDF上寻找open()系统调用以找到正确的fd,然后在其上寻找mmap,read()和close()系统调用。如果read()返回0,则表示为EOF。如果没有mmap就关闭了它,则该过程将完成(除非再次打开它,或者出于某种原因使用了dup()或dup2())。

您可以解析strace的文本输出,或者自己使用ptrace API。



或者,在Linux上,您可以查看/proc/<PID>/fdinfo/<FD>中的文件位置。其他操作系统可能具有类似的功能,可以查看打开的文件描述符/文件句柄的文件位置。

例如,我碰巧打开了evince来显示PDF。在`/ 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


这证实了我的猜测,即在完成文件读取后,证据将在EOF处具有文件位置。您可能应该等待几毫秒,然后再次检查,以防被测软件再次遍历文件。

07-24 09:44
查看更多