Не удается вычислить выражение visual studio
В предыдущих уроках («3.6 – Использование встроенного отладчика: пошаговое выполнение» и «3.7 – Использование встроенного отладчика: запуск и точки останова») вы узнали, как использовать отладчик для отслеживания пути выполнения вашей программы. Однако пошаговое выполнение программы – это только половина того, что делает отладчик полезным. Отладчик также позволяет вам отслеживать значения переменных при пошаговом выполнении кода, и всё это без изменения кода.
Как и в предыдущих уроках, в наших примерах будет использоваться Visual Studio – если вы используете другую IDE/отладчик, команды могут называться немного по-другому или располагаться в других местах.
Предупреждение
В случае сбоя в работе убедитесь, что ваш проект скомпилирован в конфигурации отладочной сборки (для получения дополнительной информации смотрите раздел «0.9 – Настройка компилятора: конфигурации сборки»). Если вы компилируете свой проект в конфигурации релиза, функции отладчика могут работать некорректно.
Отслеживание переменных
Отслеживание переменной – это процесс проверки значения переменной во время выполнения программы в режиме отладки. Большинство отладчиков предоставляют несколько способов сделать это.
Давайте посмотрим на пример программы:
Это пример довольно простой программы – она печатает числа 1, 3 и 6.
Сначала запустите выполнение до курсора в строке 6.
Рисунок 1 – Точка выполнения программы после запуска выполнения до курсора в строке 6
На данный момент переменная x уже создана и инициализирована значением 1, поэтому, когда мы проверяем значение x , мы должны ожидать увидеть значение 1.
Самый простой способ проверить значение простой переменной, такой как x , – навести указатель мыши на переменную x . Некоторые современные отладчики поддерживают этот метод проверки простых переменных, и это наиболее простой способ сделать это.
Для пользователей Code::Blocks
Если вы используете Code::Blocks, эта опция (необъяснимо) по умолчанию отключена. Давай включим. Сначала перейдите в меню Settings (Настройки) → Debugger (Отладчик). Затем в узле GDB/CDB debugger (отладчик GDB/CDB) выберите профиль Default (по умолчанию). И установите флажок «Evaluate expression under cursor» (Вычислять выражение под курсором).
Рисунок 2 – Включение вычисления выражения под курсором при отладке в Code::Blocks
Наведите курсор мыши на переменную x в строке 6, и вы должны увидеть что-то вроде этого:
Рисунок 3 – Отображение значения переменной x
Обратите внимание, что вы можете навести курсор на переменную x в любом месте, а не только в текущей строке. Например, если мы наведем курсор на x в строке 12, мы увидим то же значение:
Рисунок 4 – Отображение значения переменной x при наведении на нее курсора в любом месте
Если вы используете Visual Studio, вы также можете использовать Быструю проверку (QuickWatch). Выделите имя переменной x с помощью мыши, а затем выберите Быстрая проверка (QuickWatch) из контекстного меню.
Рисунок 5 – Меню вызова окна быстрой проверки значения переменой в Visual Studio
Это вызовет окно, содержащее текущее значение переменной:
Рисунок 6 – Окно быстрой проверки значения переменой в Visual Studio
Закройте окно быстрой проверки, если вы его открыли.
Теперь давайте посмотрим, как изменяется эта переменная по мере выполнения программы. Либо выполните два шага, либо выполнение до курсора на строке 9. Переменная x теперь должна иметь значение 3. Проверьте ее и убедитесь, что это так!
Рисунок 7 – Отображение измененного значения переменной x
Окно просмотра
Использование методов с наведением курсора или окна быстрой проверки для отслеживания переменных – это нормально, если вы хотите узнать значение переменной в определенный момент времени, но это не особенно хорошо подходит для наблюдения за изменением значения переменной при запуске кода, потому что вам постоянно приходится повторно выбирать / наводить курсор на переменную.
Чтобы решить эту проблему, все современные встроенные отладчики предоставляют еще одну функцию, называемую окном просмотра. Окно просмотра (watch window) – это окно, в котором вы можете добавлять переменные, которые вы хотели бы постоянно отслеживать, и эти переменные будут в нем обновляться по мере выполнения вашей программы. Окно просмотра может уже быть на вашем экране, когда вы входите в режим отладки, но если это не так, вы можете вызвать его с помощью команд управления окнами IDE (обычно они находятся в меню View (Вид) или Debug (Отладка)).
Для пользователей Visual Studio
В Visual Studio меню просмотра можно найти в меню Отладка (Debug) → Окна (Windows) → Контрольные значения (Watch) → Контрольные значения 1 (Watch 1). Обратите внимание, что для включения этой опции вы должны находиться в режиме отладки, поэтому сначала запустите свою программу.
Расположение этого окна (закреплено слева, справа или снизу) может отличаться. Вы можете изменить место закрепления, перетащив вкладку Контрольные значения на другую сторону окна приложения.
Для пользователей Code::Blocks
В Code::Blocks меню просмотра можно найти в меню Debug (Отладка) → Debugging windows (Окна отладки) → Watches (Просмотр). Это окно, скорее всего, появится отдельно. Вы можете закрепить его в главном окне, перетащив его.
Теперь вы должны увидеть что-то вроде этого:
Рисунок 8 – Окно отслеживания значений переменных
Окно просмотра может уже содержать или не содержать что-либо.
Обычно есть два разных способа добавить переменные в окно просмотра:
- откройте окно просмотра и введите имя переменной, которую вы хотите отслеживать, в крайнем левом столбце окна просмотра.
- в окне редактора кода кликните правой кнопкой мыши на переменной, которую вы хотите отслеживать, и выберите «Добавить контрольное значение» (Add Watch) (Visual Studio) или «Watch x» (Отслеживать x) (замените x на имя своей переменной) (Code::Blocks).
Если вы еще не находитесь в сеансе отладки с маркером выполнения в строке 9 вашей программы, запустите новый сеанс отладки и запустите выполнение до курсора на строке 9.
Теперь добавьте переменную «x» в свой список отслеживания. Вы должны увидеть следующее:
Рисунок 9 – Значение переменной x в окне отслеживания
Теперь сделайте два шага с обходом или запустите выполнение до курсора на строке 12, и вы увидите, что значение x изменилось с 3 на 6.
Переменные, выходящие за пределы области видимости (например, локальная переменная внутри функции, из которой уже был выполнен возврат к вызывающей стороне), останутся в вашем окне просмотра, но, как правило, будут либо помечены как «недоступные», либо могут отображать последнее известное значение, но выделенное серым цветом. Если переменная возвращается в область видимости (например, функция вызывается снова), ее значение снова начинает отображаться. Таким образом, можно оставить переменные в окне просмотра, даже если они находятся вне области видимости.
Использование окна просмотра – лучший способ наблюдать за изменением значения переменной с течением времени по мере выполнения программы.
Окно просмотра также может вычислять выражения
Окно просмотра также позволяет вам вычислять простые выражения. Если вы еще этого не сделали, запустите выполнение до курсора на строке 12. Затем попробуйте ввести x + 2 в окно просмотра и посмотрите, что произойдет (результат должен быть равен 8).
Вы также можете выделить выражение в своем коде, а затем проверить значение этого выражения, наведя курсор мыши или добавив его в окно просмотра через контекстное меню, вызываемое правой кнопкой мыши.
Предупреждение
Идентификаторы в отслеживаемых выражениях будут вычислять свои текущие значения. Если вы хотите знать, какое значение на самом деле вычисляет выражение в вашем коде, сначала запустите выполнение до курсора к нему, чтобы все идентификаторы имели правильные значения.
Отслеживание локальных переменных
Поскольку отслеживание значений локальных переменных внутри функции является обычным делом при отладке, многие отладчики предоставляют способ быстро просмотреть значение всех локальных переменных в области видимости.
Для пользователей Visual Studio
В Visual Studio вы можете увидеть значение всех локальных переменных в окне Локальные (Locals), которое можно найти в меню Отладка (Debug) → Окна (Windows) → Локальные (Locals). Обратите внимание, что вы должны находиться в сеансе отладки, чтобы активировать это окно.
Для пользователей Code::Blocks
В Code::Blocks это интегрировано в окно Watch (Просмотр) в узле Locals (Локальные переменные). Если вы их не видите, значит, их либо нет, либо вам нужно развернуть узел.
Если вы просто хотите посмотреть значение локальной переменной, сначала проверьте окно локальных переменных. Она уже должна быть там.
Я использую Visual Studio 2010 в режиме отладки, и у меня снят флажок" оптимизировать код". Я не могу быстро посмотреть (или навести курсор) на любую переменную в отладчике. Я получаю эту ошибку "не могу оценить выражение, потому что код текущего метода оптимизирован".
даже такая строка, как: int i = -3, делая быстрый просмотр на i, я получаю "не могу получить значение локального или аргумента "i", поскольку он недоступен в этом указателе инструкции, возможно, потому, что он был оптимизирован прочь."
этой ссылке ссылка на аналогичный вопрос, похоже, не применяется.
есть ли настройка, которую я пропускаю?
пока проект находился в режиме отладки, решение не было. Когда я изменил его, он сработал.
У меня была эта проблема, когда я использовал VS 2010. Выбрана конфигурация моего решения (Debug). Я решил это, сняв флажок оптимизировать свойство кода в разделе свойства проекта. Project (щелкните правой кнопкой мыши)=> Properties => Build (tab) => снимите флажок оптимизировать код
похоже, что вы отлаживаете оптимизированную / выпускную сборку, несмотря на то, что оптимизированная коробка не проверена. Вещи, которые вы можете попробовать:
- выполните полную перестройку файла решения (щелкните правой кнопкой мыши на решении и выберите перестроить все)
- во время отладки откройте окно модули (Debug -> Windows -> Modules) и найдите свою сборку в списке загруженных модулей. Убедитесь, что путь, указанный в загруженной сборке, является тем, что вы ожидаете, и что измененная метка времени файла указывает на то, что сборка была фактически перестроена.
- окно "модули" также должно сообщить вам, оптимизирован ли загруженный модуль или нет - убедитесь, что окно "модули" указывает, что оно не оптимизировано.
Если вы не можете увидеть пункт меню модули в меню отладка - > Windows, то вам может потребоваться добавить его в "настроить. " меню.
в VS2013 перейдите в: Инструменты - > Параметры - > отладка - > общие и включите "использовать режим управляемой совместимости". Это отключает поведение оценки новой функции.
У меня была такая же проблема в VS2008. В моем случае это было решено с помощью решения-rebuild.
помимо упомянутого @Kragen, если вы отлаживаете веб-проект
Что касается проблемы с отключенным свойством "оптимизировать код", но код все еще компилируется как оптимизированный: что, наконец, помогло мне после попытки все проверить флажок" включить отладку неуправляемого кода " на той же странице настроек (свойства проекта - отладка). Это напрямую не связано с оптимизацией кода, но с включенным этим VS больше не оптимизирует мою библиотеку, и я могу отлаживать.
У меня была такая же проблема при отладке библиотеки классов из тестирования веб-приложения. Я ссылался на версию выпуска на тестовом стенде, и она была настроена для оптимизации в свойствах библиотеки классов.
снимите флажок оптимизировать код для версии выпуска в свойствах библиотеки классов, пока я пишу его, решил проблему.
еще одна вещь, которую вы можете сделать, это создать файл с тем же именем, что и dll, который оптимизирован, но с расширением ini и добавить к нему следующее:
Это скажет JIT не оптимизировать ваши переменные.
обратите внимание, что вам все еще нужен pdb, поэтому вы получите что - то вроде этот: библиотеки DLL.файл DLL библиотеки DLL.распределительная плата библиотеки DLL.ini
Это особенно хорошо работает в сценариях, когда у вас нет доступа к повторной генерации DLL с опцией отладки.
Я понимаю, что это более поздний ответ, но я нашел еще одну ссылку на способ решения этой проблемы, которая может помочь другим в будущем. Это веб-страницы описывает установку переменной среды (COMPLUS_ZapDisable=1), которая предотвращает оптимизацию, по крайней мере, для меня! (Не забудьте вторую часть отключения процесса размещения Visual Studio.) В моем случае это могло бы быть еще более актуальным, потому что я отлаживал внешнюю DLL через сервер символов, но я не конечно.
У меня была та же проблема. Но в моем случае атрибут Debuggable был жестко закодирован в AssemblyInfo.cs-файл моего проекта и поэтому не написан компиляцией. Он работал после удаления строки, задающей атрибут Debuggable.
после сравнения XML файла проекта со здоровым, проблема была очевидна: здоровый проект имел явное <optimize>false</optimize> line, в то время как плохой его не хватало полностью. VS явно выводил из своего отсутствия, что оптимизация была отключена, в то время как компилятор делал обратное.
решение состояло в том, чтобы добавить это свойство в файл проекта и перезагрузить.
У меня была такая же проблема в VS 2010. Очистили и перестроили решение, и оно сработало.
чтобы положить его, чтобы он не потерялся, для затронутого проекта(ов):
Свойства Проекта --> Сборка -- >Дополнительно --> Отладочная Информация: Полная.
вы хотите проверить, что у вас выбрана конфигурация отладки, прежде чем делать это, если, конечно, вы не намеревались иначе.
Если вы пытаетесь отладить ASP.NET проект, убедитесь, что в раскрывающемся списке Свойства проекта > веб > серверы установлено значение "IIS Express" (в дополнение к проверке всего остального здесь).
Так же не везде удается установить breakpoints. Возможно эти проблемы связаны между собой.
1. Заново выполнить Attach to Process.
2. Установка Suppress JIT optimization on module load в настройках дебага.
3. В Build проекта снята галка Optimize code и Debugging information = Full
Вам необходимо в Options-Debugging-General также отключить флаг Enable Just My Code.
Илья,
Спасибо за ответ,
Однако, даже с отключенным флагом я могу установить breakpoints не везде, так же могу посмотреть значения только некоторых переменных.
Вот более свежий случай, причём от него же. Судя по молчанию автора, он таки решил свой вопрос или нашёл какой-то обходной способ.
Иван Небеддаг,
Алгоритм работы, при котором работает отладка у меня:
1. Если есть изменения в гите, то забрать их, это действие обновит часть содержимого из папки Pkg. Далее в конфигурации забрать изменения из файловой системы, компилировать измененное. Если изменений нет, то не нужно.
2. Создать класс в конфигураторе, сохранить. С бизнес процессом аналогично. Сохранение автоматически выгружает изменения в файловую систему.
3. Написать в студии логику, нажать на сохранить все.
4. Нажать на компилировать измененное в конфигураторе.
5. Подключиться дебаггером к процессу IIS, установить точки останова.
6. Нажать на компилировать измененное в конфигураторе. По завершении компиляции в студии будут прогружены необходимые для дебага файлы, после чего точки останова станут активны. При отладке, так же будут видны значения переменных и тд.
Нашел баг, при котором на измененной логике точки останова устанавливаются, однако значения переменных смотреть не выходит.
В этом случае после первой компиляции (п4) необходимо нажать на выгрузить измененное в файловую систему, после чего запустить повторно компиляцию, и далее 5, 6.
Надеюсь, помог. Если не помог, и Ваше решение отличается от моего, напишите его суда, пожалуйста. Для истории будет полезно.
Я использую Visual Studio 2010 в режиме отладки, и у меня снят флажок "optimize code". Я не могу быстро просмотреть (или навести курсор) какую-либо переменную в отладчике. Я получаю эту ошибку "не могу вычислить выражение, потому что код текущего метода оптимизирован".
Даже такая строка, как: int i = -3, делая быстрый просмотр на i, я получаю "не может получить значение local или аргумент 'i', так как он недоступен в этом указателе инструкции, возможно, потому, что он был оптимизирован."
Эта ссылка , на которую ссылаются в аналогичном вопросе, по-видимому, неприменима.
Есть ли какая-то настройка, которую я упускаю?
22 ответа
Существует проект с открытым исходным кодом ( Keepass ) с 3 .csproj файлами. Когда я открою основное решение, оно спросит меня о преобразовании, и оно пройдет через этот процесс без каких-либо проблем. За исключением того, что KeepassLibSD не преобразуется. The project type is not supported by.
Пока проект находился в режиме отладки, решения не было. Когда я изменил его, он сработал.
У меня была эта проблема, когда я использовал VS 2010. Выбрана конфигурация моего решения (отладка). Я решил эту проблему, сняв флажок Оптимизировать свойство кода в разделе свойства проекта. Проект (щелкните правой кнопкой мыши)=> Свойства => Сборка (вкладка) => снимите флажок Оптимизировать код
Похоже, что вы отлаживаете оптимизированную сборку / выпуск, несмотря на то, что флажок "Оптимизировано" не установлен. Вещи, которые вы можете попробовать, это:
- Выполните полную перестройку файла решения (щелкните правой кнопкой мыши на решении и выберите Перестроить все)
- Во время отладки откройте окно модули (Debug -> Windows -> Modules) и найдите свой assembly в списке загруженных модулей. Убедитесь, что путь, указанный в вашем загруженном assembly, является тем, что вы ожидаете, и что измененный timestamp файла указывает на то, что assembly был фактически перестроен.
- Окно модули также должно сообщить вам, оптимизирован ли загруженный модуль или нет - убедитесь, что окно модули указывает, что он не оптимизирован.
Если вы не видите пункт меню Модули в меню Debug -> Windows, возможно, вам потребуется добавить его в меню "Customise. ".
Для меня это происходило в VS2017 и VS2019 годах. Это перестало происходить после того, как я выбрал опцию "Suppressed JIT optimization on module load".
В VS2013 перейдите в раздел: Инструменты -> Параметры -> Отладка -> Общие и включите "Использовать режим управляемой совместимости". Это отключает поведение оценки новой функции.
У меня была та же проблема. Но в моем случае атрибут Debuggable был жестко закодирован в файле AssemblyInfo.cs моего проекта и поэтому не был (перезаписан)компиляцией. Это сработало после удаления строки, указывающей атрибут Debuggable .
У меня была такая же проблема в VS2008. В моем случае это было решено с помощью решения-перестроения.
Помимо упомянутого @Kragen, если вы отлаживаете веб-проект
Внезапно я получил следующую ошибку при отладке приложений в Visual Studio 2010 beta 2. Невозможно вычислить выражение, потому что поток останавливается в точке, где сбор мусора невозможен, возможно, потому, что код оптимизирован Почти каждое свойство или поле в окне просмотра отображает это.
Еще одна вещь, которую вы можете сделать, это создать файл с тем же именем, что и dll, который оптимизирован, но с расширением ini, и добавить к нему следующее:
Это подскажет JIT не оптимизировать ваши переменные.
Обратите внимание, что вам все еще нужен pdb, поэтому вы получите что-то вроде этого: yourDll.dll yourDll.pdb yourDll.ini
Это особенно хорошо работает в сценариях, когда у вас нет доступа к повторному созданию библиотек DLL с опцией отладки.
Что касается проблемы со свойством "Optimize code", являющимся UNCHECKED, но код все еще компилируется как оптимизированный: Что, наконец, помогло мне после того, как я попробовал все, проверил "Enable unmanaged code debugging" checkbox на той же странице настроек (свойства проекта - Отладка). Это напрямую не связано с оптимизацией кода, но с включенной функцией VS больше не оптимизирует мою библиотеку, и я могу отлаживать.
У меня была такая же проблема при отладке библиотеки классов из веб-приложения на тестовом стенде. Я ссылался на версию выпуска на тестовом стенде, и она была настроена для оптимизации в свойствах библиотеки классов.
Снятие галочки с кода оптимизации checkbox для версии выпуска в свойствах библиотеки классов, как раз в то время, когда я его пишу, решило проблему.
Я понимаю, что это более поздний ответ, но я нашел еще одну ссылку на способ решения этой проблемы, который может помочь другим в будущем. Эта веб-страница описывает настройку переменной среды (COMPLUS_ZapDisable=1), которая предотвращает оптимизацию, по крайней мере, для меня! (Не забудьте вторую часть отключения хостинга Visual Studio.) В моем случае это могло бы быть еще более актуальным, потому что я отлаживал внешний DLL через сервер символов, но я не уверен.
После сравнения XML файла проекта с файлом здорового проекта проблема была очевидна: в здоровом проекте была явная строка <optimize>false</optimize> , в то время как в плохом она полностью отсутствовала. VS, очевидно, выводил из его отсутствия, что оптимизация отключена, в то время как компилятор делал обратное.
Решение состояло в том, чтобы добавить это свойство в файл проекта и перезагрузить его.
. из вашего файла AssemblyInfo.
У меня была такая же проблема в VS 2010. Очистите и восстановите решение, и оно сработало.
Чтобы записать его, чтобы он не был потерян, для затронутого проекта(ов):
Свойства проекта --> Сборка --> Дополнительно --> Отладочная информация: Полная.
Вы хотите проверить, что у вас выбрана конфигурация отладки, прежде чем делать это, если, конечно, вы не намеревались сделать иначе.
Если вы пытаетесь отладить проект ASP.NET, убедитесь, что в раскрывающемся списке Свойства проекта > Веб-сервер > Серверы установлено значение "IIS Express" (в дополнение к проверке всего остального здесь).
У меня были смешанные библиотеки DLL расширения c++/cli mfc, которые были оптимизированы, даже если конфигурация отладки (видно из окна модулей VS 2017). Как и предполагалось в предыдущем ответе, я изменил "В VS2013 перейдите в раздел: Инструменты -> Параметры -> Отладка -> Общие и включите "Использовать режим управляемой совместимости". Это отключает поведение оценки новой функции." Эти настройки также находятся в VS 2017.
Но этого было недостаточно, поэтому я также скопировал параметр UseDebugLibraries из файла проекта другого приложения MFC в файл проекта расширения dll.
Затем восстановите, и это исправит проблему.
В Visual Studio 2012 включение опции "управляемый" из меню Инструменты > отладка > Just-In-Time сработало для меня.
Похожие вопросы:
Я написал некоторый код с большим количеством рекурсии,который занимает довольно много времени. Всякий раз, когда я бегу посмотреть, что происходит, я получаю: Невозможно вычислить выражение, так.
Существует проект с открытым исходным кодом ( Keepass ) с 3 .csproj файлами. Когда я открою основное решение, оно спросит меня о преобразовании, и оно пройдет через этот процесс без каких-либо.
Внезапно я получил следующую ошибку при отладке приложений в Visual Studio 2010 beta 2. Невозможно вычислить выражение, потому что поток останавливается в точке, где сбор мусора невозможен.
catch (Exception ex) возвращает невозможно вычислить выражение, потому что код оптимизирован или собственный фрейм находится поверх стека вызовов в этом коде: cmsql = cnsql.CreateCommand();.
Во-первых, извините, если это было задано раньше или кажется глупым вопросом. Но я играл с visual studio 2010, заставляя несколько форм щелкать и обрабатывать вместе, чтобы выполнить функцию.
Читайте также: