Visual Studio: точка останова, исключающая вызовы определенной функции - PullRequest
0 голосов
/ 16 января 2009

Я хочу установить точку останова в неуправляемом C ++, в Visual Studio 2005, но я хотел бы игнорировать эту точку останова, если стек вызовов находится в определенной функции. Есть ли способ сделать это?

Ответы [ 4 ]

3 голосов
/ 16 января 2009

Если у вас есть коммерческая версия Visual Studio, вы должны иметь возможность установить точку останова в начале процедуры вызова, а затем изменить ее поведение «При попадании ...» на «Запуск макроса». Вам нужно написать макрос, который программно отключает точку останова в вызываемой функции - используйте это как макрос для запуска. (Надеюсь, кто-то еще может описать, как можно написать такой макрос.) Затем установите другие точки останова на всех точках выхода вызывающей функции и измените их поведение, чтобы включить точку останова в вызываемой функции.

Если у вас есть Express Edition, вы обнаружите, что флажок «Запуск макроса», к сожалению, недоступен. В этом случае, если у вас есть доступ к исходному коду для вызывающей функции, я предлагаю следующее:

  1. Создайте глобальную переменную int, bp_enabled, изначально равную 1.
  2. --bp_enabled в первой строке calling_function().
  3. ++bp_enabled во всех точках выхода calling_function().
  4. Измените свойства «Condition ...» точки останова в вызываемой функции, чтобы она прерывалась только при bp_enabled == 1. (Перейдите к пункту Отладка | Windows | Точки останова, затем щелкните правой кнопкой мыши точку останова.)

Немного взломать, но это делает работу.

[EDIT: исправлено для правильной работы, даже если calling_function() рекурсивно (прямо или косвенно) вызывает себя ...]

0 голосов
/ 16 января 2009

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

Изменение кода только для отладки кажется самым простым - если это возможно.

0 голосов
/ 16 января 2009

Обновление: OP изначально не давал понять, что в начале использовался неуправляемый C ++. Так что этот ответ сейчас довольно бесполезен, потому что он будет работать только с управляемым кодом. Тем не менее, я оставлю это на тот случай, если кто-то споткнется и найдет это полезным или не знает о JMC:

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

.NET 2.0 представил новый атрибут: DebuggerNonUserCode. Это работает в сочетании с параметром Отладка только моего кода в Сервис-> Параметры-> Отладка-> Общие-> Включить только мой код.

Если установлен флажок «Включить только мой код», то любой метод, украшенный атрибутом DebuggerNonUserCode, не будет включен. Если вы хотите периодически включать отладку кода, отмеченного DebuggerNonUserCode, просто снимите этот флажок. Это экономит время на поиск и комментирование кода, через который вы обычно не будете интересоваться.

Чтобы использовать любой атрибут, просто украсьте методы по вашему выбору, например:

// The .NET 1.1 way
[DebuggerStepThrough]
public static void IgnoreMeAlways()
{
    Console.WriteLine("Hello...where is everybody!");
}

//The .NET2.0/VS2005/2008 way. Use in conjunction with Debug Just My Code
[DebuggerNonUserCode]
public static void NonUserCodeSomeTimes()
{
    Console.WriteLine("Longtime no see");
}
0 голосов
/ 16 января 2009

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

...