【问题标题】:Can java code cause segmentation fault in linux?java代码会导致linux中的分段错误吗?
【发布时间】:2023-03-30 22:59:02
【问题描述】:

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

【问题讨论】:

  • 实际上我看不出什么更安全:C 程序的进程因访问错误的指针而终止,或者 Java 进程因指针无效而因异常而终止。在这两个系统中,您都可以发现问题,但它真的可以在异常处理程序中修复吗?我认为 Java 添加的唯一安全性是,做“肮脏的事情”比在 C 中要困难得多。

标签: java linux segmentation-fault


【解决方案1】:

通常在普通的 Java 程序中你不会遇到这个问题。 但是是的,如果你使用像sun.misc.Unsafe 这样的东西,你可能会导致分段错误。但这就是为什么Unsafe 被称为Unsafe。通常您不必使用它,因此您的代码中不会出现此问题。

更多信息: Where is sun.misc.Unsafe documented?

基于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 上执行时,我得到以下输出: A fatal error has been detected by the Java Runtime Environment:

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

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

在 Windows 上,我认为这将是带有致命错误描述的类似输出。

祝大家好运!

【讨论】:

    【解决方案2】:

    Java 语言规范和 Java 虚拟机规范都没有提到分段错误是 Java 程序或 JVM 的行为。这是因为"segmentation fault" 是系统特定的东西(特定于 Unix 操作系统),而 Java 意味着可移植。这些规范也没有给出任何类似的分段错误作为允许的行为。此外,Java 字节码的指定语义没有 C 或 C++ 的 "undefined behaviour" 之类的东西。因此 JVM 规范不允许纯 Java 代码导致分段错误。

    如果纯 Java 程序导致分段错误,则表明 JVM 本身存在错误。 Linux 上的 JVM 是否有可能导致分段错误的错误?当然。但在那种情况下,是否应该说 Java 代码 导致了分段错误?我想不是;我会说“JVM 中的错误”导致了分段错误。

    所以你的问题的答案是,迂腐,

    Java 也可以调用 "native code"(实际上是 C 代码)。该 C 代码可能存在错误,因此它执行的操作具有未定义的行为,从而导致分段错误。同样,迂腐地,Java 代码 并没有导致分段错误。我会说“本机代码中的错误”导致了分段错误。

    【讨论】:

      【解决方案3】:

      Java 有一个用于执行本机代码 (JNI) 的接口。这样就可以调用用 C 编写的代码,从而使分段错误成为可能。

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

      对于纯 Java,没有。该语言旨在仅允许指向有效地址或空地址的引用。在后者之后,您会收到 NullPointerException。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-08-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-05-10
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多