我在Linux上,我有一个Java应用程序(JAR存档),它使用exec()来完成它的工作。我需要找出哪个命令是该应用程序exec()uting ...我尝试了strace和jstack但没有任何结果。假设应用程序正在调用exec(“ls”),我可以通过点击上述程序的输出来找到ls命令吗?
所以问题是: 有没有一种简单的方法来观察使用exec()执行的Java应用程序是什么?
编辑以获得更好的情况概述:
假设在Java应用程序中我有一个带onclick监听器的按钮,它从另一个类调用静态函数。在该函数中调用exec("ls");
。
当我点击那个按钮时,我在strace中看到了这个:
futex(0x7f14a6f799d0, FUTEX_WAIT, 4968, NULLDownload button clicked !
Trying SCP FROM...
<unfinished ...>
在调用exec()
之前尝试SCP FROM ..就是我在那个按钮处理程序中的sout。
另一个编辑:
谢谢大家,但我从操作系统的角度来看...假设我是系统管理员,我下载了JAR。我想(从外面)知道JAR在做什么 - 我只对从exec()
开始的程序感兴趣
所以我尝试了strace
,但它没有显示从exec调用该命令的任何内容......也许它记录了太多的低级别调用...
然后我尝试jstack -m
但是我找不到任何看起来像exec的命令。我试过捣蛋,但没有运气。
答案 0 :(得分:2)
好的,我要提出的建议是 veeeeeeeeeery 基本的做事方式,但它可能就是你要找的东西。
您可能知道,.jar
文件只是一个由Java .class
文件组成的ZIP存档。如果您只是需要查看将要执行哪些命令, 和 如果您知道应该执行它们的类,您可以只提取类使用gzip
从jar文件中获取文件,然后使用strings
查找命令。
例如,这是我能想到的最简单的使用exec()
的课程:
import java.io.IOException;
public class Main {
public static void main(String[] args) {
try {
Runtime.getRuntime().exec("/bin/ls");
} catch (IOException ignored) {}
}
}
如果你做strings Main.class
,你应该得到这样的东西:
[...]$ strings Main.class
<init>
Code
LineNumberTable
LocalVariableTable
this
LMain;
main
([Ljava/lang/String;)V
args
[Ljava/lang/String;
StackMapTable
SourceFile
Main.java
/bin/ls
java/io/IOException
Main
java/lang/Object
java/lang/Runtime
getRuntime
()Ljava/lang/Runtime;
exec
'(Ljava/lang/String;)Ljava/lang/Process;
如您所见,/bin/ls
可以被识别为字符串。这应该在大多数情况下都有效,除非你的Java程序以奇怪的方式构造命令,比如使用char数组在运行时创建命令字符串只是为了掩盖正在执行的命令(在这种情况下我非常怀疑这样的程序)。
但是,如果你想看到实时执行的命令,我担心你需要求助于一些监控工具,因为大多数命令都会过于短暂,甚至不会出现在{ {1}}之类的。
编辑:关于top
:我查看了Java's native C code for UNIX systems,它似乎实际上使用strace
系统调用来运行使用execvpe()
启动的所有命令:< / p>
Runtime.exec()
因此,从理论上讲,您应该能够运行 execvpe(argv[0], argv, envv);
列出所执行的每个命令(以及对strace -e execvpe <java command...>
的所有其他调用 - 您需要再过滤一下,那是真的。