Notice: file_put_contents(): Write of 23311 bytes failed with errno=28 No space left on device in /var/www/tgoop/post.php on line 50
Алло, это отладочная?@gdb_dbg P.76
GDB_DBG Telegram 76
An Exceptional Case

Недавние разговоры про сигналы и NPE из-за sudo kill -11 разблокировали у меня воспоминание про давний пост от Игоря на схожую тему в нашем старом блоге. С его разрешения раскапываю еще одну стюардессу и публикую здесь соответствующую адаптацию.

--

Итак, как вы помните, исполнение некоторых инструкций может спровоцировать поднятие сигнала операционной системой, чем рантайм с удовольствием пользуется, перехватывая их для своих коварных целей. Самый простой и обсужденный ранее пример - это SIGSEGV, который перехватывается рантаймом и трактуется, как NullPointerException.

Но может ли одна инструкция спровоцировать поднятие двух разных сигналов в зависимости от пути исполнения? На самом деле да, например, вот такую красоту как-то сгенерил наш компилятор:

idiv dword [ecx+10H]


С одной стороны, здесь есть налчек: он спрятан в операнде деления (там как раз происходит разыменование по офсету первого поля объекта), а потом собественно деление. Само деление тоже может пройти неудачно - если получившийся аргумент был равен 0, полетит другой сигнал: SIGFPE. Этот сигнал в свою очередь тоже может быть перехвачен рантаймом, который после этого выбросит джавовский ArithmeticException.

--

На самом деле для нас в рантайме такая ситуация (маленький шедевр компилятора, без иронии) оказалась полной неожиданностью.

Обработать два сигнала из одной инструкции мы, допустим, смогли бы (просто аккуратным диспатчем по типу сигнала), но тут ситуация была сильно хуже.

Дело в том, что на самом деле оригинальный код был какой-то такой:

int foo(Bar k) {
return k.x;
}

void baz() {
Bar k(42);
int r = x / foo(k);
}


Т.е. по факту деление и обращение к полю происходило в разных методах: обращение в foo, а деление в baz. Компилятор просто проинлайнил foo в baz, что позволило ему пойти с оптимизациями дальше и объединить налчек и деление.

И это все прекрасно, но зачем мы все это делаем? Чтобы потом в рантайме выбросить в одному случае NullPointerException, а в другом ArithmeticException. И вот в чем беда: стектрейсы у них должны отличаться, один должен заканчиваться на foo -> baz, а второй просто на baz.

Ну, как должны, вообще JVM не обязана хоть сколько-нибудь содержательные стектрейсы предоставлять, в спеке про это нет ни слова. Можно просто всегда возвращать пустой (почти пустой) стектрейс и спокойно пройти JCK, но клиентам это почему-то очень не нравится.

Получается, что чтобы сделать все красиво, для одной инструкции нужны два набора метаифнормации (включающей в себя информацию об инлайне), с которой рантайм будет консультироваться при построении стектрейса. И вот к этому мы оказались максимально не готовы: вся система хранения метаинформации ожидала, что на одну инструкцию может быть только один такой набор, что звучало вполне логично до описанного случая.

--

Что с этим делать? Можно было прокачивать систему сбора метаинформации, это бы резко усложнило ее архитекутуру и увеличило стоимость поддержки в рантайме. И ради чего? Ради одной хитрой интсрукции? С другой стороны, можно было пренебречь точностью стектрейса одного из исключений (ведь JVM не обязана строить их точно, да вообще хоть как-то!). Это позволило бы оставить только один набор метаинформации, хотя и чуть уменьшило бы удобство пользователя. В целом, приемлемый компромисс, так тогда и поступили.

--

Но на будущее задумались: так ли вообще нужна такая оптимизация? Нужен ли этот маленький шедевр компилятора? По факту кроме эстетического удовольствия смотрящего в асмы, он ничего и не давал, место в коде было не очень горячее. Поэтому при последующей поддержке новых платформ решили, что такие оптимизации делать просто не стоит, а компиялтору стоит быть попроще.

Иногда более простое (но не такое красивое) решение приносит больше пользы в глобальной перспективе, так случилось и здесь. Больше мы инструкций, которые могут поднимать по два сигнала в сгенерированном коде, не видели, так что это был действительно исключительный случай.

#откопали_стюардессу
#дух_машины
👍7💯4🔥2



tgoop.com/gdb_dbg/76
Create:
Last Update:

An Exceptional Case

Недавние разговоры про сигналы и NPE из-за sudo kill -11 разблокировали у меня воспоминание про давний пост от Игоря на схожую тему в нашем старом блоге. С его разрешения раскапываю еще одну стюардессу и публикую здесь соответствующую адаптацию.

