Dmitry Develop
ссылка на канал | ссылка на группу
Продолжаю экспериментировать и исследовать механизм Vectored Exception Handler (windows SEH).
Моей целью является реализовать трансляцию конкретных исключений для конкретных случаев и функций обратно в место их возникновения, пропуская одну инструкцию или строку кода, чтобы использовать общий механизм обработки ошибок в проекте.
Все остальные случаи и исключения будут обрабатываться операционной системой по-умолчанию, и обычно это приводит к TerminateProcess.
Чтобы в VEH возобновить исполнение программы и пропустить текущую инструкцию, которая привела к возникновению исключения, надо записать в регистр instruction pointer (на x64 это Rip, на x32 Eip) адрес начала следующей инструкции, но нужно знать размер пропускаемой инструкции в байтах.
Видимо, для этого придётся написать дисассемблер длин инструкций или найти готовое решение.
Можно просто увеличивать instruction pointer на 1 до тех пор, пока он не начнёт указывать на начало следующей инструкции, но я считаю это плохим решением.
Такой подход почти всегда будет приводить к возникновению новых ненужных (побочных) исключений, некоторые из них: STATUS_ACCESS_VIOLATION, EXCEPTION_ILLEGAL_INSTRUCTION.
ссылка на канал | ссылка на группу
Моей целью является реализовать трансляцию конкретных исключений для конкретных случаев и функций обратно в место их возникновения, пропуская одну инструкцию или строку кода, чтобы использовать общий механизм обработки ошибок в проекте.
Все остальные случаи и исключения будут обрабатываться операционной системой по-умолчанию, и обычно это приводит к TerminateProcess.
Чтобы в VEH возобновить исполнение программы и пропустить текущую инструкцию, которая привела к возникновению исключения, надо записать в регистр instruction pointer (на x64 это Rip, на x32 Eip) адрес начала следующей инструкции, но нужно знать размер пропускаемой инструкции в байтах.
Видимо, для этого придётся написать дисассемблер длин инструкций или найти готовое решение.
Можно просто увеличивать instruction pointer на 1 до тех пор, пока он не начнёт указывать на начало следующей инструкции, но я считаю это плохим решением.
Такой подход почти всегда будет приводить к возникновению новых ненужных (побочных) исключений, некоторые из них: STATUS_ACCESS_VIOLATION, EXCEPTION_ILLEGAL_INSTRUCTION.
ссылка на канал | ссылка на группу
👍1
Dmitry Develop
image_2024-02-15_14-33-05.png
Небольшое дополнение про контрольные значения в vs code.
Оказывается, там можно даже команду для отладчика писать и получать нужные данные прямо в графическом интерфейсе без надобности открывать отладочную консоль.
Мне нужно было видеть текущий адрес в регистре Rip (instruction counter на x64) без постоянного отвлечения на консоль отладчика:
ссылка на канал | ссылка на группу
Оказывается, там можно даже команду для отладчика писать и получать нужные данные прямо в графическом интерфейсе без надобности открывать отладочную консоль.
Мне нужно было видеть текущий адрес в регистре Rip (instruction counter на x64) без постоянного отвлечения на консоль отладчика:
-exec output/x $pcссылка на канал | ссылка на группу
👍2
Dmitry Develop
makePortable.zip
С версии 1.25 от июня 2018 года в vs code появился портативный (переносной) режим.
https://code.visualstudio.com/updates/v1_25#_portable-mode
В этом режиме все создаваемые и обрабатываемые данные (расширения, настройки, временные файлы) хранятся в папке установки, что позволяет хранить редактор, например, на флешке, и перемещать его между окружениями.
Доступен этот режим для всех трёх распространённых операционных систем: windows, linux и macOS и только для редактора, загружаемого в виде архива (*.zip, *.tar.gz).
Инструкция, как включить портативный режим для vs code или vs codium:
https://code.visualstudio.com/docs/editor/portable
https://github.com/VSCodium/vscodium/blob/master/docs/index.md#portable
Если пересказывать инструкцию кратко, то в папке установки нужно создать папку data, и внутри неё ещё три папки user-data, extensions и tmp (для macOS будет немного по-другому).
Выше вы можете скачать архив с расширением zip или 7-zip, в котором есть уже готовая иерархия пустых папок, содержимое которого надо просто разархивировать в корневую папку редактора.
ссылка на канал | ссылка на группу
https://code.visualstudio.com/updates/v1_25#_portable-mode
В этом режиме все создаваемые и обрабатываемые данные (расширения, настройки, временные файлы) хранятся в папке установки, что позволяет хранить редактор, например, на флешке, и перемещать его между окружениями.
Доступен этот режим для всех трёх распространённых операционных систем: windows, linux и macOS и только для редактора, загружаемого в виде архива (*.zip, *.tar.gz).
Инструкция, как включить портативный режим для vs code или vs codium:
https://code.visualstudio.com/docs/editor/portable
https://github.com/VSCodium/vscodium/blob/master/docs/index.md#portable
Если пересказывать инструкцию кратко, то в папке установки нужно создать папку data, и внутри неё ещё три папки user-data, extensions и tmp (для macOS будет немного по-другому).
Выше вы можете скачать архив с расширением zip или 7-zip, в котором есть уже готовая иерархия пустых папок, содержимое которого надо просто разархивировать в корневую папку редактора.
ссылка на канал | ссылка на группу
👍3🎉1
Dmitry Develop
image_2024-02-19_16-53-18.png
Продолжаю переписывать проект с нуля.
Пересмотрел весь старый код проекта, определил алгоритм его работы, обратил внимание на трудности, неудобства и недостатки кода и подхода.
В новом проекте из-за вынесения функций и макросов в отдельные модули, для переиспользования кода и упрощения архитектуры, количество файлов уже немного пугает, ведь это только начало).
ссылка на канал | ссылка на группу
Пересмотрел весь старый код проекта, определил алгоритм его работы, обратил внимание на трудности, неудобства и недостатки кода и подхода.
В новом проекте из-за вынесения функций и макросов в отдельные модули, для переиспользования кода и упрощения архитектуры, количество файлов уже немного пугает, ведь это только начало).
ссылка на канал | ссылка на группу
👍2
Dmitry Develop
ссылка на канал | ссылка на группу
Как же мне нравится, когда код простой и явный.
(Ну, хотя бы для меня и по моим меркам)
Амортизационный коэффициент по-умолчанию для моего массива сделал 1.5, но можно в любой момент, даже между вставками, изменить его на любой другой.
Функция из byteAlgorithm работает, а чтобы компилятор не оптимизировал её код в вызов функции memcpy из стандартной библиотеки языка, использовал следующие pragma директивы препроцессора для gcc (mingw):
Жаль, что строгая типизация не позволяет неявно преобразовывать указатель на один тип данных в указатель на другой тип данных, когда мне важен именно адрес, а не тип данных по указателю.
Хотя, это потенциальное место для ошибок, надо бы подумать над тем, чтобы придумать специальные типы-псевдонимы через директивы using, чтобы явно выразить через них семантику.
ссылка на канал | ссылка на группу
(Ну, хотя бы для меня и по моим меркам)
Амортизационный коэффициент по-умолчанию для моего массива сделал 1.5, но можно в любой момент, даже между вставками, изменить его на любой другой.
Функция из byteAlgorithm работает, а чтобы компилятор не оптимизировал её код в вызов функции memcpy из стандартной библиотеки языка, использовал следующие pragma директивы препроцессора для gcc (mingw):
#pragma GCC push_options
#pragma GCC optimize ("-fno-tree-loop-distribute-patterns")
void byteCopy(uint8_t* from, uint8_t* to, int64_t size, status_s* status)
{
...
}
#pragma GCC pop_options
Жаль, что строгая типизация не позволяет неявно преобразовывать указатель на один тип данных в указатель на другой тип данных, когда мне важен именно адрес, а не тип данных по указателю.
Хотя, это потенциальное место для ошибок, надо бы подумать над тем, чтобы придумать специальные типы-псевдонимы через директивы using, чтобы явно выразить через них семантику.
ссылка на канал | ссылка на группу
👍4
Dmitry Develop
ссылка на канал | ссылка на группу
Как сломать отладку в vs code за 1 секунду?
Всего лишь попытаться вызвать функцию по её адресу в контрольных значениях)).
С чего всё началось и как я вообще додумался так сделать?
Когда пишешь на python, в контрольных значениях можно не только отслеживать уже созданные переменные, но и писать целые выражения и вызовы функций, которые будут выполняться прямо в runtime.
В моём модуле динамической памяти я поймал странное поведение.
Функция GetProcessHeap завершалась успешно, но GetLastError возвращала код 126: ERROR_MOD_NOT_FOUND (The specified module could not be found).
Из-за этого модуль сообщал о неуспешной операции.
Решил проверить последний код ошибки в самом начале main и получил тот же самый код, что мне показалось странным.
И я захотел начать отладку ещё до начала main где-то вstartfiles или crt mainCRTStartup.
А возвращаемое значение из функции GetLastError отслеживать в контрольных значениях, но что-то пошло не так...
ссылка на канал | ссылка на группу
Всего лишь попытаться вызвать функцию по её адресу в контрольных значениях)).
(unsigned long)(*0x7ffd10f15bf0)(void)()С чего всё началось и как я вообще додумался так сделать?
Когда пишешь на python, в контрольных значениях можно не только отслеживать уже созданные переменные, но и писать целые выражения и вызовы функций, которые будут выполняться прямо в runtime.
В моём модуле динамической памяти я поймал странное поведение.
Функция GetProcessHeap завершалась успешно, но GetLastError возвращала код 126: ERROR_MOD_NOT_FOUND (The specified module could not be found).
Из-за этого модуль сообщал о неуспешной операции.
Решил проверить последний код ошибки в самом начале main и получил тот же самый код, что мне показалось странным.
И я захотел начать отладку ещё до начала main где-то в
А возвращаемое значение из функции GetLastError отслеживать в контрольных значениях, но что-то пошло не так...
ссылка на канал | ссылка на группу
👍2
XL.jpeg
136.3 KB
Фотография не моя, взял её из фотографий отзывов бара failover на google maps.
ссылка на канал | ссылка на группу
ссылка на канал | ссылка на группу
Dmitry Develop
XL.jpeg
Я считаю, что программисту одного только написания кода недостаточно, важно поддерживать общение в IT сообществе не только в online, но и в offline.
Поэтому сегодня я буду на offline-вечеринке в IT баре failover.
В Санкт-Петербурге я буду 2-3 дня, буду рад встретить каждого).
ссылка на канал | ссылка на группу
Поэтому сегодня я буду на offline-вечеринке в IT баре failover.
В Санкт-Петербурге я буду 2-3 дня, буду рад встретить каждого).
ссылка на канал | ссылка на группу
👍2
Dmitry Develop
ссылка на канал | ссылка на группу
Делал небольшую инструкцию для человека, как в vs code выделить и редактировать несколько строк, и решил выложить её сюда.
Я очень часто использую данный подход для обработки большого количества строк в одинаковом формате, чтобы, например, вырезать какие-то названия.
ссылка на канал | ссылка на группу
Я очень часто использую данный подход для обработки большого количества строк в одинаковом формате, чтобы, например, вырезать какие-то названия.
ссылка на канал | ссылка на группу
Как бы мне реализовать главный цикл программы, чтобы в одном потоке:
1) обрабатывать сообщения windows
2) делать вычисления и отрисовку с нужной частотой
3) остальное время спать
4) даже во время сна обрабатывать новые сообщения
Является ли такая реализация через PeekMessageA:
Аналогом такой типичной реализации через GetMessageA?
Плохо только, что я не проверяю возвращаемое значение функции MsgWaitForMultipleObjects, но это только демонстрационный пример.
ссылка на канал | ссылка на группу
1) обрабатывать сообщения windows
2) делать вычисления и отрисовку с нужной частотой
3) остальное время спать
4) даже во время сна обрабатывать новые сообщения
Является ли такая реализация через PeekMessageA:
MSG message { };
while(true)
{
while(PeekMessageA(&message, nullptr, 0, 0, PM_REMOVE))
{
TranslateMessage(&message);
DispatchMessageA(&message);
}
if(message.message == WM_QUIT)
{
break;
}
MsgWaitForMultipleObjects(0, nullptr, false, INFINITE, QS_ALLINPUT);
}Аналогом такой типичной реализации через GetMessageA?
MSG message { };
while(GetMessageA(&message, nullptr, 0, 0))
{
TranslateMessage(&message);
DispatchMessageA(&message);
}Плохо только, что я не проверяю возвращаемое значение функции MsgWaitForMultipleObjects, но это только демонстрационный пример.
ссылка на канал | ссылка на группу
👏1
C MsgWaitForMultipleObjects, CreateWaitableTimerA и SetWaitableTimer у меня не получилось достигнуть более 60 FPS.
Windows, конечно, не RTOS, но и само разрешение системного таймера довольно низкое.
Можно его изменить при помощи timeBeginPeriod, но мне этот способ не нравится.
Зато этот просто способ даёт точную и стабильную частоту кадров).
Правда, этот способ впустую тратит такты процессора, создаёт повышенную нагрузку и тепловыделение.
В диспетчере задач будет большой процент использования ЦП.
Поэтому мне нужен другой способ или комбинированный предыдущий.
ссылка на канал | ссылка на группу
Windows, конечно, не RTOS, но и само разрешение системного таймера довольно низкое.
Можно его изменить при помощи timeBeginPeriod, но мне этот способ не нравится.
Зато этот просто способ даёт точную и стабильную частоту кадров).
// timeNow возвращает текущее время в наносекундах (windows QPC)
while(true)
{
...
static int64_t nextIter { };
int64_t now { };
timeNow(&now);
if(now >= nextIter)
{
InvalidateRect(window, nullptr, false);
const int64_t targetFPS { 240 };
nextIter = now + 1'000'000'000 / targetFPS;
}
...
}
Правда, этот способ впустую тратит такты процессора, создаёт повышенную нагрузку и тепловыделение.
В диспетчере задач будет большой процент использования ЦП.
Поэтому мне нужен другой способ или комбинированный предыдущий.
ссылка на канал | ссылка на группу
🤔1
Dmitry Develop
ссылка на канал | ссылка на группу
Необычная ошибка возникла при реализации off-screen bitmap rendering).
Как хорошо, что я уже давно не начинающий, поэтому никаких сложностей с отладкой не возникнет).
На экране рисуются две строки: 1) FPS, 2) задержка в наносекундах после отрисовки кадра.
Причина проблемы была в заполнении прямоугольника RECT функцией GetWindowRect вместо GetClientRect.
ссылка на канал | ссылка на группу
Как хорошо, что я уже давно не начинающий, поэтому никаких сложностей с отладкой не возникнет).
На экране рисуются две строки: 1) FPS, 2) задержка в наносекундах после отрисовки кадра.
Причина проблемы была в заполнении прямоугольника RECT функцией GetWindowRect вместо GetClientRect.
ссылка на канал | ссылка на группу