Автоматический сбой при изменении или чтении содержимого ячейки памяти

У старого отладчика DEC Tru64 UNIX была функция (называемая "точки наблюдения для мониторинга переменных" ), которая будет следить за местоположением (или диапазоном адресов) памяти для активности чтения или записи, и когда она обнаружит такую ​​активность, она сломает программу, чтобы вы может исследовать, почему. Подробнее см.

http://h30097.www3.hp.com/docs/base_doc/DOCUMENTATION/V50_HTML/ARH9QATE/DOCU_009.HTM

Есть ли способ сделать это в отладчике VisualStudio? Или есть надстройка или какой-нибудь другой инструмент, который может сделать это под Windows?

Ответ 1

Да, вы можете сделать это в визуальной студии. Вы можете создать "новую точку останова данных" в меню отладки, когда вы нарушены в запущенной программе. Затем вы указываете адрес для просмотра и количество байтов.

Это работает только для изменения значения. Я не знаю, как смотреть доступ на чтение. Однако очень часто возникает вопрос, нужно ли знать, где изменилось значение. Я считаю, что я не хочу знать, кто читает значение так часто.

Ответ 2

Visual Studio позволяет установить контрольные точки в ячейке памяти только длиной 4 байта (в 32-разрядной версии Windows). Чтобы уловить доступ к памяти (чтение или запись), вы можете использовать следующий класс:

struct protect_mem_t {
    protect_mem_t( void* addr, size_t size ) : addr(addr), size(size), is_protected(FALSE) { 
        protect(); 
    }
    ~protect_mem_t() { release(); }
    BOOL protect() { 
        if ( !is_protected ) {
            // To catch only read access you should change PAGE_NOACCESS to PAGE_READONLY
            is_protected = VirtualProtect( addr, size, PAGE_NOACCESS, &old_protect );
        }
        return is_protected;
    }
    BOOL release() { 
        if ( is_protected ) 
            is_protected = !VirtualProtect( addr, size, old_protect, &old_protect );
        return !is_protected;
    }

protected:
    void*   addr;
    size_t  size;
    BOOL    is_protected;
    DWORD   old_protect;
};

Он изменяет режим доступа на выбранных страницах памяти. Размер страницы равен 4096 байт в 32-битных системах. Исключение будет зависеть от каждого доступа к защищенной памяти. Этот класс ограничен в использовании только для больших областей памяти, но я надеюсь, что это может быть полезно.

Его можно использовать следующим образом:

// some_array should be aligned on PAGE_SIZE boundaries
protect_mem_t guard( &some_array, PAGE_SIZE );

Ответ 3

Вы можете использовать WINDBG и установить точку останова ba по желаемому адресу

Ответ 4

Да, точки останова данных могут обнаруживать записи. Однако не знаю, можно ли проверить чтение. Я не верю, что x86 имеет встроенную поддержку для этого.

Ответ 5

Я рекомендую проект hwbreak. Он даже позволяет установить точку прерывания данных, когда считывается местоположение.

Я изменил его, чтобы создать только один поток и повторно использовать этот поток для всех точек прерывания данных, но это было просто для эффективности.