--

Итак, как вы помните, исполнение некоторых инструкций может спровоцировать поднятие сигнала операционной системой, чем рантайм с удовольствием пользуется, перехватывая их для своих коварных целей. Самый простой и обсужденный ранее пример - это SIGSEGV, который перехватывается рантаймом и трактуется, как NullPointerException.

Но может ли одна инструкция спровоцировать поднятие двух разных сигналов в зависимости от пути исполнения? На самом деле да, например, вот такую красоту как-то сгенерил наш компилятор:

idiv dword [ecx+10H]


С одной стороны, здесь есть налчек: он спрятан в операнде деления (там как раз происходит разыменование по офсету первого поля объекта), а потом собественно деление. Само деление тоже может пройти неудачно - если получившийся аргумент был равен 0, полетит другой сигнал: SIGFPE. Этот сигнал в свою очередь тоже может быть перехвачен рантаймом, который после этого выбросит джавовский ArithmeticException.

--

На самом деле для нас в рантайме такая ситуация (маленький шедевр компилятора, без иронии) оказалась полной неожиданностью.

Обработать два сигнала из одной инструкции мы, допустим, смогли бы (просто аккуратным диспатчем по типу сигнала), но тут ситуация была сильно хуже.

Дело в том, что на самом деле оригинальный код был какой-то такой:

int foo(Bar k) {
return k.x;
}

void baz() {
Bar k(42);
int r = x / foo(k);
}


Т.е. по факту деление и обращение к полю происходило в разных методах: обращение в foo, а деление в baz. Компилятор просто проинлайнил foo в baz, что позволило ему пойти с оптимизациями дальше и объединить налчек и деление.

И это все прекрасно, но зачем мы все это делаем? Чтобы потом в рантайме выбросить в одному случае NullPointerException, а в другом ArithmeticException. И вот в чем беда: стектрейсы у них должны отличаться, один должен заканчиваться на foo -> baz, а второй просто на baz.

Ну, как должны, вообще JVM не обязана хоть сколько-нибудь содержательные стектрейсы предоставлять, в спеке про это нет ни слова. Можно просто всегда возвращать пустой (почти пустой) стектрейс и спокойно пройти JCK, но клиентам это почему-то очень не нравится.

Получается, что чтобы сделать все красиво, для одной инструкции нужны два набора метаифнормации (включающей в себя информацию об инлайне), с которой рантайм будет консультироваться при построении стектрейса. И вот к этому мы оказались максимально не готовы: вся система хранения метаинформации ожидала, что на одну инструкцию может быть только один такой набор, что звучало вполне логично до описанного случая.

--

Что с этим делать? Можно было прокачивать систему сбора метаинформации, это бы резко усложнило ее архитекутуру и увеличило стоимость поддержки в рантайме. И ради чего? Ради одной хитрой интсрукции? С другой стороны, можно было пренебречь точностью стектрейса одного из исключений (ведь JVM не обязана строить их точно, да вообще хоть как-то!). Это позволило бы оставить только один набор метаинформации, хотя и чуть уменьшило бы удобство пользователя. В целом, приемлемый компромисс, так тогда и поступили.

--

Но на будущее задумались: так ли вообще нужна такая оптимизация? Нужен ли этот маленький шедевр компилятора? По факту кроме эстетического удовольствия смотрящего в асмы, он ничего и не давал, место в коде было не очень горячее. Поэтому при последующей поддержке новых платформ решили, что такие оптимизации делать просто не стоит, а компиялтору стоит быть попроще.

Иногда более простое (но не такое красивое) решение приносит больше пользы в глобальной перспективе, так случилось и здесь. Больше мы инструкций, которые могут поднимать по два сигнала в сгенерированном коде, не видели, так что это был действительно исключительный случай.

#откопали_стюардессу
#дух_машины

BY Алло, это отладочная?


Share with your friend now:
tgoop.com/gdb_dbg/76

View MORE
Open in Telegram


Telegram News

Date: |

Among the requests, the Brazilian electoral Court wanted to know if they could obtain data on the origins of malicious content posted on the platform. According to the TSE, this would enable the authorities to track false content and identify the user responsible for publishing it in the first place. The optimal dimension of the avatar on Telegram is 512px by 512px, and it’s recommended to use PNG format to deliver an unpixelated avatar. Image: Telegram. In handing down the sentence yesterday, deputy judge Peter Hui Shiu-keung of the district court said that even if Ng did not post the messages, he cannot shirk responsibility as the owner and administrator of such a big group for allowing these messages that incite illegal behaviors to exist. How to create a business channel on Telegram? (Tutorial)
from us


Telegram Алло, это отладочная?
FROM American