草庐IT

c++ - JNI C++ 调试技术?

coder 2024-02-17 原文

我有一个创建 JVM 并进行 JNI 调用的 Linux C++ 应用程序。我是 JNI 的新手,到目前为止,我发现在开发过程中调试我的应用程序的唯一有效方法是反复试验。有哪些技术可用于调试臭名昭著的“Java 运行时环境检测到 fatal error ”Java VM 崩溃?我如何知道问题是我的代码还是真正的 JVM 错误?

总的来说,到目前为止我所知道的显而易见的事情是:

  • 在代码中,始终检查从 JNI 调用返回的 jobject、class 和 jmethodID 值是否为 NULL 值,然后再继续。
  • 在适当的时候调用 env->ExceptionCheck() 以确保没有未决的异常。

目前,我遇到了错误报告文件中的堆栈跟踪没有帮助的问题:

# A fatal error has been detected by the Java Runtime Environment:
#
#  SIGSEGV (0xb) at pc=0x00002b137a99db59, pid=19977, tid=47362673452544
#
# JRE version: 6.0_20-b02
# Java VM: Java HotSpot(TM) 64-Bit Server VM (16.3-b01 mixed mode linux-amd64 )
# Problematic frame:
# V  [libjvm.so+0x40fb59]
  ... <snip> ...
Stack: [0x00007fff1964f000,0x00007fff1974f000],  sp=0x00007fff1974e050,  free space=3fc0000000000000018k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
V  [libjvm.so+0x40fb59]
V  [libjvm.so+0x3ecbe1]
C  [libDataFabric.so+0x1bb5b]  _Jv_JNIEnv::CallObjectMethod(__jobject*, _jmethodID*, ...)+0xe3
etc. ...

好的,所以我知道它在 env->CallObjectMethod() 中快要死了。在深入研究 JVM 代码之前,我检查了 GDB 中的所有参数,但我没有看到任何明显的 NULL 或奇怪值。当然,所有的 JNI 类(例如 jobject)都是无益的不透明的,因此我看不到它们的指针指向的是虚假数据还是真实数据。

对于此类问题有什么提示/建议/想法吗?

最佳答案

好的,这就是我解决上述问题的方法。有点乏味,但是,如果有足够的时间和努力,它最终会得到返回。

  1. 不要假设 env->CallMethod(jobj, meth_id, ...) 传递的值是正确的。如果这是它崩溃的地方,则很可能是一些难以发现但基本的问题有问题,例如传递的 methodId 与传递给 CallObjectMethod(...) 的 jobject 不匹配。我编写了一个简单的辅助方法 std::string getClassInfo(JNIEnv* env, jclass aJavaClass) 获取类上“toString”的 MethodID,调用该方法,并将结果作为 std 返回: :字符串。这告诉我一个物体是否如我所想。
  2. 在 JNI 调用之间随意散布调试输出语句。特别是输出类名(例如通过上述方法)将帮助您弄清楚天气对象是您认为的什么。
  3. 确保检查空方法 ID 并在每个 CallMethod(...) 之后调用 env->ExceptionCheck()。在 CallMethod(...) 之后检查 null 无济于事,因为 JNI 不知道 null 是否是有效的返回类型。
  4. 不要假设 JNI 会在出现问题的第一个迹象时崩溃。在它真正崩溃之前,我实际上是通过几个 JNI 调用传递了错误的对象类型。请参阅 #3 以确保您及早发现问题。

关于c++ - JNI C++ 调试技术?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4024718/

