Функция создания точки останова на чтение/запись
Хочу поделиться одной очень полезной функцией, которую я написал несколько лет назад. Она была включена в модуль visor.c со страницы моего отладчика, но многие, подозреваю, до сих пор не ведают о ней :)
Речь идет о VIS_Guard ().
Эта функция принимает адрес, при чтении/записи по которому ваша программа упадет с системной ошибкой SINGLE_STEP. Для отладки эта вещь незаменима, так как при разработке часто возникает ситуация, когда портится какая-то область данных, но не удается установить момент порчи и, соот-но, найти тот код, который в этой порче виноват. Передав же нужный адрес в функцию VIS_Guard, вы можете дождаться, когда ваша программа упадет и далее просмотреть стек вызова (кстати, пример кода вывода кадров стека находится в том же исходнике).
На это можно возразить, что многие отладчики позволяют делать то же самое. Это так, но дело в том, что адреса и условия проверки такой точки могут изменяться от случая к случая, да и сам отладчик может быть недоступен. Здесь же вы можете программно, т.е. автоматически определить и нужный адрес, и нужное условие, быстро и легко исправив баг.
Замечу также, что эта возможность не основана на каком-либо хаке, а обеспечивается документированной, легальной функциональностью процессора. Для работы функция использует отладочные регистры Dr0-D3, которые пишутся через функцию SetThreadContext из Windows API.
Она имеет два ограничения:
1. одновременно можно поставить лишь не более четырех точек останова по записи/чтению.
2. каждая точка размером от 1 до 4 байт, за исключением трех байт.
/*
=============
VIS_Guard
(с) Sapunov Vladimir, www.fyzor.com
Сохраняет/стирает точку останова по данным.
- Точка может иметь индекс от 0 до 3.
- Точка может иметь размер от 1 до 4, кроме 3.
- Прерывание происходит по чтению или записи.
- Точка локальна для задачи.
Условие останова может быть:
0 - Останов при выполнении
1 - Останов по записи
3 - Останов по записи или чтению
Стирается - записью NULL вместо адреса.
=============
*/
boolean VIS_Guard (int index, void* adr, int size, boolean read)
{
const sizeBB = 0x3 & (size - 1);
const condBB = 0x3 & (read * 2 + 1);
CONTEXT ct;
ct.ContextFlags = CONTEXT_DEBUG_REGISTERS;
if (!GetThreadContext (GetCurrentThread(), &ct))
return false;
// Стираем старые поля
ct.Dr7 &= ~(0xF << (16 + index * 4));
ct.Dr7 &= ~(0x3 << (index * 2));
if (size && adr)
{
ct.Dr7 |= sizeBB << (18 + index * 4); // Длина поля LEN
ct.Dr7 |= condBB << (16 + index * 4); // Условие прерывания RW
ct.Dr7 |= 0x3 << (index * 2); // Флаги разрешения LE/GE
switch (index)
{
case 0: ct.Dr0 = (DWORD) adr; break;
case 1: ct.Dr1 = (DWORD) adr; break;
case 2: ct.Dr2 = (DWORD) adr; break;
case 3: ct.Dr3 = (DWORD) adr; break;
}
}
// Сохраняем изменения
if (!SetThreadContext (GetCurrentThread(), &ct))
return false;
LOG_Printf ("VIS_Guard: index=%i adr=%X read=%i\n", index, adr, read);
return true;
}
Ваше имя:
| Articles & posts |
|---|
| Как работает временная память в мозгу | Резюме на статей о работе гиппокампа мозга, ответственного за хранение временной памяти.
|
|---|
| Потоковая память | Иногда нужно выполнить множество операций конкатенации строки, и сделать это максимально быстро. В статье описывается алгоритм и даются исходники одного из методов решения этой задачи.
|
|---|
| Временная память - удобная альтернатива | Многие, наверное, сталкивались с "ограничением" языка Си на работу со строками, когда надо возвратить строку или другие объемные данные, созданные внутри функции. Сейчас вы поймете, почему я взял это слово в кавычки :)
|
|---|
| Функция создания точки останова на чтение/запись | Эта функция будет полезна при отладке, когда нужно определить, где портятся заданные данные.
|
|---|
| Кремль со спутника | Вид со спутника на несколько известных мест. Карты maps.google.com.
|
|---|
| Представление цвета | Принцип разложения цветов на составляющие для удобного их сравнения. Существующие два олсновных формата представления цвета.
|
|---|
| Сравнение цветов | Соображения по поводу возможного алгоритма сравнения цветов.
|
|---|
| Детектор движения | Общие соображения насчет алгоритма обнаружения движения.
|
|---|
| Сборщик мусора | Альтернатива стандартному алгоритму сборщика мусора, используемому в java.
|
|---|
|