我可以通过哪些方式调试此JNI代码?我看到它说有问题的框架是writeUSB函数,但我没有看到任何错误。这个Java应用程序是为Mac编写的,它们是一个JNI,用于与我们内部制造的硬件进行通信。我们硬件中的USB芯片来自cypress fx2lp Cy64713。我不确定为什么会导致SIGSEGV ...
这里完全转储 http://pastebin.com/BbgK796a
此JNI的完整来源是HERE https://bitbucket.org/snippets/partialdata/6L69r/ucs30interfacejni
这是netbeans中的调试器控制台,当我插入我们的硬件时打开它然后调试应用程序。
答案 0 :(得分:1)
向下滚动到堆栈跟踪的这一部分非常有用:
Stack: [0x000070000011a000,0x000070000021a000], sp=0x0000700000218010, free space=1016k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
C [UCS30InterfaceJNI.dylib+0x1146] _Z8writeUSBPP20IOUSBInterfaceStructPhi+0x46
C [UCS30InterfaceJNI.dylib+0xfcc] _Z15getSerialNumberPP20IOUSBInterfaceStruct+0x6c
C [UCS30InterfaceJNI.dylib+0x2b19] _Z14findUSBDevicesPc+0x259
C [UCS30InterfaceJNI.dylib+0x2f40] Java_ucs30interface_Main_findUCS30s+0x40
j ucs30interface.Main.findUCS30s()Ljava/lang/String;+0
虽然参数名称在某种程度上被C ++编译器破坏了,但您可以看到程序失败时调用的函数的名称。 最上面的一个匹配像writeUSB(IOUSBInterfaceStruct **,int *)这样的函数。找到这样的函数并查找它使用指针的地方。该函数中的一个指针可能指向从未分配或已被释放的内存。
<强>更新强>
如果您无法在顶级功能中看到问题,则可能在调用它的函数中。例如,如果调用它的函数(getSerialNumber)使用可能导致相同SIGSEGV的错误指针调用它。在使用Netbeans 8.1 RC2的Linux上,我可以使用调试器从java代码转到C ++代码。你可以在Mac上试试,但我不确定它是否有效。如果没有调试器,您可以使用printf&#39; s。在每行代码之间放一个。显示的打印件位于坏线之前,而未显示的打印件位于坏线之后。您应确保所有printf以\n
结束并刷新stdout,否则当SIGSEGV发生时,仍可以缓冲打印。您还可以将函数拆分为从此函数调用的较小函数,这也将有助于缩小范围。打印变量的值。作为字符串的命令需要在它来自的数组结束之前具有终止0。您可能需要查看调用代码以了解该数组的长度。作为指针指针的接口可能会导致失败,无论是作为坏指针还是指向坏指针。问题可能在writeUSB调用的函数之一,如WritePipe,如果该函数被内联,它可能不会出现在堆栈跟踪上。