avva: (moose)
[personal profile] avva
Прикольно - оказывается, инструкция idiv, деление со знаком, на x86 кидает исключение не только при делении на ноль, но и когда результат не помещается в регистр. А этого очень легко добиться, написав в C например INT_MIN / -1. Как мы помним, INT_MIN по модулю на единицу больше, чем INT_MAX; например, в 32-битных числах INT_MIN равно -2147483648, а INT_MAX равно 2147483647. Поэтому когда INT_MIN делят на -1, положительный результат не вмещается в 32 бита.

Само по себе это не катастрофа - ну кидает исключение, ну и подумаешь. Дело в том, однако, что про деление на ноль все знают и помнят, и проверяют перед попыткой делить. А против INT_MIN/-1 никто практически не защищается. Поэтому можно, например:

- крэшнуть компилятор (правда, игрушечный), PostgreSQL (не игрушечную) или антивирус;
- подвесить Windows 8;
- убить bash

Date: 2013-01-30 01:12 am (UTC)
spamsink: (Default)
From: [personal profile] spamsink
При чем тут "все случаи"? Я о том, что по (явному) запросу SIG_IGN ядро должно реализовывать полезное поведение, раз уж битика игнорировать исключения при целочисленном делении не предусмотрено.

Date: 2013-01-30 01:34 am (UTC)
From: [identity profile] archaicos.livejournal.com
При беглом взгляде на описание signal() и SIG_IGN в нескольких местах (С99, http://www.cplusplus.com/reference/csignal/signal/, http://pubs.opengroup.org/onlinepubs/7908799/xsh/signal.h.html, http://linux.die.net/man/2/signal) я не увидел ничего явно обязывающее перепрыгнуть через, например, инструкцию деления. Ты можешь замаскировать и не получить сигнал - да. Что будет дальше - про это как-то не очень написано.

Если есть нормативный документ, требующий перепрыгивающего поведения, имеем ошибку реализации, которую можно донести реализаторам, чтобы те её исправили.

Если это всё чепуха, тогда имеет смысл надавить на документаторов, чтобы они чётче определили поведение в данной ситуации.

Кстати, на странице по последней ссылке вообще написано следующее: Integer division by zero has undefined result. On some architectures it will generate a SIGFPE signal. (Also dividing the most negative integer by -1 may generate SIGFPE.) Ignoring this signal might lead to an endless loop.

Сейчас это можно практически трактовать только как то, что искомое поведение не является гарантированным на практике.

Date: 2013-01-30 08:12 am (UTC)
From: [identity profile] netp-npokon.livejournal.com
Что будет дальше - про это как-то не очень написано.
Про это там как раз очень хорошо написано:

According to POSIX, the behavior of a process is undefined after it ignores a SIGFPE, SIGILL, or SIGSEGV signal that was not generated by kill(2) or raise(3)

Date: 2013-01-30 08:36 am (UTC)
From: [identity profile] archaicos.livejournal.com
О, умудрился пропустить. Ну вот, ещё меньше причин ожидать чтобы игнорирование сигналов «работало».

Date: 2013-01-30 03:09 am (UTC)
From: [identity profile] meshko.livejournal.com
Не факт, что придумать полезное поведение, когда такое исключение происходит внутри ядра, просто.

Date: 2013-01-30 05:27 am (UTC)
spamsink: (Default)
From: [personal profile] spamsink
Про "внутри ядра" тоже никто не говорил.

Date: 2013-01-30 01:54 pm (UTC)
From: [identity profile] meshko.livejournal.com
Ну оно бы не упало, если бы это был userspace. И не случайно в качестве вектора выбран GDI call.

Date: 2013-01-31 04:02 am (UTC)
From: [identity profile] archaicos.livejournal.com
Выбор весьма не случайный. GDI старый, исторически дырявый, и в нём появились новые дыры с новым UI и новой функциональностью в Win8.

Date: 2013-01-30 08:23 am (UTC)
From: [identity profile] netp-npokon.livejournal.com
Это бесполезное поведение. Когда человек пишет код на C, он чаще всего не представляет, какая там будет следующая инструкция после деления (не говоря уже о том, что это зависит от компилятора). Если она использует какие-то регистры, на которые могла повлиять инструкция деления, то дальше совершенно неизвестно, что за код будет выполнен, потому что содержимое регистров не определено.
Хуже того, если бы программа игнорировала этот сигнал, она могла бы долгое время успешно делать вид, что она работает правильно, что гораздо опаснее падения.

Date: 2013-01-30 08:26 am (UTC)
spamsink: (Default)
From: [personal profile] spamsink
Содержимое регистров будет определено: частное 0x80000000, остаток 0. Ровно то же самое, что и при умножении MIN_INT на -1.

Date: 2013-01-30 08:32 am (UTC)
From: [identity profile] netp-npokon.livejournal.com
Если я правильно трактую интеловский мануал (http://download.intel.com/products/processor/manual/325383.pdf, страница 3-375), то там нигде не написано про содержимое регистров в случае #DE

Date: 2013-01-30 04:10 pm (UTC)
From: [identity profile] archaicos.livejournal.com
#DE - falut, что означает, что контекст не портится и операцию, вызвавшую #DE можно повторить, по необходимости подкрутив контекст перед этим.

А вот #DF и #MC - abort - сливай воду, туши свет, практически.

Date: 2013-01-30 04:31 pm (UTC)
From: [identity profile] netp-npokon.livejournal.com
Согласен, в таком случае теоретически можно написать код, который будет выключать SIGFPE, а потом после каждого деления проверять, произошло ли оно на самом деле, или операнды не изменились, а процессор просто перепрыгнул через инструкцию. Но это фактически эквивалентно встраиванию обработчика сигнала после каждой инструкции деления (плюс надо добиться, чтобы компилятор ничего никуда не передвинул), так что польза все равно сомнительная.

Date: 2013-01-30 08:38 am (UTC)
From: [identity profile] archaicos.livejournal.com
Он знает, когда знает платформу и компилятор. Но игнорирование ошибок действительно обычно само является ошибкой.

Date: 2013-01-30 08:52 am (UTC)
From: [identity profile] netp-npokon.livejournal.com
Отнюдь. Некоторые вещи могут поплыть в зависимости от версии компилятора (редко кто рассчитывает всю жизнь прожить на gcc 4.2, к примеру), уровня оптимизации, каких-то модификаций выше или ниже по коду.

Date: 2013-01-30 08:57 am (UTC)
From: [identity profile] archaicos.livejournal.com
Факт, могут.

January 2026

S M T W T F S
    1 2 3
4 5678910
11121314151617
18192021222324
25262728293031

Most Popular Tags

Page Summary

Style Credit

Expand Cut Tags

No cut tags
Page generated Jan. 6th, 2026 06:08 pm
Powered by Dreamwidth Studios