Использовать количество попаданий одной точки останова для состояния другой точки останова
Я использую Visual Studio 2008 на коде C#.
Я хотел бы сломать точку останова только в том случае, если другая точка останова была достигнута (и сломана). Есть ли способ сделать это?
Я думаю, что в качестве подзадачи было бы неплохо получить доступ к информации, которая есть у отладчика.
Обоснование этого заключается в том, что меня интересует только нарушение определенной точки останова с учетом определенного стека вызовов (и в определенный момент выполнения одной из этих функций в стеке вызовов). Возможно, я должен использовать колл-стэк вместо этого? Другая причина в том, что было бы интересно иметь программный доступ к тому, о чем знает отладчик.
Благодарю.
1 ответ
Использование локальной переменной
Самый простой способ создать такую условную точку останова - создать новую потоковую статическую переменную (или просто статическую, если она должна быть глобальной). Предположим, что наш код выглядит следующим образом:
class Program
{
#if DEBUG
[ThreadStatic]
static int breakVariable = 0;
#endif
static void Main(string[] args)
{
TestMethod2();
TestMethod1();
TestMethod2();
TestMethod2();
TestMethod1();
TestMethod2();
}
static void TestMethod1()
{
Console.WriteLine("test1");
}
static void TestMethod2()
{
Console.WriteLine("test2");
}
}
Теперь давайте предположим, что вы установили точку останова на Console.WriteLine("test1");
и точка останова 2 на Console.WriteLine("test2");
, Вы хотели бы остановиться на точке останова 2 только тогда, когда на точку останова 1 был нанесен удар 2 раза. В этом случае вам нужно будет установить Hit Count...
свойство breapoint1 для break when the hit count is equal to 2
, Тогда в When Hit...
проверка имущества Print a message
и в текстовом поле введите: {breakVariable = 1}
:
Затем установите свойство Condition...
точки останова2 в breakVariable == 1
и проверить Is true
:
Если вы хотите, чтобы точка останова2 стала неактивной после удара, вы можете снова использовать When Hit...
Свойство, устанавливающее его Print a message
значение для {breakVariable=0}
,
Использование макроса
Этот подход намного сложнее, особенно если вам не нравится VBA (как я:)), но вам может быть интересно, так как он не требует никаких изменений в коде приложения. Давайте определим два макроса:
Imports System
Imports EnvDTE
Imports EnvDTE80
Imports EnvDTE90
Imports EnvDTE90a
Imports EnvDTE100
Imports System.Diagnostics
Public Module Module1
Public Sub SetMyBreakpoint()
Dim bps As EnvDTE.Breakpoints
bps = DTE.Debugger.Breakpoints.Add(File:="C:\MyProject\ConsoleApplication1\Program.cs", _
Line:=25)
Dim bp As EnvDTE80.Breakpoint2
For Each bp In bps
bp.Tag = "mytag"
' Add this line only if you want the breakpoint to be removed on hit
' Although I don't know why - it does not always worked :(
bp.Macro = "Macros.MyMacros.Module1.RemoveMyBreakpoint"
Next
End Sub
Public Sub RemoveMyBreakpoint()
Dim bp As EnvDTE.Breakpoint
For Each bp In DTE.Debugger.Breakpoints
If (bp.Tag = "mytag") Then
bp.Delete()
End If
Next
End Sub
End Module
Теперь для точки останова1 вы все еще хотите установить Hit Count...
собственность, как раньше, но теперь в When Hit...
свойство вместо проверки Print a message
проверять Run a macro
и выберите SetMyBreakpoint
процедура. Очень важно, чтобы вы указали полный путь к файлу кода в Breakpoints.Add
метод и правильная строка (вы можете проверить API, чтобы найти другие способы установки точки останова, например, для функции вместо файла кода). Одно маленькое замечание: я заметил, что автоматическое удаление второй точки останова не всегда работает, но, возможно, это была моя Visual Studio.
Использование стека вызовов
Вы можете снова использовать Condition
свойство точки останова - посмотрите на этот вопрос, чтобы найти некоторые детали.