我目前正在使用 HP Fortify 工具扫描项目中的安全漏洞。在扫描时,Fortify 的 CLI 允许构建工具集成到其 CLI 命令中,以便构建并同时扫描项目中存在的文件。我正在使用以下命令:
sourceanalyzer -b mcapbookvalue -gradle -verbose ./gradlew -x test --console=verbose -debug --continue assemble
但是构建陷入了困境:
2020-01-14T12:31:39.836-0500 [DEBUG] [org.gradle.cache.internal.DefaultFileLockManager] Lock acquired on daemon addresses registry.[0K
2020-01-14T12:31:39.836-0500 [DEBUG] [org.gradle.cache.internal.DefaultFileLockManager] Releasing lock on daemon addresses registry.
2020-01-14T12:31:39.836-0500 [DEBUG] [org.gradle.cache.internal.DefaultFileLockManager] Waiting to acquire shared lock on daemon addresses registry.
2020-01-14T12:31:39.836-0500 [DEBUG] [org.gradle.cache.internal.DefaultFileLockManager] Lock acquired on daemon addresses registry.
2020-01-14T12:31:39.836-0500 [DEBUG] [org.gradle.cache.internal.DefaultFileLockManager] Releasing lock on daemon addresses registry.
如果我在不使用集成的 Fortify 命令的情况下构建项目,仅使用以下命令,则构建成功:
./gradlew -x test --console=verbose -debug --continue assemble
我无法弄清楚为什么 gradle 构建会卡住。阅读和理解线程转储日志中发生的事情超出了我的能力范围。
线程转储(jstack 日志):https://drive.google.com/file/d/13b6vdDGCWoke7McM_FJROVOkvTaRGqem/view?usp=sharing
如果能得到任何帮助那就太好了。
提前致谢。
所以线程转储确实是开发人员查看的工具。用户(甚至像你我这样的其他软件开发人员)在不了解代码库的情况下将无法真正调试问题。很高兴您将其包含在内,因此如果有更有知识的人出现,他们可以给我们一些见解。
话虽这么说,如果您之前在自己的项目中使用过线程转储,您就可以开始了解可能发生的情况。再说一次,我不是 gradle 开发人员,所以对此持保留态度。但本质上我们只对状态为
WAITING (on object monitor)
的线程感兴趣。而且只有 4 个。 Finalizer
、Common Cleaner
、Daemon #20
和执行人员。 Finalizer
和 Common Cleaner
没有做任何工作,因此可以忽略它们。 Daemon #20
似乎是一个 gradle 守护线程,它启动了 gradle 脚本,因此它只是等待脚本完成(这是预期的)。所以执行工作人员看起来像这样:
"Execution worker for ':'" #42 prio=5 os_prio=0 cpu=2818.31ms elapsed=196.05s tid=0x00007f9358702800 nid=0x16cfe in Object.wait() [0x00007f93428f1000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait([email protected]/Native Method)
- waiting on <0x00000000ea1d41f8> (a java.lang.ProcessImpl)
at java.lang.Object.wait([email protected]/Object.java:328)
at java.lang.ProcessImpl.waitFor([email protected]/ProcessImpl.java:495)
- waiting to re-lock in wait() <0x00000000ea1d41f8> (a java.lang.ProcessImpl)
at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0([email protected]/Native Method)
at jdk.internal.reflect.NativeMethodAccessorImpl.invoke([email protected]/NativeMethodAccessorImpl.java:62)
at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke([email protected]/DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke([email protected]/Method.java:566)
有趣的部分是
java.lang.ProcessImpl.waitFor
,所以看起来 gradle 只是在等待外部进程完成。这似乎不是死锁情况或任何奇怪的锁定问题,这是个好消息。基本上,HP 工具只是在运行,尚未完成。突然间,halting problem
变得太真实了。是要完成还是挂起?我们无从得知。
但是我要做的是查看 Linux 上的
top
输出,并找到 gradle 启动的进程(即 HP 进程)。该进程的 CPU 使用率是否波动?那么也许它只是在做一些需要一段时间的事情,要有耐心,让它运行,看看它是否完成。如果它没有运行,那么你就会遇到更大的问题。我敢打赌,在 Linux 上,HPI 软件会尝试扫描一些不应该扫描的内容,这可能是配置问题或 Linux 与 Windows 之间的差异。完全是猜测,但只是我的直觉。
我的下一步可能是看看是否可以在 gradle 之外的 Linux 上手动运行该工具。我们从转储中发现,gradle 似乎并未导致该问题,因此让我们隔离 HP 工具,看看是否可以从中获取更多错误消息或其他内容。需要考虑的一些事项:
我今天没有给你一个完整的答案,所以只是给你一个解决这个问题的策略。祝你好运。
Gradle 构建过程似乎在获取守护进程地址注册表上的锁时陷入困境,这可能会导致运行 Fortify 命令时构建过程中的延迟或挂起。
一个潜在的解决方案是在运行 Fortify 的 sourceanalyzer 命令时尝试将
--no-daemon
选项添加到 Gradle 命令中。此选项会禁用 Gradle 守护进程,这可能有助于解决与锁定或争用相关的任何问题。
以下是如何修改命令以包含
--no-daemon
选项:
sourceanalyzer -b mcapbookvalue -gradle -verbose ./gradlew --no-daemon -x test --console=verbose -debug --continue assemble
将
--no-daemon
添加到 Gradle 命令中可指示 Gradle 在不使用守护进程的情况下运行。这有时可以在守护进程导致意外行为或延迟的情况下有所帮助。
尝试运行修改后的命令,看看它是否解决了 Gradle 构建卡住的问题。如果问题仍然存在,可能需要进一步调查以确定构建过程中锁定问题的根本原因。