Comments 12
Вы бы рассказали побольше про ваш чудо-отладчик — скриншоты, возможно ссылка на гитхаб?
Интересно, а что за проект у вас на PL/1.
Глубоко!
например, вот документация, раздел 30 «Встроенный символьный отладчик»
«pl1.su/?smd_process_download=1&download_id=590»
«pl1.su/?smd_process_download=1&download_id=590»
Кратность указателя стека 8 (на самом деле даже 16)- это часть ABI. Там вместе с правилами передачи параметров и возврата результатов, списком регистров, которые функция обязана сохранять, указано, что RSP при вызове кратен 16. Вызывая чужие функции с невыровненным стеком, вы нарушаете принятые соглашения о вызовах.
Здесь исключение, а не вызов функции. Исключение может произойти в любой момент. Кратность же стека 16 — это просто дурость какого-то полоумного индуса, которому приспичило при разборе параметров API запоминать регистры XMM. Вместо того, чтобы в одном этом месте самому выровнять стек на 16, он заставляет делать это все программы.
Кстати, при вызове подпрограммы стек аппаратно меняется на 8, а не на 16, поэтому, чтобы стек при вызове стал кратен 16, он до вызова должен быть НЕ кратен 16 ))) Т.е. когда стек выравнивается на 16 и идет обращение к API, то после вызова стек как раз НЕ кратен 16 )))
Я пробовал в NTDLL убрать эту чертову команду проверки кратности стека на 8. Разумеется, и без этой проверки все работает нормально: и Windows и процессор.
Кстати, при вызове подпрограммы стек аппаратно меняется на 8, а не на 16, поэтому, чтобы стек при вызове стал кратен 16, он до вызова должен быть НЕ кратен 16 ))) Т.е. когда стек выравнивается на 16 и идет обращение к API, то после вызова стек как раз НЕ кратен 16 )))
Я пробовал в NTDLL убрать эту чертову команду проверки кратности стека на 8. Разумеется, и без этой проверки все работает нормально: и Windows и процессор.
Вообще там есть интересные вещи: docs.microsoft.com/en-us/cpp/build/prolog-and-epilog?view=msvc-160 например
То есть тут прямо говорится, что при исключении код будет анализироваться («дисассемблироваться») для поиска эпилога функции с целью раскрутки стека.
Вообще, там жесткие правила работы с указателем стека, которые вы обязаны соблюдать, если вы хотите пользоваться SEH или вызывать чужие функции. docs.microsoft.com/en-us/cpp/build/stack-usage?view=msvc-160
В частности, трогать его в произвольном месте внутри функции вообще нельзя, только в прологе и эпилоге.
The epilog code must follow a strict set of rules for the unwind code to reliably unwind through exceptions and interrupts. These rules reduce the amount of unwind data required, because no extra data is needed to describe each epilog. Instead, the unwind code can determine that an epilog is being executed by scanning forward through a code stream to identify an epilog.
То есть тут прямо говорится, что при исключении код будет анализироваться («дисассемблироваться») для поиска эпилога функции с целью раскрутки стека.
Вообще, там жесткие правила работы с указателем стека, которые вы обязаны соблюдать, если вы хотите пользоваться SEH или вызывать чужие функции. docs.microsoft.com/en-us/cpp/build/stack-usage?view=msvc-160
В частности, трогать его в произвольном месте внутри функции вообще нельзя, только в прологе и эпилоге.
А с VEH у вас как обстоят дела? И в целом, хотелось бы о них тоже больше узнать.
так писали же вроде об этом еще 5 лет назад
habr.com/ru/company/xakep/blog/260577
У меня стояла задача только сделать работоспособным отладчик. Если бы он заработал сразу, я бы и не совался в потроха Windows
habr.com/ru/company/xakep/blog/260577
У меня стояла задача только сделать работоспособным отладчик. Если бы он заработал сразу, я бы и не совался в потроха Windows
Но вот простой контрпример: в стеке лежит текстовая строка, от которой нужно отрезать слева число байт, записанное, скажем, в EAX.Ну пусть лежит она в стеке, но зачем sp то двигать? Вам других регистров не хватает, чтобы указатель на строку хранить? Так их добавили как раз.
Так здесь через стек передаются объекты длиннее 8 байт (для Win32 длиннее 4).
В языке:
s=substr(s,2); // у брать из строки первый символ
1. В стек помещается исходная s
2. Стек подвигается на 1.
3. Содержимое стека переписывается в s
4. Стек возвращается в исходное (очищается)
Это нормально и в Win64 работает, но если идти пошаговым исключением или просто что-то случится, когда стек не в исходном — крах системы и отчет мелкомягким.
В языке:
s=substr(s,2); // у брать из строки первый символ
1. В стек помещается исходная s
2. Стек подвигается на 1.
3. Содержимое стека переписывается в s
4. Стек возвращается в исходное (очищается)
Это нормально и в Win64 работает, но если идти пошаговым исключением или просто что-то случится, когда стек не в исходном — крах системы и отчет мелкомягким.
Sign up to leave a comment.
Особенности структурной обработки исключений в Win64