gpt4 book ai didi

java - dlopen() 中的 BUS_ADRERR

转载 作者:太空宇宙 更新时间:2023-11-04 10:01:49 24 4
gpt4 key购买 nike

dlopen() 期间,什么可能导致 BUS_ADRERR 信号?我收到了很多来自不同用户的此类崩溃报告。

一些注意事项:

  1. 它发生在不同的库中(我们的应用程序使用了一些)
  2. si_addr 信号指向加载库的地址。这让我很困惑。
  3. 始终有足够的系统内存可用。
  4. 用户说应用程序将在第二次尝试时正确启动。
  5. 我们的应用程序在加载它们之前从 ZIP 中提取库。
  6. 研究 journalctl 没有任何兴趣。

典型的崩溃报告(由 Java 生成):

Stack: [0x00007f284919b000,0x00007f284939c000],  sp=0x00007f2849397258,  free space=2032k
Native frames: (J=compiled Java code, A=aot compiled Java code, j=interpreted, Vv=VM code, C=native code)
C [ld-linux-x86-64.so.2+0x1fa6f]
C [ld-linux-x86-64.so.2+0x8ffc]

Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
j java.lang.ClassLoader$NativeLibrary.load0(Ljava/lang/String;Z)Z+0 java.base@10.0.1
j java.lang.ClassLoader$NativeLibrary.load()Z+53 java.base@10.0.1
j java.lang.ClassLoader$NativeLibrary.loadLibrary(Ljava/lang/Class;Ljava/lang/String;Z)Z+216 java.base@10.0.1
j java.lang.ClassLoader.loadLibrary0(Ljava/lang/Class;Ljava/io/File;)Z+46 java.base@10.0.1
j java.lang.ClassLoader.loadLibrary(Ljava/lang/Class;Ljava/lang/String;Z)V+48 java.base@10.0.1
j java.lang.Runtime.load0(Ljava/lang/Class;Ljava/lang/String;)V+57 java.base@10.0.1
j java.lang.System.load(Ljava/lang/String;)V+7 java.base@10.0.1
<snip>

siginfo: si_signo: 7 (SIGBUS), si_code: 2 (BUS_ADRERR), si_addr: 0x00007f27deec7880

<snip>

7f27dec43000-7f27decc1000 r-xp 00000000 08:08 1054117 <snip>/libswt-gtk-4922r22.so
7f27decc1000-7f27deec0000 ---p 0007e000 08:08 1054117 <snip>/libswt-gtk-4922r22.so
7f27deec0000-7f27deec8000 rw-p 0007d000 08:08 1054117 <snip>/libswt-gtk-4922r22.so
7f27deec8000-7f27deecb000 r-xp 00285000 08:08 1054117 <snip>/libswt-gtk-4922r22.so

<snip>

Memory: 4k page, physical 3902428k(1540768k free), swap 3998716k(3998716k free)

最佳答案

SIGBUS 在 Linux/x86 系统上非常罕见。

发生这种情况的一种情况是 mmaped 文件被截断。来自 man mmap :

SIGBUS Attempted access to a portion of the buffer that does not
correspond to the file (for example, beyond the end of the
file, including the case where another process has truncated
the file).

Our application extracts the libraries from ZIP before loading them.

一个疯狂的猜测:你有一个竞争条件,你可以同时从两个单独的线程执行这个提取。

第一个线程从 ZIP 存档中提取 libswt-gtk-4922r22.so,然后 dlopen 将其保存。 dlopen mmaps 文件,重新定位它,并调用库初始化程序。

当库初始化程序正在运行时,第二个线程决定必须提取库(这是错误),并在将新的(相同的)内容写入其中之前截断 .so 文件。一旦截断完成,第一个线程(仍在运行库初始化程序)就会被 SIGBUS 杀死。

通常的修复是确保“检查文件是否存在,如果不存在则提取”在关键部分完成。

关于java - dlopen() 中的 BUS_ADRERR,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55589086/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com