JNA调用中的间歇性内存损坏错误

时间:2018-11-29 07:32:27

标签: java c memory-leaks native jna

我们非常简单地要求从Java调用几个本机函数。我们正在使用JNA进行这些本地调用。

编辑:我们没有任何自定义本机代码。我们正在调用Linux Kernel C库函数。

我们收到了非常奇怪的内存损坏错误,例如

  • `/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.191.b12-0.el7_5.x86_64/jre/bin/java'中的错误:malloc():内存损坏:0x00007f9b7849fc40
  • `/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.191.b12-0.el7_5.x86_64/jre/bin/java'中的错误:大小损坏与prev_size:0x00007f253c4470f0
  • SIGSEGV(0xb)

程序甚至挂断了几次。这些错误是间歇性的。

一些在JNA调用中使用结构的标准示例/文档会有所帮助。


这是我们的具有本地功能的库包装程序:

https://github.com/tmtsoftware/csw/blob/master/csw-time-client/src/main/scala/csw/time/client/internal/TimeLibrary.java

这些是本地模型,它们映射到C中的结构:

https://github.com/tmtsoftware/csw/tree/master/csw-time-client/src/main/scala/csw/time/client/internal/native_models

这就是我们访问库函数的方式:

val timeVal = new NTPTimeVal()
TimeLibrary.ntp_gettimex(timeVal)
println(timeVal.tai)

您可以参考TimeServiceImpl.scala以获得更清晰的说明。

https://github.com/tmtsoftware/csw/blob/master/csw-time-client/src/main/scala/csw/time/client/internal/TimeServiceImpl.scala

有人可以告诉我们我们到底在做什么错吗?

1 个答案:

答案 0 :(得分:1)

ntptimeval和相关结构中有一些保留字段:

struct ntptimeval
{
  struct timeval time;  /* current time (ro) */
  long int maxerror;    /* maximum error (us) (ro) */
  long int esterror;    /* estimated error (us) (ro) */
  long int tai;     /* TAI offset (ro) */

  long int __glibc_reserved1;
  long int __glibc_reserved2;
  long int __glibc_reserved3;
  long int __glibc_reserved4;
};

your code中没有的内容:

public class NTPTimeVal extends Structure {
    public TimeVal time;        /* Current time */
    public Long maxerror;       /* Maximum error */
    public Long esterror;
    public int tai;
}

如果这些保留字段恰好在您的glibc版本中使用,则可以解释堆损坏。

我还将仔细检查您获得的数据。如果某些字段包含奇怪的值,则可能意味着字段大小/对齐问题,这也可能表示结构短于所需的长度。