有关c++ - JNI C++ 调试技术?的更多相关文章

  1. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  2. ruby-on-rails - 无法让 rspec、spork 和调试器正常运行 - 2

    GivenIamadumbprogrammerandIamusingrspecandIamusingsporkandIwanttodebug...mmm...let'ssaaay,aspecforPhone.那么,我应该把“require'ruby-debug'”行放在哪里,以便在phone_spec.rb的特定点停止处理?(我所要求的只是一个大而粗的箭头,即使是一个有挑战性的程序员也能看到:-3)我已经尝试了很多位置,除非我没有正确测试它们,否则会发生一些奇怪的事情:在spec_helper.rb中的以下位置:require'rubygems'require'spork'

  3. ruby - JetBrains RubyMine 3.2.4 调试器不工作 - 2

    使用Ruby1.9.2运行IDE提示说需要gemruby​​-debug-base19x并提供安装它。但是,在尝试安装它时会显示消息Failedtoinstallgems.Followinggemswerenotinstalled:C:/ProgramFiles(x86)/JetBrains/RubyMine3.2.4/rb/gems/ruby-debug-base19x-0.11.30.pre2.gem:Errorinstallingruby-debug-base19x-0.11.30.pre2.gem:The'linecache19'nativegemrequiresinstall

  4. ruby-on-rails - 如何调试 cucumber 测试? - 2

    我有:When/^(?:|I)follow"([^"]*)"(?:within"([^"]*)")?$/do|link,selector|with_scope(selector)doclick_link(link)endend我打电话的地方:Background:GivenIamanexistingadminuserWhenIfollow"CLIENTS"我的HTML是这样的:CLIENTS我一直收到这个错误:.F-.F--U-----U(::)failedsteps(::)nolinkwithtitle,idortext'CLIENTS'found(Capybara::Element

  5. ruby - 使用 `+=` 和 `send` 方法 - 2

    如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:

  6. Unity 热更新技术 | (三) Lua语言基本介绍及下载安装 - 2

    ?博客主页:https://xiaoy.blog.csdn.net?本文由呆呆敲代码的小Y原创,首发于CSDN??学习专栏推荐:Unity系统学习专栏?游戏制作专栏推荐:游戏制作?Unity实战100例专栏推荐:Unity实战100例教程?欢迎点赞?收藏⭐留言?如有错误敬请指正!?未来很长,值得我们全力奔赴更美好的生活✨------------------❤️分割线❤️-------------------------

  7. MIMO-OFDM无线通信技术及MATLAB实现(1)无线信道:传播和衰落 - 2

     MIMO技术的优缺点优点通过下面三个增益来总体概括:阵列增益。阵列增益是指由于接收机通过对接收信号的相干合并而活得的平均SNR的提高。在发射机不知道信道信息的情况下,MIMO系统可以获得的阵列增益与接收天线数成正比复用增益。在采用空间复用方案的MIMO系统中,可以获得复用增益,即信道容量成倍增加。信道容量的增加与min(Nt,Nr)成正比分集增益。在采用空间分集方案的MIMO系统中,可以获得分集增益,即可靠性性能的改善。分集增益用独立衰落支路数来描述,即分集指数。在使用了空时编码的MIMO系统中,由于接收天线或发射天线之间的间距较远,可认为它们各自的大尺度衰落是相互独立的,因此分布式MIMO

  8. ruby - 如何计算 Liquid 中的变量 +1 - 2

    我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我

  9. ruby - Ruby 是否有类似于 Perl 的 "perl -d"的逐步调试器? - 2

    Ruby是否有逐步调试器,类似于Perl的“perl-d”? 最佳答案 ruby-debug(对于ruby1.8),debugger(对于ruby1.9),byebug(对于ruby​​2.0)以及trepanning系列都有一个-x或--trace选项。在调试器内部,命令setlinetrace将打开或关闭线路跟踪。这是themanualforruby-debug原来的答案已经修改,因为数据噪声文章的链接,唉,不再有效了。还添加了ruby​​-debug的后继者 关于ruby-Ruby

  10. arrays - Ruby 数组 += vs 推送 - 2

    我有一个数组数组,想将元素附加到子数组。+=做我想做的,但我想了解为什么push不做。我期望的行为(并与+=一起工作):b=Array.new(3,[])b[0]+=["apple"]b[1]+=["orange"]b[2]+=["frog"]b=>[["苹果"],["橙子"],["Frog"]]通过推送,我将推送的元素附加到每个子数组(为什么?):a=Array.new(3,[])a[0].push("apple")a[1].push("orange")a[2].push("frog")a=>[[“苹果”、“橙子”、“Frog”]、[“苹果”、“橙子”、“Frog”]、[“苹果”、“

随机推荐