Прерывание при изменении значения с помощью отладчика Visual Studio

198

Есть ли способ поместить часы в переменную, и только Visual Studio прерывается, когда это значение изменяется?

Было бы намного проще находить сложные государственные проблемы.

Можно ли это сделать?

Условия точки останова все еще нуждаются в установке точки останова, и я бы предпочел установить часы и позволить Visual Studio устанавливать точки останова при изменении состояния.

FlySwat
источник
но точка останова не влияет ни на что, если условие не выполняется, поэтому вы можете поместить свою точку останова где угодно (например, Setter) и взять ее оттуда. Или я что-то упустил?
Оскар
6
хорошо. это как способ отладки vb6. Вы не заботитесь о местоположении точки останова. просто добавьте условное выражение к окну просмотра, и vb6 гарантирует, что оно будет нарушаться при выполнении условия ..
Гульзар Назим
извините, никогда не видел пути, насколько я знаю, сеттер - это путь, по которому нужно идти
Оскар
1
я надеялся найти лучшие новости; vs2010 указывает на отсутствие изменений msdn.microsoft.com/en-us/library/350dyxd0.aspx только в родном c ++ есть @Scottgu, который вы можете сделать лучше!
gerryLowry

Ответы:

134

В меню Visual Studio 2005:

Отладка -> Новая точка останова -> Новая точка останова данных

Войти:

&myVariable
AShelly
источник
38
это доступно для управляемого кода? Я вижу, что эта опция отключена для проекта C #. Не забывайте читать где-нибудь, это сложная функция для отладки управляемых приложений, особенно с вовлеченным сборщиком мусора.
Гульзар Назим
27
К сожалению, он доступен только для неуправляемого кода: msdn.microsoft.com/en-us/library/350dyxd0.aspx
Джош Кодрофф,
17
Вы также можете временно преобразовать поле в свойство и поместить точку останова в метод получения или установки.
Джон Дэвис
12
Опция «Точка останова данных» в разделе «Отладка -> Новая точка останова» отключена ... Есть идеи, почему? Он остается отключенным, или нет, я на самом деле отлаживаю или нет. Я использую Visual Studio 2015.
JBB
2
Немного поздно, но @jbb для меня он включается только тогда, когда я остановился в точке останова во время отладки.
Allball103
27

Вы также можете явно разорвать в коде:

// Assuming C#
if (condition)
{
    System.Diagnostics.Debugger.Break();
}

Из MSDN:

Debugger.Break: если отладчик не подключен, пользователей спрашивают, хотят ли они присоединить отладчик. Если да, то отладчик запущен. Если отладчик подключен, отладчик получает сигнал о событии точки останова пользователя, и отладчик приостанавливает выполнение процесса так же, как если бы была достигнута точка останова отладчика.

Это всего лишь запасной вариант. Установка условной точки останова в Visual Studio, как описано в других комментариях, является лучшим выбором.

Майкл Петротта
источник
2
FWIW, с правкой и продолжением, я предпочитаю делать это следующим образом: IME, условные точки останова - sloooow
Mark Sowul
Это работает - но это очень больно - я заканчивал тем, что делал что-то подобное - я помещал это в верхнюю часть каждого метода, который я подозревал - и снова в нижнюю часть (в конечном пункте) - таким образом, я точно знал, какой Метод вызывал проблему - (т.е. я знал, что данные были хорошими до входа в метод, а затем плохими перед выходом из него).
BrainSlugs83
26

Действительно старый пост, но в случае, если кто-то не знает ...

В Visual Studio 2015 вы можете поместить точку останова на метод setдоступа к автоматически внедряемому свойству, и отладчик сломается при обновлении свойства

public bool IsUpdated
{
    get;
    set;    //set breakpoint on this line
}

Обновить

В качестве альтернативы; @AbdulRaufMujahid указал в комментариях, что, если автоматически внедренное свойство находится на одной строке, вы можете расположить курсор на кнопке get;или set;и, F9и точка останова будет соответственно размещена. Ницца!

public bool IsUpdated { get; set; }
Craig
источник
5
Даже если автоматически реализованное свойство находится в одной строке, например, общедоступная строка UserName {set; получить; }. Пользователь может выделить геттер или сеттер и нажать F9, чтобы добавить точку останова
Абдул Рауф
@AbdulRaufMujahid Отлично!
Крейг
13

Представьте, что у вас есть класс с именем A со следующим объявлением.

class A  
{  
    public:  
        A();

    private:
        int m_value;
};

Вы хотите, чтобы программа остановилась, когда кто-то изменил значение «m_value».

Перейти к определению класса и поставить точку останова в конструкторе A.

A::A()
{
    ... // set breakpoint here
}

Как только мы остановили программу:

