ПрограммированиеФорумОбщее

breakpoint на изменение данных в VS 2003, проблемы

#0
19:22, 18 янв 2006

Попробовал ставить в Visual Studio breakpoints на изменения данных.
Либо они игнорируются, либо программа работает слишком медленно, так что до изменения данных я просто не могу ждать (Ставлю breakpoint на член класса).
Если сделать breakpoing на глобальную переменную с фиксированным адресом, то всё ok - изменения замечаются, программа работает быстро(связываю это с тем, что в этом случае студия используются Debug-регистры).
Можно конечно их ручками выставлять, но это не удобно.

Если я знаю адрес переменной, то как мне установить на неё breakpoint?
Пробовал набрать как имя переменной что-то вроде *(int*)0x00defde8, но таже фигня -
---------------------------
Microsoft Development Environment
---------------------------
The following breakpoint may cause the program to run very slowly while being debugged:

When '*(int*)0x00defde8' changes in '{winnie_face_optimizer_t::get_next_face,,"test4.exe"}'

Is this OK?
---------------------------
Да  Нет
---------------------------

И почему-то это всё-равно не работает, программа идёт дальше не замечая изменений по этому адресу - 0x00defde8.


Как правильно установить breakpoint на адрес переменной?
Как удобно выяснить адрес переменной? Сейчас я делаю так - набираю в Quick Watch имя переменной со взятием адресса, он мне выдаёт что-то вроде

-	&m_best_path_cache_misses	0x0044e958 int m_best_path_cache_misses	int *

Я это целиком копирую (просто только адрес скопировать нельзя), вставляю в текстовый редактор, там его выделяю, копирую и вставляю уже в студии, добавив к нему *(int*). И всё равно не работает.
Как правильно установить breakpoint на адрес переменной? Просто адрес, мне не надо что бы после каждой ассемблерной команды студия перевычисляла значение выражения. Что бы при этом это было удобно, без прыжков с copy-paste и notepad.exe, в котором выделять адрес.

Сейчас, так как я отлаживаю только один объект, я просто вынес его внутренности как глобальные переменные. Но это сверх-криво.
Есть ещё такой код -

/**
http://www.gamedev.ru/forum/?group=0&topic=19532&page=1 \n
Сохраняет/стирает точку останова по данным.
Что бы стереть точку останова, установите adr и size в 0.\n
 Set/GetThreadContext может не работать, так как MSDN запрещает доступ к thread context
  runing-потока. Лечится заведением дополнительного потока, но мне лень, так как работает и так.\n
 Точка может иметь index от 0 до 3.\n
 Точка может иметь размер от 1 до 4, кроме 3.\n
 если in_bOnRead == false, то остановка происходит только при записи. Если in_bOnRead == true,
 Прерывание происходит по чтению или записи.\n
 Точка останова действует только на один поток, в котором устанавливается точка останова.\n
*/
bool SetReadWriteBreakpoint(unsigned index, unsigned adr, int size, bool in_bOnRead)
{
	if (index > 3)
	{
		assert(false);
		return false;
	}
	CONTEXT    ct;
	ct.ContextFlags = CONTEXT_DEBUG_REGISTERS;
	if (!GetThreadContext (GetCurrentThread(), &ct))
	{
		assert(false);
		return false;
	}

	// Стираем старые поля
	ct.Dr7 &= ~(0xF << (16 + index * 4));
	ct.Dr7 &= ~(0x3 << (index * 2));

	// Записываем поля условия и разрешения
	if (size && adr)
	{
		assert(size == 1 || size == 2 || size == 4);
		if (size != 1 && size != 2 && size != 4)
			return false;

		ct.Dr7 |= (((size-1) << 2) | (in_bOnRead ? 0x03 : 0x01)) << (16 + index * 4);
		ct.Dr7 |= 0x3 << (index * 2);

		switch (index)
		{
		case 0: ct.Dr0 = adr; break;
		case 1: ct.Dr1 = adr; break;
		case 2: ct.Dr2 = adr; break;
		case 3: ct.Dr3 = adr; break;
		}
	}
	// Сохраняем изменения
	if (!SetThreadContext (GetCurrentThread(), &ct))
		return false;

	return true;
}

но неужели такую тупую вещь, как установка breakpoint на адрес переменной нельзя удобно сделать из отладчика студии?

#1
23:20, 18 янв 2006

_Winnie

А зачем ты адрес передаешь? Передавай имя переменной.

>И почему-то это всё-равно не работает, программа идёт дальше не замечая изменений по этому адресу - 0x00defde8.

А у меня - любой вызов функции WinAPI вызывает Illegal Instruction. Если убрать все QPC, CreateThread и т.п., то брейкпойнт работает правильно.

Контекст пишу так (имя переменной - как оно есть в программе):

{main,rsqrt_test.cpp,rsqrt_test.exe}

ПрограммированиеФорумОбщее

Тема в архиве.