我正在尝试自动化我在应用程序中执行的检测,但问题是我正在处理在处理后不会自行退出的应用程序。例如,任何pdfviewer / reader,如果我打开文件,显示文件,我可以看到应用程序已处理该文件。
通过应用程序处理文件,我的意思是该文件已被应用程序成功显示。
应用程序可以是任何用于ex adobe reader,xpdf,foxitreader或任何图像查看器的GUI pdf查看器,用于ex gpicview等。文件格式可以是任何类型,而不是任何特定的文件格式。
此外,我没有应用程序的源代码,我正在处理应用程序的二进制文件。
但是在自动化流程的同时,我想知道应用程序何时处理了文件。我最初可以想到的是会有一些基本的块表示在执行它之后它已经完成处理文件并在特定的基本块执行时退出我的检测。
但这里的问题是如何识别基本块?
答案 0 :(得分:1)
对于黑盒可执行文件,您可以自动执行的最简单,最可靠的操作可能是查看其CPU使用率。当他们完成加载时,他们的所有线程都应该(大部分)空闲,如果他们等待具有非无限超时的事件,可能偶尔会唤醒。 (以及鼠标移动等各种GUI事件。)
确保等待足够长的时间来检测磁盘I / O上阻塞与阻止等待用户输入之间的区别。 (在类Unix操作系统上,这是磁盘睡眠和睡眠之间的区别,如D
与S
之类的top
进程列表中的strace
所示。)
如果您不想依赖操作系统检测磁盘睡眠与常规睡眠,请等待最长磁盘I / O请求服务时间的几倍(〜=磁盘延迟的几倍) ,如果被测过程是进行I / O的唯一过程,则降低。如果黑盒进程在该时间间隔内没有使用任何CPU时间,您可以假设它已完成加载并在屏幕上显示该文件。
当然,正如@ Ped7g指出的那样,它可能没有解析整个文件。当用户滚动浏览大型PDF时,它可能会根据需要懒洋洋地加载它。在以编程方式向其发送向下翻页命令后,观察CPU时间应该是检测进程何时完成更新的合理方法。
我认为你应该能够从中获得可靠的结果。您可能需要一种考虑多个输入的启发式方法,例如系统I / O性能或未完成的磁盘IO请求,如果您想要可靠地确定进程已完成加载而无需等待最坏情况。
正如评论中所讨论的那样,寻找在文件描述符上达到EOF的过程对于此目的是不可靠的(它可能是mmap)。我会把它留在这里,以防它对任何人有用或有用,但为了你的使用,你可能想完全忽略它。充其量,您可以使用它作为启发式的输入,以决定何时加载进程。
在大多数操作系统上,有一些工具可以跟踪其他进程。在Linux上,主要的是ptrace API。像/proc/<PID>/fdinfo/<FD>
这样的命令用它来跟踪系统调用。我相信Windows有类似的东西,我也认为OS X也是如此。
因此,您可以在PDF上查找open()系统调用以找到正确的fd,然后在其上查找mmap,read()和close()系统调用。如果read()返回0,则它在EOF处。如果它在没有mmap的情况下关闭,则该过程完成(除非它再次打开它,或者出于某种原因使用dup()或dup2())。
你可以解析strace的文本输出,或者自己使用ptrace API。
或者,在Linux上,您可以查看evince
中的文件位置。其他操作系统可能具有类似的工具,用于查看打开文件描述符/文件句柄的文件位置。
例如,我碰巧$ 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
打开显示PDF。在`/ proc /
<LinearLayout
android:id="@+id/buttons"
android:layout_below="@+id/first"
android:layout_above="@+id/second"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin">
<com.facebook.login.widget.LoginButton
android:id="@+id/login_with_facebook"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:text="@string/login_with_facebook" />
<Button
android:id="@+id/login_with_google"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:background="@drawable/google_button_press"
android:text="@string/login_with_google" />
<Button
android:id="@+id/login_with_twitter"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:text="@string/login_with_twitter" />
<Button
android:id="@+id/login_with_password"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:text="@string/login_with_password" />
</LinearLayout>
这证实了我的猜测,当它完成读取文件时,evince将在EOF中具有文件位置。您应该等待几毫秒并再次检查,以防被测试的软件再次循环遍历该文件。