Здравствуйте, ononim, Вы писали:
O>Да хоть и для банального memcpy.
Это ведь так банально с помощью SSE2. Почти как гланды автогеном через задницу.
O>Исключения логики могут возникнуть при throw и при арифметике. Исключение доступа — это исключение, после которого не живут, а выживают. Без гарантий.
Почему? Ну обратились к нулевому указателю, бывает. Зачем же сразу падать?
O>Кроме того, как я понял проблема возникла с кодом, который был сгенерен доморощенным PL/1 компилятором. Фиксить ее нужно было начинать с того, чтоб после каждой инструкции сгенеренного кода RSP оставался выровненным на 8 байт. И не забывать генерить правильные прологи/эпилоги функций.
Я так понял, что проблема была в организации передачи объектов-строк через стек. В Win32 все прерывания ( в том числе пошаговой отладки и контрольных точек) не требовали никакого выравнивания стека. В Win64 любое исключение требует выровненного стека – иначе принудительное завершение задачи. В любом трансляторе легко обеспечить любое выравнивание. Здесь же пришлось менять парадигму размещения строк в стеке и дорабатывать системную библиотеку, а не транслятор.
O>Впрочем кулхакерам, привыкшим писать на асме пофиг на соглашения, они такого понятия не понимают..
Такое впечатление, что у Вас к ассемблеру что-то личное…
O>SetUnhandledExceptionFilter* не предназначена для реализации дебаггера, всем кто в теме давно известно что она ненадежна. Для дебаггера есть DebugAPI у коготорых нет таких проблем, т.к. они работают через LPC из соседнего процесса. Автор статьи пошел через реку вброд, хотя рямом был мост и жалуется**.
В Win32 все было надежно. На все исключения есть встроенная реакция PL/1 run-time библиотеки, т.е. в язык уже была изначально встроена структурная обработка исключений. Поэтому автору и нужны были все исключения, а не только отладка. И таки-да, в пресловутом PL/1 все исключения делятся на фатальные и нефатальные. Отличия – что делать, если не задан обработчик. Фатальные – оканчивают задачу, нефатальные – продолжают.
«Исследования» стека автор легко (и законно) отключил, сторонние обработчики исключений идут в сад.
И проблема в Win64 осталась ровно одна – исключение есть, обработчик есть, стек в допустимых пределах, но обработчик вызывается только на выровненном на 8 стеке. Это противоречит принципу универсальности ОС, причем процессору на это выравнивание плевать, а одному кретину в микрософте – нет.
O>* Использование SetUnhandledExceptionFilter для дебаггера тем более странно, что оно не ловит уже пойманные исключения. Полагаю AddVectoredExceptionHandler для самодебаггера было бы более адекватным решением, хотя все еще не адекватным.
Это все было в Win32 без нареканий. Теперь SetUnhandledExceptionFilter не используется.
O>Установка обработчика через RtlAddFunctionTable на всевозможные адреса чревата сломом других обработчиков исключений, написанных не автором: в системном коде и в стороннем коде, который оказался в его процессе по каким либо причинам (например windows hooks dll, COM серверы). Кроме того однажды RtlAddFunctionTable может отказаться регистрировать такую функцию, т.к. ее диапазон перекрывается с уже зарегистрированными и будет совершенно права. Аккуратнее надо быть.
Еще раз – все исключения должны проходить через системную библиотеку по философии языка.
O>** Я сам ходил через реку вброд и реализовывал аналогичный механизм в одном исследовательском проекте для трейсинга софта, а в другом, неисследовательском — для реализации подкачки на уровне юзермода. Но в отличии от автора статьи я примерно понимал с чем имею дело и вместо того чтоб жаловаться на гнусный микрософт, не дающий кулхацкерам жизним, просто похукал ntdll!KiUserExceptionDispatcher.
Я разговаривал вчера с Караваевым на эту тему. Все давным-давно сделано и нормально работает. Но, говорит, дополнительных команд в системную библиотеку пришлось много добавить. И не только из-за одной этой проверки. Еще INTO выкинули, двоично-десятичную арифметику похерили. Кому они в х86-64 мешали? Микрософт здесь вроде не причем