Gradle 构建停留在“等待获取守护进程地址注册表的共享锁”。

Sek*_*ray 13 java build jstack gradle fortify

我目前正在使用 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.
Run Code Online (Sandbox Code Playgroud)

如果我在不使用 Fortify 的集成命令的情况下构建项目,则构建成功,仅使用:

./gradlew -x test --console=verbose -debug --continue assemble

我无法弄清楚为什么 gradle 构建卡住了。阅读和理解线程转储日志中发生的事情超出了我的范围。

线程转储(jstack 日志):https ://drive.google.com/file/d/13b6vdDGCWoke7McM_FJROVOkvTaRGqem/view?usp = sharing

如果能得到任何帮助就太好了。

提前致谢。

chu*_*ubs 0

所以线程转储确实是开发人员查看的工具。用户(甚至像你我这样的其他软件开发人员)在不了解代码库的情况下将无法真正调试问题。很高兴您将其包含在内,因此如果有更有知识的人出现,他们可以给我们一些见解。

话虽这么说,如果您之前在自己的项目中使用过线程转储,您就可以开始了解可能发生的情况。再说一次,我不是 gradle 开发人员,所以对此持保留态度。但本质上我们只对状态为 的线程感兴趣WAITING (on object monitor)。而且只有 4 个。 FinalizerCommon CleanerDaemon #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(java.base@11.0.5/Native Method)
    - waiting on <0x00000000ea1d41f8> (a java.lang.ProcessImpl)
    at java.lang.Object.wait(java.base@11.0.5/Object.java:328)
    at java.lang.ProcessImpl.waitFor(java.base@11.0.5/ProcessImpl.java:495)
    - waiting to re-lock in wait() <0x00000000ea1d41f8> (a java.lang.ProcessImpl)
    at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(java.base@11.0.5/Native Method)
    at jdk.internal.reflect.NativeMethodAccessorImpl.invoke(java.base@11.0.5/NativeMethodAccessorImpl.java:62)
    at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(java.base@11.0.5/DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(java.base@11.0.5/Method.java:566)
Run Code Online (Sandbox Code Playgroud)

有趣的是,java.lang.ProcessImpl.waitForgradle 似乎只是在等待外部进程完成。这似乎不是死锁情况或任何奇怪的锁定问题,这是个好消息。基本上,HP 工具只是在运行,尚未完成。突然halting problem变得太真实了。是要完成还是挂起?我们不知道。

但我要做的是查看topLinux 上的输出,并找到 gradle 启动的进程(即 HP 进程)。该进程的 CPU 使用率是否波动?那么也许它只是在做一些需要一段时间的事情,要有耐心,让它运行,看看它是否完成。如果它没有运行,那么你就会遇到更大的问题。我敢打赌,在 Linux 上,HPI 软件会尝试扫描一些不应该扫描的内容,这可能是配置问题或 Linux 与 Windows 之间的差异。完全是猜测,但只是我的直觉。

我的下一步可能是看看我是否可以在 gradle 之外的 Linux 上手动运行该工具。我们从转储中发现,gradle 似乎并未导致该问题,因此让我们隔离 HP 工具,看看是否可以从中获取更多错误消息或其他内容。需要考虑的一些事项:

  • gradle 是否为其提供了足够的内存来运行?如果您手动运行的可执行文件与 Gradle 的不同,则可能是 Linux 与 Windows 中的配置不同。
  • 是否有涉及 HP 工具的 gradle 插件?是否需要在 Linux 上配置一些配置选项?
  • 是否有足够的可用内存供 HP 工具和 gradle 在 Linux 机器上运行?也许您的 Linux 机器的内存上限与 Windows 机器不同。如果你能装一个更大的机器也许就能解决 Linux 的问题。

今天我没有给你一个完整的答案,所以只是给你一个解决这个问题的策略。祝你好运。