Включить точку останова B, если была достигнута точка останова A

#.net #visual-studio #breakpoints #visual-studio-debugging

#.net #visual-studio #точки останова #visual-studio-debugging

Вопрос:

Я часто ловлю себя на том, что устанавливаю точку останова A где-нибудь в коде и вручную включаю одну или несколько точек останова при достижении этой точки останова. Типичный случай — это когда я отлаживаю unittest и не забочусь о предыдущих тестах.

 void testAddZeros()
{
  Number a(0);
  Number b(0);
  Number result = a.add(b);
  assert((a   b) == Number(0))
}
void testAddOnes()
{
  Number a(1);
  Number b(1);
  Number result = a.add(b);
  assert((a   b) == Number(2));
}
void testAddNegativeNumber()
{
  Number a(1);
  Number b(-1)
  Number result = a.add(b);
  assert((a   b) == Number(0));
}
  

Представьте, что если testAddZeros() и testAddOnes() работает нормально, но testAddNegativeNumber() . В этом случае установка точки останова в Number result = a.add(b); была бы естественным местом для начала отладки. Теперь представьте, что ошибка находится где-то глубоко внутри Number::add , поэтому нас не особо интересует то, что происходит на ранней стадии Numbers::add . Что я хочу сделать, так это установить точку останова где-нибудь внутри, Numbers::add которая срабатывает, только если я нахожусь внутри testAddNegativeNumber() -test.

Есть ли какой-либо способ автоматически включить точку останова B при достижении точки останова A ?

Комментарии:

1. Вы проверили условные точки останова? Вероятно, вы могли бы использовать условие, при котором достигается точка останова A, чтобы включить «условную» точку останова B. (В этом случае вам, возможно, больше не нужна точка останова A)

2. @ChristiaanV: да, но я боюсь, что условных точек останова в этом случае будет недостаточно — по крайней мере, не в общем случае.

3. Не могли бы вы показать пример кода, где вы хотели бы это использовать?

4. Единственное, что я могу придумать, это использовать отражение, чтобы найти метод, который вызывается внутри условной точки останова. Что-то вроде этого: создать StackTrace(). GetFrame(1). GetMethod().Name == «testAddNegativeNumber»

Ответ №1:

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

Одно из наиболее доступных хранилищ, которое я нашел, — это пользовательские свойства домена приложения. К ним может быть получен доступ системой.AppDomain.CurrentDomain.Методы getData и setData.

Итак, для первой точки останова вы определяете параметр «при достижении» с помощью :

{Система.AppDomain.CurrentDomain.setData(«break»,true)}

условие точки останова

Для зависимой точки останова установите условие попадания в:

Система.AppDomain.CurrentDomain.getData(«break») != null

Комментарии:

1. Я задавался вопросом, будут ли подобные вещи работать с точками трассировки… теперь я знаю. Поддержано!

2. Возможно ли заставить это работать при отладке кода на C ?

Ответ №2:

Я думаю, это лучшее, что вы могли бы сделать, но это кажется слишком сложным, чтобы даже пытаться, потому что это включает добавление переменной…

 string breakpointToStopOn = string.Empty;
Console.WriteLine("HERE"); // You can set breakpoint A here, 
                           // with a condition (right click on the breakpoint, then selectCondition),
                           // that sets breakpointToStopOn = "A"
Console.WriteLine("B"); // and you can set your breakpoint here with this condition
                        // (breakpointToStopOn == "A");  
  

На самом деле вы не сможете остановиться на консоли.Строка WriteLine(«ЗДЕСЬ»), но вы могли бы включить или отключить точку останова, что фактически включило бы другую точку останова.

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

Комментарии:

1. Хотя это не то, что я искал, я думаю, это лучшее (ну, единственное) предложение.