Отладка во время паузы и "не может оценивать выражение"
Используя Visual Studio, после присоединения к процессу и нажатия кнопки Pause (Break-All), вы переключаетесь на нужный поток и используете окно Quick Watch, чтобы проверить некоторые данные, скажем
MySingletonClass.Instance.Data
Иногда я либо получаю это:
Невозможно оценить выражение, потому что текущий поток находится в режиме ожидания, ожидания или соединения
или это (при попытке просмотра определенных свойств данных):
Невозможно оценить выражение, потому что собственный кадр находится поверх стека вызовов.
Честно говоря, мне все равно, я просто хочу посмотреть данные! Я знаю, что есть разные способы обойти это, а именно:
- Установка точки останова в потоке и ожидание, пока она не пострадает (громоздко, не всегда возможно).
- Получение дампа процесса и загрузка обратно в VS (даже тогда я все еще получаю вторую ошибку)
- WinDbg
Учитывая, что вы можете видеть эти данные, если вы предположительно использовали windbg, почему мы все не можем использовать намного проще и красивее VS для проверки объектов при присоединении к процессу?
Ответы
Ответ 1
Почему мы не делаем этого? Мы не можем этого сделать, потому что окно просмотра Visual Studio не просто извлекает данные из памяти и отображает их. Он фактически выполняет управляемый код (это то, что означает "оценивать выражение" ). В частности, он почти всегда выполняет метод ToString()
для отображения пользовательского результата.
Суть в том, что он выполняет этот код в процессе/потоке, который вы отлаживаете. Это гарантирует, что выражение оценивается так же, как если бы оно находилось в коде, который вы отлаживаете. Это оставляет недостаток, что он может выполняться только между управляемыми инструкциями, но не в том случае, если собственный код активен, а не в заблокированном потоке.
Что мы можем сделать с этим? Если вы действительно отлаживаете управляемое приложение и находитесь в собственном стеке, просто нажимайте F10 или Shift + F11, пока не вернетесь в управляемый код. Затем вы можете оценить выражения. Однако для полностью родных процессов и для потоков в заблокированном состоянии я не знаю об обходном пути.
Ответ 2
Вот ссылка для обсуждения этой проблемы. По-видимому, когда аргументы функции являются структурами, а общая память, необходимая для стека для вызова функции, превосходит некоторые магические числа для отладки визуальной студии.
Дополнительная ссылка из обсуждения в OpenTK.
Ответ 3
Просто нажмите Shift-F11, пока на стеке не будет установлен фрейм управляемого стека, и вы сможете делать то, что хотите в VS.
В основном это сводится к тому, что при выполнении процесса небезопасно оценивать выражения в определенных точках или вы рискуете повредить среду выполнения. WinDbg не защищает время выполнения от вас. VS делает.
Ответ 4
Проблема заключается в том, что это не данные, которые вы хотите увидеть, это результат запуска некоторого кода. В свойствах .Net на самом деле просто маскируются методы, поэтому для получения значения свойства Visual Studio необходимо выполнить код приложения (эта функция называется FuncEval).
Этот код должен запускаться в каком-то потоке, а VS - это то, что для этого используется один из приложений. Существует ряд ситуаций, где VS не может запустить код для получения результата, и именно тогда вы видите сообщения об ошибках, я говорю.
Ответ 5
Если вы переходите к следующей инструкции, отладчик может иметь достаточно времени, чтобы оценить его до истечения времени ожидания.
Заметьте, что это обычно не работает.
Ответ 6
Если ваш проект является клиентским сервером, попробуйте перезагрузить ссылку MySql.Data.dll
Ответ 7
Я знаю, что это kludge, но я доволен тем, как он работает. В конце моего метода Main(), который изначально запускает все и создает все другие структуры данных и потоки, а затем завершается, я придерживаюсь этого:
while (true)
{
// This infinite while loop just gives me a convenient place for a
// breakpoint, so I can see everything everywhere during debugging.
Thread.Sleep(100);
}
Вместо того, чтобы делать "Break All", я просто придерживаюсь точки останова на фигурной скобке {. Программа прерывается. У меня есть поток и ссылка на все, поэтому я могу легко просматривать все структуры данных и все потоки, видеть все везде.