java - jni 函数调用一些 gdb 不知道的 libc 函数

标签 java c performance file-io jvm

我有一个简单的 JNI 函数,我用它从 C 代码 UnixUtil.unsafeReadToByteArray 中将数据从文件读取到 byte[] 中,实现如下:

JNIEXPORT jlong JNICALL Java_net_xxxxxxx_UnixUtil_unsafeReadToByteArray
  (JNIEnv *e, jclass jc, jint fd, jbyteArray array, jlong offset, jlong count){
  signed char *array_native_ptr = (*e) -> GetByteArrayElements(e, array, NULL);
  ssize_t bytes_read = read(fd, array_native_ptr + offset, (size_t) count);
  (*e) -> ReleaseByteArrayElements(e, array, array_native_ptr, 0);
  return bytes_read;
}

分析运行该函数的 Java 应用程序显示了一些不清楚的结果。这是顶部:

enter image description here

HitTest 门的事情之一是来自 libc-2.27.so 的地址 0x18eb1f 的一些指令。我想了解它是什么,但 gdb 不知道它

(gdb) disas 0x18eb1f
No function contains specified address

Objdump'ing libc grep 我发现的地址

18eb0b:       72 0f                   jb     18eb1c <__nss_group_lookup@GLIBC_2.2.5+0x24ddc>
[...]
18eb1c:       48 89 d1                mov    %rdx,%rcx
18eb1f:       f3 a4                   rep movsb %ds:(%rsi),%es:(%rdi)

它看起来像是 __nss_group_lookup 的一部分,而 __nss_group_lookup 似乎不包含地址:

(gdb) disas __nss_group_lookup
Dump of assembler code for function __nss_passwd_lookup:
   0x0000000000169d40 <+0>:     mov    rax,QWORD PTR [rip+0x281121]        # 0x3eae68
   0x0000000000169d47 <+7>:     mov    DWORD PTR fs:[rax],0x26
   0x0000000000169d4e <+14>:    mov    eax,0xffffffff
   0x0000000000169d53 <+19>:    ret    
End of assembler dump. making the things more unclear then it was before.

让事情变得比以前更不清楚。

问题:您能否给出任何提示以了解为什么属于 __nss_group_lookup 的指令在调用时 HitTest jni_GetByteArrayElements/jni_ReleaseByteArrayElements 及其实际内容。

我的预期是因为 jni_GetByteArrayElements/jni_ReleaseByteArrayElements 通过 memcpybyte[] 从 Java 堆复制到 C 堆> 这将是 HitTest 门的。

最佳答案

显然您系统上的 libc 不包含调试符号(共享库中没有 .symtab 部分)。因此 gdb 显示距离 .dynsym 最近的导出符号,这与实际 HitTest 门的函数无关。

rep movsb 指令表明此片段是 memcpy 实现的一部分。

安装 libc-dbg 包(或者它在您的 Linux 发行版中的调用方式)。

例如在我的 Ubuntu 18.04 上,地址 __nss_group_lookup+0x24ddc 确实指向 memcpy 内部:

(gdb) disas __nss_group_lookup+0x24ddc
Dump of assembler code for function __memmove_avx_unaligned_erms:
   0x00007ffffef7ead0 <+0>:     mov    %rdi,%rax
   ...
   0x00007ffffef7eb1c <+76>:    mov    %rdx,%rcx
   0x00007ffffef7eb1f <+79>:    rep movsb %ds:(%rsi),%es:(%rdi)
   0x00007ffffef7eb21 <+81>:    retq

关于java - jni 函数调用一些 gdb 不知道的 libc 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56447869/

相关文章:

java - 为什么 'T.super.toString()' 和 'super::toString' 使用合成访问器方法?

c - 如何使用但不公开 c99 库中的内联函数?

c# - C# 中的 ArrayList 性能测试

java - CXF 如何在没有 Spring 的情况下在 CXF 端口上设置 SoapVersion

java - JTextfield 中的转义字符

c - OpenNL 的 LSCM 实现在其 UV 映射中显示了重叠的三角形

c - 段错误 - 使用 Pthreads 和矩阵的 C 程序

c# - 有谁知道一种更快的方法来执行 String.Split()?

Mysql查询执行速度非常慢

c# - 将 C# Activity 附加到一个 Android 应用程序中的 Java Activity