Может ли исходный код .NET жестко кодировать точку останова отладки? - PullRequest
68 голосов
/ 12 декабря 2008

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

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

Моя попытка использовать Debug.Assert(false) была не идеальной, и я предполагаю, что Debug.Fail() будет вести себя так же. Теоретически он не должен иметь никакого эффекта в работе, и он успешно останавливается при отладке, но по своей конструкции (насколько я могу судить) нет способа продолжить выполнение, если вы хотите игнорировать эту ошибку, как вы могли бы с реальной точкой останова И, как это было бы в производстве, где мы глотаем ошибку. Это также явно нарушает оценку состояния переменной, потому что отладчик фактически останавливается в собственном системном коде, а не в нашем, поэтому его помощь в отладке ограничена. (Возможно, мне не хватает способа вернуться к вещам, чтобы посмотреть на переменные и так далее, где это произошло. ???)

Я надеялся на что-то вроде Debug.Break(), но его, похоже, не существует (разве что в более поздней версии .NET?), И никакие другие методы Debug не кажутся применимыми.

Обновление: Хотя ответ ctacke - лучшее совпадение с тем, что я искал, с тех пор я также обнаружил уловку с Debug.Assert () - при работе в отладчике - приостановить отладчик перейдите к коду ожидающего вызова Debug.Assert (выделено зеленым, потому что он находится в коде платформы) и нажмите Step-Out (shift-F11), затем нажмите Ignore в диалоговом окне assert. Это оставит отладчик на паузе после возврата подтверждения (и сможет продолжить выполнение, как если бы оно не произошло, потому что оно было проигнорировано). Могут быть и другие способы сделать то же самое (делает ли Retry это более прямым?), Но этот способ был интуитивно понятным.

Ответы [ 7 ]

127 голосов
/ 12 декабря 2008

Вы, вероятно, ищете что-то вроде этого:

if(System.Diagnostics.Debugger.IsAttached)
  System.Diagnostics.Debugger.Break();

Конечно, это все равно будет скомпилировано в сборке Release. Если вы хотите, чтобы он вел себя больше как объект Debug, где код просто не существует в сборке Release, вы можете сделать что-то вроде этого:

    // Conditional("Debug") means that calls to DebugBreak will only be
    // compiled when Debug is defined. DebugBreak will still be compiled
    // even in release mode, but the #if eliminates the code within it.
    // DebuggerHidden is so that, when the break happens, the call stack
    // is at the caller rather than inside of DebugBreak.
    [DebuggerHidden]
    [Conditional("DEBUG")] 
    void DebugBreak()
    {
        if(System.Diagnostics.Debugger.IsAttached)
            System.Diagnostics.Debugger.Break();
    }

Затем добавьте к нему вызов в своем коде.

12 голосов
/ 12 декабря 2008

System.Diagnostics.Debugger.Break * * 1002

9 голосов
/ 27 мая 2017

Если вы хотите иметь только одну строку кода вместо 4, оберните

#if DEBUG
       if (Debugger.IsAttached)
            Debugger.Break();
#endif

в

public static class DebugHelper
{
    [DebuggerHidden]
    [Conditional("DEBUG")]
    public static void Stop()
    {
       if (Debugger.IsAttached)
            Debugger.Break();
    }
}

и используйте

DebugHelper.Stop();

DebuggerHiddenAttribute был добавлен для предотвращения остановки отладчиком внутреннего кода метода Stop и перехода в метод с помощью F11.

9 голосов
/ 12 декабря 2008

Я однажды столкнулся с ситуацией, когда это не сработало

System.Diagnostics.Debugger.Break();

но это сделал

System.Diagnostics.Debugger.Launch();
4 голосов
/ 12 декабря 2008

Как насчет простой настройки Visual Studio для всплывающего окна с отладчиком, даже если вы проглотили его?

Сделайте это:

  • Перейти в Debug-> Исключения ...
  • Найдите правильное исключение или добавьте его, если оно ваше
  • Установите флажок «Брошенный» для исключения

Это остановит Visual Studio в месте, где выдается исключение, а не только в том случае, если оно не обработано.

Вы можете увидеть больше информации здесь .

3 голосов
/ 12 декабря 2008

Хороший трюк, который я нашел, - это поместить Debugger.Break () в ctor вашего исключения.

1 голос
/ 23 ноября 2011

В Visual Studio 2010 нажатие Retry в диалоговом окне Debug.Assert приведет вас к ошибочному утверждению отладки, как если бы у вас была точка останова.

...