- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我的老板想让我看看我是否可以在我们的 Java 客户端中为我们的测试人员编写一个“一键内存泄漏检查器”(因为这样我就可以花更少的时间自己在分析器下运行我们的完整手动测试套件;我们没有自动化测试套件)。
我找到了非常接近我需要的东西:Heap Walker我不得不稍微修改它以在 Windows 中的 VS 中编译(我认为它是为 Mac 下的 GCC 制作的)。但是当我运行它时,JVM 崩溃了。
我想要一个 native 堆栈跟踪以至少查看它崩溃的位置,如果我能找出发生了什么,但我不知道如何。我已经构建了一个“调试”DLL,但我仍然没有得到堆栈跟踪。既不在控制台上,也不在 JVM 生成的“hs_err_pidXXXX.log”文件中。
我已经有大约 15 年没有接触过任何 C/C++ 了;我仍然可以“猜测”代码的作用,但我忘记了调试是如何进行的(除了“无处不在的 printf”......),而且我从来没有必要在 JVM 中调试 native 代码。到目前为止,谷歌没有任何帮助;我可能使用了错误的术语进行搜索。
最佳答案
JVM 通常在崩溃转储中报告 native 堆栈跟踪。如果 hs_err_pid.log
中没有堆栈跟踪,则表示 JVM 无法从 PC 寄存器获取最后一帧,通常是因为它指向不可读的地址。
例如,如果 native 代码取消引用空函数指针,就会发生这种情况:
void (*func)() = 0;
func();
在这种情况下,PC 将为零,并且 JVM 不会打印跟踪。但是您仍然可以从堆栈中找到调用方 PC,因为返回地址通常在调用之前被压入堆栈。以下是如何在 hs_err_pid.log
中找到它:
Top of Stack: (sp=0x0000000002e2f438)
0x0000000002e2f438: 00007ffcf03f1030 00007ffcf041d000
^^^^^^^^^^^^^^^^
the return address (the address after the last valid instruction)
然后你可以在动态库
部分找到这个地址,并计算从dll开头的偏移量。
Dynamic libraries:
...
0x00007ffcf03f0000 - 0x00007ffcf0426000 C:\Java\Test\crash.dll
^^^^^^^^^^^^^^^^^^
offset = 0x00007ffcf03f1030 - 0x00007ffcf03f0000 = 0x1030
使用反汇编程序(例如 Visual Studio 的 dumpbin )将偏移量解码为代码中的特定函数/指令。
您还可以在 JVM 崩溃时将其附加到 Visual Studio 调试器。为此,您应该使用 -XX:+ShowMessageBoxOnError
运行 Java。以下窗口将邀请您连接调试器:
关于c++ - 如何在 Java native 代理出错时获取 *native* 堆栈跟踪?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38766360/
我是一名优秀的程序员,十分优秀!