Java代码能在Linux中引起分段错误吗?

3
据说Java在内存处理方面比C更加安全。在C中,通过访问无效指针很容易导致分段错误。现在我想知道Java代码是否也会导致分段错误。有人能举个例子吗?

实际上,我不知道哪个更安全:C程序由于访问无效指针而终止的进程,还是Java进程由于无效指针引发异常而被终止。在这两种系统中,您都可以捕获问题,但它真的可以在异常处理程序中修复吗?我认为Java增加的唯一安全性是,在C中执行“危险操作”要困难得多。 - U. Windl
3个回答

3
通常在普通的Java程序中,您不会遇到这个问题。但是如果您使用像sun.misc.Unsafe这样的东西,就可能会导致分段错误。但这就是为什么Unsafe被称为Unsafe。通常你不必使用它,所以你的代码不会出现这些问题。
更多信息: sun.misc.Unsafe文档在哪里? 有基于sun.misc.Unsafe的分段错误报告的错误: https://github.com/eclipse/openj9/issues/4153 下面是一个测试示例:
import java.lang.reflect.Field;

import sun.misc.Unsafe;

public class MainClass {

public static void main(String[] args)
        throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {

    Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
    theUnsafe.setAccessible(true);
    Unsafe unsafe = (Unsafe) theUnsafe.get(null);


     long ten = 10;
     byte size = 1;
     long mem = unsafe.allocateMemory(size);
     //Put here the wrong address!!!
     unsafe.putAddress(1, ten);
     //With this will work:
     //unsafe.putAddress(mem, ten);
     long readValue = unsafe.getAddress(mem);
     System.out.println("result: " + readValue);
}

}

当我在Ubuntu 18.04上执行时,我会得到以下输出:Java运行时环境检测到致命错误:

SIGSEGV(0xb)于pc=0x00007f05bdf04d27,pid=4145,tid=4147

JRE版本:OpenJDK Runtime Environment(10.0.2+13)(build 10.0.2+13-Ubuntu-1ubuntu0.18.04.4)

在Windows上,我认为将会有类似的致命错误描述。

祝大家好运!


2
Java语言规范和Java虚拟机规范都没有提到分段错误作为Java程序或JVM的行为。这是因为“分段错误”是一个系统特定的东西(仅适用于Unix操作系统),而Java旨在具有可移植性。这些规范也没有允许类似于分段错误的任何行为。此外,Java字节码的指定语义不像C或C++的未定义行为那样。因此,JVM规范不允许纯Java代码导致分段错误。
如果纯Java程序导致分段错误,则这将表明JVM本身存在错误。Linux上的JVM可能会出现导致分段错误的错误吗?当然可以。但在这种情况下,是否正确地说是“Java代码”导致了分段错误?我认为不是;我会说是“JVM中的错误”导致了分段错误。
因此,对你的问题的答案是,严谨地说,是“不”。
Java也可以调用"本地代码"(实际上指的是C代码)。该C代码可能存在漏洞,因此执行操作时会出现未定义行为,随后导致分段错误。同样地,严谨地说,Java代码并没有导致分段错误;我会说是“本地代码中的漏洞”导致了分段错误。

1

Java有一个用于执行本地代码(JNI)的接口。通过这个接口,可以调用用C编写的代码,从而可能导致分段错误。

JVM代码本身中的错误可能会导致分段错误,但这种情况相当罕见。

对于纯Java,不会出现这种情况。该语言被设计为仅允许引用指向有效地址或null。如果引用指向null,则会出现NullPointerException。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接