Отладка -> Новая точка останова -> Новая точка останова данных ...

Адрес: & (this-> m_value)
байтов: 4 (потому что int имеет 4 байта)

Теперь мы можем возобновить программу. Отладчик остановится при изменении значения.

Вы можете сделать то же самое с унаследованными классами или составными классами.

class B
{
   private:
       A m_a;
};

Адрес: & (this-> m_a.m_value)

Если вы не знаете количество байтов переменной, которую вы хотите проверить, вы можете использовать оператор sizeof.

Например:

// to know the size of the word processor,  
// if you want to inspect a pointer.
int wordTam = sizeof (void* ); 

Если вы посмотрите на «Стек вызовов», вы увидите функцию, которая изменила значение переменной.

momboco
источник
1
Итак, что именно вы будете делать, если то, что я ищу, не в моих собственных классах? Как, например, я пытаюсь выяснить, где именно элемент управления включен или отключен? Конечно, я могу добавить наблюдение за значением Enabled элемента управления во время отладки, но нет способа сломать его при изменении, а затем посмотреть, где оно остановилось.
Nyerguds
2
Если вы попытаетесь отладить внешнюю библиотеку, вам потребуется библиотека, скомпилированная в режиме отладки. Я не знаком с компонентом, но, возможно, вы можете подключить «обратный вызов» к свойству и установить точку останова внутри. Форма, которую я описываю, нуждается в адресе памяти, если у вас нет способа узнать это, есть поиск других методов.
Момбоко
9

Измените переменную на свойство и добавьте точку останова в методе set. Пример:

private bool m_Var = false;
protected bool var
{
    get { 
        return m_var;
    }

    set { 
        m_var = value;
    }
}
Marcello
источник
3

Если вы используете WPF, есть отличный инструмент: WPF Inspector .
Он присоединяется к приложению WPF и отображает полное дерево элементов управления со всеми свойствами, что позволяет (помимо прочего) нарушать любые изменения свойств.

Но, к сожалению, я не нашел никакого инструмента, который позволил бы вам сделать то же самое с ЛЮБЫМ свойством или переменной.

Жюльен Н
источник
2

Щелчок правой кнопкой мыши по точке останова отлично работает для меня (хотя в основном я использую ее для условных точек останова на определенных значениях переменных. Даже разбиение на выражения, использующее имя потока, работает, что очень полезно, если вы пытаетесь обнаружить проблемы с потоками).

Oskar
источник
2

Как писал Питер Мортенсен:

В меню Visual Studio 2005:

Отладка -> Новая точка останова -> Новая точка останова данных

Введите: & myVariable

Дополнительная информация:

Очевидно, система должна знать, какой адрес в памяти смотреть. Итак - установите нормальную точку останова на инициализацию myVariable(или myClass.m_Variable) - запустите систему и дождитесь ее остановки в этой точке останова. - Теперь запись меню включена, и вы можете смотреть переменную, вводя &myVariable, или экземпляр, вводя&myClass.m_Variable . Теперь адреса четко определены.

Извините, когда я поступил неправильно, объяснив уже данное решение. Но я не мог добавить комментарий, и там было несколько комментариев по этому поводу.

R Рисак
источник
1

Вы можете использовать контрольную точку памяти в неуправляемом коде. Не уверен, что они доступны в управляемом коде.

1800 ИНФОРМАЦИЯ
источник
1

Вероятно, вы можете разумно использовать функцию DebugBreak () .

WIP
источник
Как именно? Запустив отдельный поток в узком цикле и вызывая DebugBreak () при каждом изменении?
nalply
@nalpy Например, вы можете отследить места, где myVariableиспользуется, и сохранить его значения после использования во вспомогательной previousValueпеременной, а затем вызвать DebugBreak () когда myVariable!=previousValue; тогда вы будете знать, между какими блоками кода myVariableпроизошли изменения. Но я согласен, что решение AShelly является лучшим.
WIP
1

При желании вы можете перегрузить оператор = для переменной и поставить точку останова внутри перегруженной функции при определенных условиях.

PRIME
источник
1

Обновление в 2019 году:

Теперь это официально поддерживается в Visual Studio 2019 Preview 2 для .Net Core 3.0 или выше. Конечно, вам, возможно, придется подумать о потенциальных рисках использования предварительной версии IDE. Думаю, в ближайшее время это будет включено в официальную Visual Studio.

https://blogs.msdn.microsoft.com/visualstudio/2019/02/12/break-when-value-changes-data-breakpoints-for-net-core-in-visual-studio-2019/

К счастью, точки останова данных больше не являются эксклюзивными для C ++, поскольку теперь они доступны для .NET Core (3.0 или выше) в Visual Studio 2019 Preview 2!

Matt
источник