Может ли код Java вызвать ошибку сегментации в Linux? - PullRequest
3 голосов
/ 28 марта 2019

Говорят, что java более безопасен в обработке памяти, чем C. В Си очень легко вызвать ошибку сегментации путем доступа к неверному указателю. Теперь я хотел бы знать, может ли код Java также вызвать ошибку сегментации. Может кто-нибудь привести пример?

Ответы [ 3 ]

3 голосов
/ 28 марта 2019

Как правило, в обычной программе Java у вас нет этой проблемы. Но да, если вы используете что-то вроде sun.misc.Unsafe, вы можете вызвать ошибку сегментации Но именно поэтому Unsafe называется Unsafe. Обычно вам не нужно его использовать, поэтому у вас нет этих проблем в вашем коде.

Для получения дополнительной информации: Где документировано sun.misc.Ansafe?

Сообщение об ошибке, основанное на ошибке сегментации с 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 голосов
/ 28 марта 2019

Ни в спецификации языка Java, ни в спецификации виртуальной машины Java не упоминается ошибка сегментации как поведение Java-программы или JVM.Это связано с тем, что «ошибка сегментации» - это специфическая для системы вещь (специфическая для операционных систем Unix), а Java предназначен для переносимости.Также эти спецификации не дают ничего , такого как ошибка сегментации, как разрешенное поведение.Кроме того, указанная семантика байтового кода Java не имеет ничего общего с «неопределенным поведением» C или C ++.Поэтому спецификация JVM не позволяет чистому Java-коду приводить к ошибке сегментации.

Если бы чистая Java-программа приводила к ошибке сегментации, это указывало бы на ошибку в самой JVM.Может ли JVM в Linux иметь ошибку, которая может вызвать ошибку сегментации?Конечно.Но в этом случае было бы правильно сказать, что Java-код вызвал ошибку сегментации?Думаю, нет;Я бы сказал, что «ошибка в JVM» вызвала ошибку сегментации.

Так что ответ на ваш вопрос, педантично, no .

Java также может вызывать «нативный код» (что на практике означает код C).Этот код C может содержать ошибки, поэтому он выполняет операции с неопределенным поведением, что впоследствии приводит к ошибке сегментации.Снова, педантично, Java-код не вызвал ошибку сегментации;Я бы сказал, что «ошибка в нативном коде» вызвала ошибку сегментации.

1 голос
/ 28 марта 2019

Java имеет интерфейс для выполнения собственного кода (JNI).При этом можно вызывать код, написанный на C, что делает возможными ошибки сегментации.

Ошибки в самом коде JVM могут вызывать ошибки сегментации, но это довольно редко.

В чистой Java,нет.Язык разработан так, чтобы разрешать только ссылки, которые указывают на действительные адреса или ноль.После последнего вы получаете исключение NullPointerException.

...