调试 JNI 模块中的特定访问冲突

Posted

技术标签:

【中文标题】调试 JNI 模块中的特定访问冲突【英文标题】:Debugging specific access violation in JNI module 【发布时间】:2012-06-07 09:02:35 【问题描述】:

我正在尝试通过带有 WinDBG 的 JNI 调试在基于 Java 的服务进程中运行的 C++ 组件中的访问冲突错误。 我目前面临两个问题:

    Java 本身使用第一次机会访问冲突异常来执行一些内部线程同步(至少看起来是这样),所以我不能只打破所有第一次机会访问冲突(根据 Java 错误数据库,这是有意的行为,所以我们不应该期待任何修复) 在外部代码中处理异常(应保护生产环境免受 C++ 代码的不当行为)

目前我看到了一种区分 Java 的 AV 和我的 AV 的方法 - Java 发生在属于没有加载任何符号的模块的地址,或者在内存的任何其他点,我有兴趣捕捉在已加载符号的地方发生的 AV。

似乎我有关于如何使用 WinDbg 实现它的所有元素,但无法将它们组合在一起:

sxe -c ".if (ln) gN" av

问题是我无法在 .if 语句中指定 ln 命令的输入(因为它需要一个表达式),而且我不确定如何检查 ln 的输出是否为空。

【问题讨论】:

【参考方案1】:

有趣的案例!我认为使用 ln 并检查输出会非常慢(而且也不知道该怎么做)。稍微不同的方法: 伪@$ip 应该包含异常的地址

First chance exceptions are reported before any exception handling.
 <cut cut >
 eip=0041625d
 0:000> r @$ip
 $ip=0041625d

使用rebase utility 将您的.dll 的默认加载地址更改为较高的值,并希望它们都被加载到那里。

然后你可以测试:@$ip > “RebaseAddr”

【讨论】:

【参考方案2】:

我们有一个本地 C++ 服务,它加载 jvm.dll 并调用它。大量的 AV 来自它 :-(。幸运的是,它们总是来自 jvm.dll 中最多两个不同的指令,所以我使用 sxe -c ".if (@eip == &lt;addr1&gt;) || (@eip == &lt;addr2&gt;) gn" av,这对我有用。

【讨论】:

以上是关于调试 JNI 模块中的特定访问冲突的主要内容,如果未能解决你的问题,请参考以下文章

使用Windows事件查看器调试崩溃

调试模式下内存映射向量的读取访问冲突

为什么调试器会抛出“读取访问冲突。这是nullptr”例外吗?

仅在调试期间在 C++ 中初始化 matlab-compiler dll / lib 时访问冲突

如何调试JNI程序

如何调试JNI程序