Сообщение Re[11]: особенности структурной обработки исключений в Win64 от 04.12.2016 15:48
Изменено 04.12.2016 15:49 ononim
O>>Да хоть и для банального memcpy.
кт>Это ведь так банально с помощью SSE2. Почти как гланды автогеном через задницу.
Если это выгоднее, почему нет?
O>>Исключения логики могут возникнуть при throw и при арифметике. Исключение доступа — это исключение, после которого не живут, а выживают. Без гарантий.
кт>Почему? Ну обратились к нулевому указателю, бывает. Зачем же сразу падать?
Ну например, в null pointer dereferencing — это undefined behaviour. Но вобщем-то на уровне системы — это конечно же обрабатываемая ситуация. Но для этого нужно играть по правилам. Законы физики позволяют автомобилю ехать как угодно, но все почемуто едят по дорогам. Когда ктото выезжает с дороги и наматывается на столб никто не винит создателей дорог/автомобилей. Сам виноват. Так и в этом случае — то что разрешает процессор — это законы физики. Но есть и более высокоуровневые правила, как то корректность прологов/эпилогов, обязательное выравнивание стека в любой точке исполнения программы. Процессор позволяет их нарушать, но функционал, предоставляемый ОС предполагает что те кто его используют — таки следуют правилам. Ну а раз не следует и их намотало на столб — сами виноваты.
кт>Я так понял, что проблема была в организации передачи объектов-строк через стек. В Win32 все прерывания ( в том числе пошаговой отладки и контрольных точек) не требовали никакого выравнивания стека. В Win64 любое исключение требует выровненного стека – иначе принудительное завершение задачи. В любом трансляторе легко обеспечить любое выравнивание. Здесь же пришлось менять парадигму размещения строк в стеке и дорабатывать системную библиотеку, а не транслятор.
Классическое "оно же у меня работало". Вы полагались на недокументированные особенности имплементации на определенной платформе. Теперь они изменились. Более того — они могут измениться в любой момент, с любым аптейтом.
O>>Впрочем кулхакерам, привыкшим писать на асме пофиг на соглашения, они такого понятия не понимают..
кт>Такое впечатление, что у Вас к ассемблеру что-то личное…
У меня просто неплохой такой опыт в хаканье, хуканье, асме/дизасме и прочем этом болоте, потому я крайне не разделяю решения "а давайте сделаем так как работает, оно же работает". Вначале нужно читать документацию и делать сразу как полагается. И лишь если если так как полагается не работает как хочется — тогда уже думать о хаках.
кт>В Win32 все было надежно. На все исключения есть встроенная реакция PL/1 run-time библиотеки, т.е. в язык уже была изначально встроена структурная обработка исключений. Поэтому автору и нужны были все исключения, а не только отладка. И таки-да, в пресловутом PL/1 все исключения делятся на фатальные и нефатальные. Отличия – что делать, если не задан обработчик. Фатальные – оканчивают задачу, нефатальные – продолжают.
кт>«Исследования» стека автор легко (и законно) отключил, сторонние обработчики исключений идут в сад.
кт>И проблема в Win64 осталась ровно одна – исключение есть, обработчик есть, стек в допустимых пределах, но обработчик вызывается только на выровненном на 8 стеке. Это противоречит принципу универсальности ОС, причем процессору на это выравнивание плевать, а одному кретину в микрософте – нет.
Не стоит путать свои хотелки и "принципы универсальности ОС".
O>>Установка обработчика через RtlAddFunctionTable на всевозможные адреса чревата сломом других обработчиков исключений, написанных не автором: в системном коде и в стороннем коде, который оказался в его процессе по каким либо причинам (например windows hooks dll, COM серверы). Кроме того однажды RtlAddFunctionTable может отказаться регистрировать такую функцию, т.к. ее диапазон перекрывается с уже зарегистрированными и будет совершенно права. Аккуратнее надо быть.
кт>Еще раз – все исключения должны проходить через системную библиотеку по философии языка.
Системная библиотека — в смысле рантайм конкретно этого языка, который работает ПОД ОС Windows? В таком случае это нарушает принцип разделения ответственности. Так как юзая функционал ОС — вызывая системные функции, пользуясб COM интерфейсом — вы должны полагаться на то что этот функционал является для вас черным ящиком. Своим сквозным перехватом исключеный вы вмешиваетесь в его работу. В итоге некоторые системные функции будут работать не так как следует. К примеру LookupAccountSid вместо возврата кода ошибки может бросить исключение, т.к. внутри она юзает RPC, а RPC внутри себя юзает механизм SEH. Таким образом, замкнув на себя обработку исключений, вы рискуете сломать чужой код, который работает в вашем процессе. Это не ДОС. Ваш далеко не единственный в системе. Но разумеется у программиста все всегда будет работать. Проблемы вылезут у юзеров.
кт>Это ведь так банально с помощью SSE2. Почти как гланды автогеном через задницу.
Если это выгоднее, почему нет?
O>>Исключения логики могут возникнуть при throw и при арифметике. Исключение доступа — это исключение, после которого не живут, а выживают. Без гарантий.
кт>Почему? Ну обратились к нулевому указателю, бывает. Зачем же сразу падать?
Ну например, в null pointer dereferencing — это undefined behaviour. Но вобщем-то на уровне системы — это конечно же обрабатываемая ситуация. Но для этого нужно играть по правилам. Законы физики позволяют автомобилю ехать как угодно, но все почемуто едят по дорогам. Когда ктото выезжает с дороги и наматывается на столб никто не винит создателей дорог/автомобилей. Сам виноват. Так и в этом случае — то что разрешает процессор — это законы физики. Но есть и более высокоуровневые правила, как то корректность прологов/эпилогов, обязательное выравнивание стека в любой точке исполнения программы. Процессор позволяет их нарушать, но функционал, предоставляемый ОС предполагает что те кто его используют — таки следуют правилам. Ну а раз не следует и их намотало на столб — сами виноваты.
кт>Я так понял, что проблема была в организации передачи объектов-строк через стек. В Win32 все прерывания ( в том числе пошаговой отладки и контрольных точек) не требовали никакого выравнивания стека. В Win64 любое исключение требует выровненного стека – иначе принудительное завершение задачи. В любом трансляторе легко обеспечить любое выравнивание. Здесь же пришлось менять парадигму размещения строк в стеке и дорабатывать системную библиотеку, а не транслятор.
Классическое "оно же у меня работало". Вы полагались на недокументированные особенности имплементации на определенной платформе. Теперь они изменились. Более того — они могут измениться в любой момент, с любым аптейтом.
O>>Впрочем кулхакерам, привыкшим писать на асме пофиг на соглашения, они такого понятия не понимают..
кт>Такое впечатление, что у Вас к ассемблеру что-то личное…
У меня просто неплохой такой опыт в хаканье, хуканье, асме/дизасме и прочем этом болоте, потому я крайне не разделяю решения "а давайте сделаем так как работает, оно же работает". Вначале нужно читать документацию и делать сразу как полагается. И лишь если если так как полагается не работает как хочется — тогда уже думать о хаках.
кт>В Win32 все было надежно. На все исключения есть встроенная реакция PL/1 run-time библиотеки, т.е. в язык уже была изначально встроена структурная обработка исключений. Поэтому автору и нужны были все исключения, а не только отладка. И таки-да, в пресловутом PL/1 все исключения делятся на фатальные и нефатальные. Отличия – что делать, если не задан обработчик. Фатальные – оканчивают задачу, нефатальные – продолжают.
кт>«Исследования» стека автор легко (и законно) отключил, сторонние обработчики исключений идут в сад.
кт>И проблема в Win64 осталась ровно одна – исключение есть, обработчик есть, стек в допустимых пределах, но обработчик вызывается только на выровненном на 8 стеке. Это противоречит принципу универсальности ОС, причем процессору на это выравнивание плевать, а одному кретину в микрософте – нет.
Не стоит путать свои хотелки и "принципы универсальности ОС".
O>>Установка обработчика через RtlAddFunctionTable на всевозможные адреса чревата сломом других обработчиков исключений, написанных не автором: в системном коде и в стороннем коде, который оказался в его процессе по каким либо причинам (например windows hooks dll, COM серверы). Кроме того однажды RtlAddFunctionTable может отказаться регистрировать такую функцию, т.к. ее диапазон перекрывается с уже зарегистрированными и будет совершенно права. Аккуратнее надо быть.
кт>Еще раз – все исключения должны проходить через системную библиотеку по философии языка.
Системная библиотека — в смысле рантайм конкретно этого языка, который работает ПОД ОС Windows? В таком случае это нарушает принцип разделения ответственности. Так как юзая функционал ОС — вызывая системные функции, пользуясб COM интерфейсом — вы должны полагаться на то что этот функционал является для вас черным ящиком. Своим сквозным перехватом исключеный вы вмешиваетесь в его работу. В итоге некоторые системные функции будут работать не так как следует. К примеру LookupAccountSid вместо возврата кода ошибки может бросить исключение, т.к. внутри она юзает RPC, а RPC внутри себя юзает механизм SEH. Таким образом, замкнув на себя обработку исключений, вы рискуете сломать чужой код, который работает в вашем процессе. Это не ДОС. Ваш далеко не единственный в системе. Но разумеется у программиста все всегда будет работать. Проблемы вылезут у юзеров.
Re[11]: особенности структурной обработки исключений в Win64
O>>Да хоть и для банального memcpy.
кт>Это ведь так банально с помощью SSE2. Почти как гланды автогеном через задницу.
Если это выгоднее, почему нет?
O>>Исключения логики могут возникнуть при throw и при арифметике. Исключение доступа — это исключение, после которого не живут, а выживают. Без гарантий.
кт>Почему? Ну обратились к нулевому указателю, бывает. Зачем же сразу падать?
Ну например, в С null pointer dereferencing — это undefined behaviour. Но вобщем-то на уровне системы — это конечно же обрабатываемая ситуация. Но для этого нужно играть по правилам. Законы физики позволяют автомобилю ехать как угодно, но все почемуто едят по дорогам. Когда ктото выезжает с дороги и наматывается на столб никто не винит создателей дорог/автомобилей. Сам виноват. Так и в этом случае — то что разрешает процессор — это законы физики. Но есть и более высокоуровневые правила, как то корректность прологов/эпилогов, обязательное выравнивание стека в любой точке исполнения программы. Процессор позволяет их нарушать, но функционал, предоставляемый ОС предполагает что те кто его используют — таки следуют правилам. Ну а раз не следует и их намотало на столб — сами виноваты.
кт>Я так понял, что проблема была в организации передачи объектов-строк через стек. В Win32 все прерывания ( в том числе пошаговой отладки и контрольных точек) не требовали никакого выравнивания стека. В Win64 любое исключение требует выровненного стека – иначе принудительное завершение задачи. В любом трансляторе легко обеспечить любое выравнивание. Здесь же пришлось менять парадигму размещения строк в стеке и дорабатывать системную библиотеку, а не транслятор.
Классическое "оно же у меня работало". Вы полагались на недокументированные особенности имплементации на определенной платформе. Теперь они изменились. Более того — они могут измениться в любой момент, с любым аптейтом.
O>>Впрочем кулхакерам, привыкшим писать на асме пофиг на соглашения, они такого понятия не понимают..
кт>Такое впечатление, что у Вас к ассемблеру что-то личное…
У меня просто неплохой такой опыт в хаканье, хуканье, асме/дизасме и прочем этом болоте, потому я крайне не разделяю решения "а давайте сделаем так как работает, оно же работает". Вначале нужно читать документацию и делать сразу как полагается. И лишь если если так как полагается не работает как хочется — тогда уже думать о хаках.
кт>В Win32 все было надежно. На все исключения есть встроенная реакция PL/1 run-time библиотеки, т.е. в язык уже была изначально встроена структурная обработка исключений. Поэтому автору и нужны были все исключения, а не только отладка. И таки-да, в пресловутом PL/1 все исключения делятся на фатальные и нефатальные. Отличия – что делать, если не задан обработчик. Фатальные – оканчивают задачу, нефатальные – продолжают.
кт>«Исследования» стека автор легко (и законно) отключил, сторонние обработчики исключений идут в сад.
кт>И проблема в Win64 осталась ровно одна – исключение есть, обработчик есть, стек в допустимых пределах, но обработчик вызывается только на выровненном на 8 стеке. Это противоречит принципу универсальности ОС, причем процессору на это выравнивание плевать, а одному кретину в микрософте – нет.
Не стоит путать свои хотелки и "принципы универсальности ОС".
O>>Установка обработчика через RtlAddFunctionTable на всевозможные адреса чревата сломом других обработчиков исключений, написанных не автором: в системном коде и в стороннем коде, который оказался в его процессе по каким либо причинам (например windows hooks dll, COM серверы). Кроме того однажды RtlAddFunctionTable может отказаться регистрировать такую функцию, т.к. ее диапазон перекрывается с уже зарегистрированными и будет совершенно права. Аккуратнее надо быть.
кт>Еще раз – все исключения должны проходить через системную библиотеку по философии языка.
Системная библиотека — в смысле рантайм конкретно этого языка, который работает ПОД ОС Windows? В таком случае это нарушает принцип разделения ответственности. Так как юзая функционал ОС — вызывая системные функции, пользуясб COM интерфейсом — вы должны полагаться на то что этот функционал является для вас черным ящиком. Своим сквозным перехватом исключеный вы вмешиваетесь в его работу. В итоге некоторые системные функции будут работать не так как следует. К примеру LookupAccountSid вместо возврата кода ошибки может бросить исключение, т.к. внутри она юзает RPC, а RPC внутри себя юзает механизм SEH. Таким образом, замкнув на себя обработку исключений, вы рискуете сломать чужой код, который работает в вашем процессе. Это не ДОС. Ваш далеко не единственный в системе. Но разумеется у программиста все всегда будет работать. Проблемы вылезут у юзеров.
кт>Это ведь так банально с помощью SSE2. Почти как гланды автогеном через задницу.
Если это выгоднее, почему нет?
O>>Исключения логики могут возникнуть при throw и при арифметике. Исключение доступа — это исключение, после которого не живут, а выживают. Без гарантий.
кт>Почему? Ну обратились к нулевому указателю, бывает. Зачем же сразу падать?
Ну например, в С null pointer dereferencing — это undefined behaviour. Но вобщем-то на уровне системы — это конечно же обрабатываемая ситуация. Но для этого нужно играть по правилам. Законы физики позволяют автомобилю ехать как угодно, но все почемуто едят по дорогам. Когда ктото выезжает с дороги и наматывается на столб никто не винит создателей дорог/автомобилей. Сам виноват. Так и в этом случае — то что разрешает процессор — это законы физики. Но есть и более высокоуровневые правила, как то корректность прологов/эпилогов, обязательное выравнивание стека в любой точке исполнения программы. Процессор позволяет их нарушать, но функционал, предоставляемый ОС предполагает что те кто его используют — таки следуют правилам. Ну а раз не следует и их намотало на столб — сами виноваты.
кт>Я так понял, что проблема была в организации передачи объектов-строк через стек. В Win32 все прерывания ( в том числе пошаговой отладки и контрольных точек) не требовали никакого выравнивания стека. В Win64 любое исключение требует выровненного стека – иначе принудительное завершение задачи. В любом трансляторе легко обеспечить любое выравнивание. Здесь же пришлось менять парадигму размещения строк в стеке и дорабатывать системную библиотеку, а не транслятор.
Классическое "оно же у меня работало". Вы полагались на недокументированные особенности имплементации на определенной платформе. Теперь они изменились. Более того — они могут измениться в любой момент, с любым аптейтом.
O>>Впрочем кулхакерам, привыкшим писать на асме пофиг на соглашения, они такого понятия не понимают..
кт>Такое впечатление, что у Вас к ассемблеру что-то личное…
У меня просто неплохой такой опыт в хаканье, хуканье, асме/дизасме и прочем этом болоте, потому я крайне не разделяю решения "а давайте сделаем так как работает, оно же работает". Вначале нужно читать документацию и делать сразу как полагается. И лишь если если так как полагается не работает как хочется — тогда уже думать о хаках.
кт>В Win32 все было надежно. На все исключения есть встроенная реакция PL/1 run-time библиотеки, т.е. в язык уже была изначально встроена структурная обработка исключений. Поэтому автору и нужны были все исключения, а не только отладка. И таки-да, в пресловутом PL/1 все исключения делятся на фатальные и нефатальные. Отличия – что делать, если не задан обработчик. Фатальные – оканчивают задачу, нефатальные – продолжают.
кт>«Исследования» стека автор легко (и законно) отключил, сторонние обработчики исключений идут в сад.
кт>И проблема в Win64 осталась ровно одна – исключение есть, обработчик есть, стек в допустимых пределах, но обработчик вызывается только на выровненном на 8 стеке. Это противоречит принципу универсальности ОС, причем процессору на это выравнивание плевать, а одному кретину в микрософте – нет.
Не стоит путать свои хотелки и "принципы универсальности ОС".
O>>Установка обработчика через RtlAddFunctionTable на всевозможные адреса чревата сломом других обработчиков исключений, написанных не автором: в системном коде и в стороннем коде, который оказался в его процессе по каким либо причинам (например windows hooks dll, COM серверы). Кроме того однажды RtlAddFunctionTable может отказаться регистрировать такую функцию, т.к. ее диапазон перекрывается с уже зарегистрированными и будет совершенно права. Аккуратнее надо быть.
кт>Еще раз – все исключения должны проходить через системную библиотеку по философии языка.
Системная библиотека — в смысле рантайм конкретно этого языка, который работает ПОД ОС Windows? В таком случае это нарушает принцип разделения ответственности. Так как юзая функционал ОС — вызывая системные функции, пользуясб COM интерфейсом — вы должны полагаться на то что этот функционал является для вас черным ящиком. Своим сквозным перехватом исключеный вы вмешиваетесь в его работу. В итоге некоторые системные функции будут работать не так как следует. К примеру LookupAccountSid вместо возврата кода ошибки может бросить исключение, т.к. внутри она юзает RPC, а RPC внутри себя юзает механизм SEH. Таким образом, замкнув на себя обработку исключений, вы рискуете сломать чужой код, который работает в вашем процессе. Это не ДОС. Ваш далеко не единственный в системе. Но разумеется у программиста все всегда будет работать. Проблемы вылезут у юзеров.