Just-in-Time debugging
Имеется интересная опция отладки Just-in-Time debugging (назовем ее отладкой здесь-и-теперь). При отладке здесь-и-теперь ваше приложение работает вне интегрированной среды Visual C++, пока не происходит ошибки. При ошибке программы автоматически запускается отладчик Visual C++. Чтобы построить программу с возможностью отладки здесь-и-теперь, нужно сделать следующее:
1. Выберите Options в меню Tools.
2. Выберите закладку Debug.
3. Пометьте флажок Just-in-Time debugging.
5. В меню Build выполните Build <имя проекта>.exe.
Чтобы активировать отладку здесь-и-теперь в Windows NT, программист должен иметь привилегии администратора.
Страница Debug в окне Options
Отладчик очень гибок в отношении форматирования выводимых данных. В то время как многие опции можно менять «на ходу», иногда предпочтителен единообразный формат вывода. Рис.8показывает страницу Debug окна Орtions для установки таких предопределенных форматов. К странице Debug можно обратиться через меню Tools | Options. Имеющиеся на странице установки описываются в следующих параграфах.
Рис.8 Страница Tools | Options | Debug.
В табл.5 даны комментарии к флагам опций отладчика MS VC++6.0.
Таблица 5. Опции Debug.
При установке этого флажка все выводимые значения представляются, а вводимые пользователем воспринимаются как шестнадцатеричные. Когда флажок помечен, обычные десятичные значения можно вводить с префиксом On, например Оn123456789.
При установке флажка вывод вашего исходного кода сопровождается параллельным переводом на язык ассемблера.
При установке с каждой инструкцией ассемблера ассоциируются байты машинного кода.
Опция выводит в окне Disassembly символические имена адресов.
Опция выводит в окне стека вызовов все значения, переданные в параметрах функций.
Опция выводит в окне стека вызовов информацию о типах переданных функции параметров.
Опция отображает в окне Variables значения, возвращаемые функциями.
Load COFF & Exports
Опция позволяет отладчику при отсутствии отладочной информации загружать COFF-формат или экспортируемые символы DLL.
Окно Address позволяет указать начальный адрес по умолчанию для окна Memory Dump.
Этот список позволяет выбрать формат по умолчанию для типа данных в окне дампа памяти; доступно 13 форматов, таких как ASCII, Byte, Long, Real и Int64.
Эта опция автоматически перемещает содержимое окна Memory Dump. Когда вы вводите в окне Memory Dump имя переменной-указателя, содержимое окна будет обновляться всякий раз, когда адрес в указателе меняется. При выключенной опции содержимое окна дампа меняться не будет, даже если адрес-содержимое переменной изменяется.
Show data bytes
Отображаются сырые байту данных.
Указывает формат фиксированной ширины для окна Memory Dump. Работает совместно со списком Format.
Display Unicode strings
Отображает строки формата Unicode. Это полезно, когда отлаживаемое приложение вводит и выводит тексты в многоязыковых форматах.
View floating point registers
Отображает в окне Registers содержимое регистров плавающей арифметики.
Построенная с такой опцией программа может выполняться вне среды Visual Studio, загружая отладчик Visual C++ только при возникновении ошибки.
OLE RFC debugging
Позволяет отлаживать вызовы удаленных процедур.
Debug commands invoke Edit and Continue
Когда этот флажок установлен, многие, хотя и не все изменения исходного кода могут автоматически вноситься в исполняемый модуль программы при исполнении таких команд, как Go, Step Into, Step Over или Run.
Name already in use
visualstudio-docs / docs / debugger / debug-using-the-just-in-time-debugger.md
- Go to file T
- Go to line L
- Copy path
- Copy permalink
15 contributors
Users who have contributed to this file
- Open with Desktop
- View raw
- Copy raw contents Copy raw contents
Copy raw contents
Copy raw contents
Debug using the Just-In-Time Debugger in Visual Studio
Just-In-Time debugging can launch Visual Studio automatically when an app running outside Visual Studio errors or crashes. With Just-In-Time debugging, you can test apps outside of Visual Studio, and open Visual Studio to begin debugging when a problem occurs.
Just-In-Time debugging works for Windows desktop apps. It does not work for Universal Windows Apps, or for managed code that is hosted in a native application, such as Visualizers.
[!TIP] If you just want to stop the Just-In-Time Debugger dialog box from appearing, but don’t have Visual Studio installed, see Disable the Just-In-Time Debugger. If you once had Visual Studio installed, you may need to disable Just-In-Time debugging from the Windows registry.
Enable or disable Just-In-Time debugging in Visual Studio
[!NOTE] To enable or disable Just-In-Time debugging, you must be running Visual Studio as an administrator. Enabling or disabling Just-In-Time debugging sets a registry key, and administrator privileges may be required to change that key. To open Visual Studio as an administrator, right-click the Visual Studio app and choose Run as administrator.
You can configure Just-In-Time debugging from the Visual Studio Tools > Options (or Debug > Options) dialog box.
To enable or disable Just-In-Time debugging:
On the Tools or Debug menu, select Options > Debugging > Just-In-Time.

[!NOTE] If the Just-In-Time menu option is not shown, make sure the Just-In-Time debugger is installed using the Visual Studio Installer.
In the Enable Just-In-Time debugging for these types of code box, select the types of code you want Just-In-Time debugging to debug: Managed, Native, and/or Script.
Select OK.
If you enable the Just-In-Time debugger, but it doesn’t open when an app crashes or errors, see Troubleshoot Just-In-Time debugging.
Disable Just-In-Time debugging from the Windows registry
Just-In-Time debugging may still be enabled even if Visual Studio is no longer installed on your computer. If Visual Studio is no longer installed, you can disable Just-In-Time debugging by editing the Windows registry.
To disable Just-In-Time debugging by editing the registry:
From the Windows Start menu, run the Registry Editor (regedit.exe).
In the Registry Editor window, locate and delete the following registry entries if they exist:
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\.NETFramework\DbgManagedDebugger
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows NT\CurrentVersion\AeDebug\Debugger
. image type=»content» source=»../debugger/media/dbg-jit-registry.png» alt-text=»JIT registry key» border=»true».
Also delete the following registry entries if they exist:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\DbgManagedDebugger
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AeDebug\Debugger
Make sure not to delete or change any other registry keys.
Close the Registry Editor window.
Enable Just-In-Time debugging of a Windows Form
By default, Windows Form apps have a top-level exception handler that lets the app keep running if it can recover. If a Windows Forms app throws an unhandled exception, it shows the following dialog:

To enable Just-In-Time debugging instead of standard Windows Form error handling, add these settings:
In the system.windows.forms section of the machine.config or <app name>.exe.config file, set the jitDebugging value to true :
In a C++ Windows Form application, also set DebuggableAttribute to true in a .config file or in your code. If you compile with /Zi and without /Og, the compiler sets this attribute for you. If you want to debug a non-optimized release build, however, you must set DebuggableAttribute by adding the following line in your app’s AssemblyInfo.cpp file:
For more information, see xref:System.Diagnostics.DebuggableAttribute.
Use Just-In-Time debugging
This example walks you through Just-In-Time debugging when an app throws an error.
You must have Visual Studio installed to follow these steps. If you don’t have Visual Studio, you can download the free Visual Studio Community Edition.
Make sure Just-In-Time debugging is enabled in Tools > Options > Debugging > Just-In-Time.
For this example, you’ll make a C# console app in Visual Studio that throws a NullReferenceException.
In Visual Studio, create a C# console app (File > New > Project > Visual C# > Console Application) named ThrowsNullException. For more information about creating projects in Visual Studio, see Walkthrough: Create a simple application.
When the project opens in Visual Studio, open the Program.cs file. Replace the Main() method with the following code, which prints a line to the console and then throws a NullReferenceException:
To build the solution, choose either the Debug (default) or Release configuration, and then select Build > Rebuild Solution.
- Choose Debug configuration for the full debugging experience.
- If you select Release configuration, you must turn off Just My Code for this procedure to work. Under Tools > Options > Debugging, deselect Enable Just My Code.
For more information about build configurations, see Understanding build configurations.
Open the built app ThrowsNullException.exe in your C# project folder (. \ThrowsNullException\ThrowsNullException\bin\Debug or . \ThrowsNullException\ThrowsNullException\bin\Release).
You should see the following command window:

The Choose Just-In-Time Debugger dialog opens.

Under Available Debuggers, select New instance of <your preferred Visual Studio version/edition>, if not already selected.
Select OK.
The ThrowsNullException project opens in a new instance of Visual Studio, with execution stopped at the line that threw the exception:

You can start debugging at this point. If you were debugging a real app, you would need to find out why the code is throwing the exception.
[!CAUTION] If your app contains untrusted code, a security warning dialog box appears, enabling you to decide whether to proceed with debugging. Before you continue debugging, decide whether you trust the code. Did you write the code yourself? If the application is running on a remote machine, do you recognize the name of the process? If the app is running locally, consider the possibility of malicious code running on your computer. If you decide the code is trustworthy, select OK. Otherwise, select Cancel.
Troubleshoot Just-In-Time debugging
If Just-In-Time debugging doesn’t start when an app crashes, even though it is enabled in Visual Studio:
Windows Error Reporting could be taking over the error handling on your computer.
To fix this issue, use Registry Editor to add a DWORD Value of Disabled, with Value data of 1, to the following registry keys:
HKEY_LOCAL_MACHINE\Software\WOW6432Node\Microsoft\Windows\Windows Error Reporting
(For 32-bit machines) HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\Windows Error Reporting
For more information, see .WER settings.
A known Windows issue may be causing the Just-In-Time debugger to fail.
The fix is to add a DWORD Value of Auto, with Value data of 1, to the following registry keys:
HKEY_LOCAL_MACHINE\Software\WOW6432Node\Microsoft\Windows NT\CurrentVersion\AeDebug
(For 32-bit machines) HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AeDebug
You might see the following error messages during Just-In-Time debugging:
Unable to attach to the crashing process. The specified program is not a Windows or MS-DOS program.
The debugger tried to attach to a process running under another user.
To work around this problem, in Visual Studio, open Debug > Attach to Process (or press Ctrl + Alt + P), and find the process you want to debug in the Available Processes list. If you do not know the name of the process, find the Process ID in the Visual Studio Just-In-Time Debugger dialog. Select the process in the Available Processes list, and select Attach. Select No to dismiss the Just-In-Time debugger dialog.
Debugger could not be started because no user is logged on.
There is no user logged onto the console, so there is no user session to display the Just-In-Time debugging dialog.
To fix this problem, log onto the machine.
Class not registered.
The debugger tried to create a COM class that is not registered, probably due to an installation problem.
To fix this problem, use the Visual Studio Installer to reinstall or repair your Visual Studio installation.
Just in time debugging что это такое
Имеется интересная опция отладки Just-in-Time debugging (назовем ее отладкой здесь-и-теперь). При отладке здесь-и-теперь ваше приложение работает вне интегрированной среды Visual C++, пока не происходит ошибки. При ошибке программы автоматически запускается отладчик Visual C++. Чтобы построить программу с возможностью отладки здесь-и-теперь, нужно сделать следующее:
1. Выберите Options в меню Tools.
2. Выберите закладку Debug.
3. Пометьте флажок Just-in-Time debugging.
5. В меню Build выполните Build <имя проекта>.exe.
Чтобы активировать отладку здесь-и-теперь в Windows NT, программист должен иметь привилегии администратора.
Страница Debug в окне Options
О
тладчик очень гибок в отношении форматирования выводимых данных. В то время как многие опции можно менять «на ходу», иногда предпочтителен единообразный формат вывода. Рис.8показывает страницу Debug окна Орtions для установки таких предопределенных форматов. К странице Debug можно обратиться через меню Tools | Options. Имеющиеся на странице установки описываются в следующих параграфах.
Рис.8 Страница Tools | Options | Debug.
В табл.5 даны комментарии к флагам опций отладчика MS VC++6.0.
Таблица 5. Опции Debug.
При установке этого флажка все выводимые значения представляются, а вводимые пользователем воспринимаются как шестнадцатеричные. Когда флажок помечен, обычные десятичные значения можно вводить с префиксом On, например Оn123456789.
При установке флажка вывод вашего исходного кода сопровождается параллельным переводом на язык ассемблера.
При установке с каждой инструкцией ассемблера ассоциируются байты машинного кода.
Опция выводит в окне Disassembly символические имена адресов.
Опция выводит в окне стека вызовов все значения, переданные в параметрах функций.
Опция выводит в окне стека вызовов информацию о типах переданных функции параметров.
Опция отображает в окне Variables значения, возвращаемые функциями.
Load COFF & Exports
Опция позволяет отладчику при отсутствии отладочной информации загружать COFF-формат или экспортируемые символы DLL.
Окно Address позволяет указать начальный адрес по умолчанию для окна Memory Dump.
Этот список позволяет выбрать формат по умолчанию для типа данных в окне дампа памяти; доступно 13 форматов, таких как ASCII, Byte, Long, Real и Int64.
Эта опция автоматически перемещает содержимое окна Memory Dump. Когда вы вводите в окне Memory Dump имя переменной-указателя, содержимое окна будет обновляться всякий раз, когда адрес в указателе меняется. При выключенной опции содержимое окна дампа меняться не будет, даже если адрес-содержимое переменной изменяется.
Show data bytes
Отображаются сырые байту данных.
Указывает формат фиксированной ширины для окна Memory Dump. Работает совместно со списком Format.
Display Unicode strings
Отображает строки формата Unicode. Это полезно, когда отлаживаемое приложение вводит и выводит тексты в многоязыковых форматах.
View floating point registers
Отображает в окне Registers содержимое регистров плавающей арифметики.
Построенная с такой опцией программа может выполняться вне среды Visual Studio, загружая отладчик Visual C++ только при возникновении ошибки.
OLE RFC debugging
Позволяет отлаживать вызовы удаленных процедур.
Debug commands invoke Edit and Continue
Когда этот флажок установлен, многие, хотя и не все изменения исходного кода могут автоматически вноситься в исполняемый модуль программы при исполнении таких команд, как Go, Step Into, Step Over или Run.
Возможности встроенного отладчика Visual C++
Встроенный отладчик Visual C++ – это мощный и удобный инструмент, оказывающий неоценимую помощь в процессе поиска и устранения ошибок в программе. Прежде чем изучать конкретные техники отладки, необходимо ознакомиться с его возможностями.
Как работает отладчик
В отладке принимают участие два процесса – отладчик (debugger) и отлаживаемый (debuggee). Отладчик имеет полный контроль над отлаживаемым процессом. Он может приостанавливать и возобновлять его потоки, читать или изменять память и регистры процессора и т. д. Кроме того, отладчик получает уведомления обо всех важных событиях, которые происходят в отлаживаемом процессе. К таким событиям относятся запуск или завершение новых процессов и потоков, загрузка и выгрузка DLL, исключения, а также вывод отладочной информации посредством функции OutputDebugString . В случае возникновения одного из этих событий отлаживаемый процесс приостанавливается и ждёт, пока отладчик не выполнит необходимые действия и возобновит его работу. Завершение отладчика приводит к завершению отлаживаемого процесса.
Точки останова
Точки останова (breakpoints) играют важную роль в отладке приложений. На самом деле, точка останова – это некоторое условие (например, достижение определённой команды в программе), при выполнении которого возбуждается исключение EXCEPTION_BREAKPOINT (0x80000003). Как мы уже знаем, исключение приводит к тому, что отлаживаемый процесс приостанавливается, а отладчик получает управление. В частности, он может считать текущие значения регистров процессора и ячеек памяти и выдать их на экран для анализа. После этого он может возобновить выполнение отлаживаемого процесса по команде программиста.
Для реализации точек останова в Visual C++ используется специальная инструкция процессора ( int 3 на процессорах Intel ). Выполнение этой инструкции приводит к исключению EXCEPTION_BREAKPOINT . Установить точку останова можно в любом месте программы. Для этого отладчик записывает по соответствующему адресу инструкцию int 3 (1 байт с кодом 0xCC). Очевидно, что это можно сделать и вручную, вставив в программу инструкцию __asm int 3 . Можно также использовать функцию DebugBreak из Win32 API. Ниже мы увидим, для чего применяется этот приём.
В современных процессорах Intel существуют отладочные регистры (DR0-DR7), которые позволяют установить до 4 аппаратных точек останова. Visual C++ использует эти регистры, но когда их количества оказывается недостаточно, их функциональность эмулируется посредством int 3 .
С помощью точек останова в отладчике Visual C++ реализовано множество полезных возможностей, например, пошаговая отладка (режим, в котором пользователь может выполнять по одной инструкции отлаживаемой программы за раз).
Отладочные символы
Конечно, возможность читать данные из памяти отлаживаемого процесса полезна. Но для программиста на C++ гораздо удобнее просматривать значения переменных, а не безликих ячеек памяти. Пошаговую отладку также гораздо удобнее выполнять по исходному тексту программы, а не по ассемблерному листингу. Чтобы это стало возможным, применяются отладочные символы (debugging symbols). Эти символы генерируются в процессе построения программы. Существуют различные форматы записи символов. По умолчанию Visual C++ записывает их в отдельный файл с расширением PDB, включая в приложение или DLL абсолютный путь к этому файлу.
PDB-файл содержит информацию, которая позволяет определить адрес любой переменной, функции или строки кода. Возможно и обратное преобразование. Кроме того, в PDB-файл включается информация о типах. Благодаря этому отладчик может не только считать из памяти значение переменной, но и выдать это значение на экран в определённом виде (в зависимости от типа переменной). Пошаговая отладка по исходному тексту также становится возможна (при условии, что у вас есть этот исходный текст, так как он не включается в PDB-файл).
Обратите внимание, что отладочные символы хранятся отдельно для каждого модуля (EXE или DLL). Вполне возможна ситуация, когда отладочные символы доступны для DLL, которую загружает приложение, но не для самого приложения. В этом случае код DLL можно будет отлаживать на уровне исходных текстов, а код приложения – на уровне ассемблера.
Настройка отладки
Для настройки отладки используется закладка Debug в окне Project->Settings . На этой закладке можно выбрать две категории: General и Additional DLLs . Первая категория используется для задания общих параметров отладки (рис. 1).
Рисунок 1. Настройка отладки, категория General
Здесь вы можете задать следующие параметры.
В категории Additional DLLs задаются модули, для которых необходимо принудительно загрузить отладочные символы (рис. 2).
Рисунок 2. Настройка отладки, категория Additional DLLs
Зачем это может понадобиться, спросите вы. Дело в том, что сразу после запуска отлаживаемого процесса отладчик пытается установить в нём заданные вами точки останова. Для этого ему требуются отладочные символы модулей, в которых эти точки устанавливаются Символы exe-файла приложения и подключаемых к нему при запуске DLL отладчик загружает сразу. Но символы DLL, которые будут загружены в программу позже (это касается явно загружаемых DLL, внутрипроцессных COM-серверов и т.п.), по умолчанию не загружаются. Это приведёт к сообщению “One or more breakpoints cannot be set and have been disabled”, когда отладчик попытается установить точки останова в этих DLL, а сами точки будут отключены. Для решения этой проблемы и используется категория Additional DLLs . К этому вопросу мы ещё вернёмся, когда будем обсуждать отладку DLL.
Запуск и прекращение отладки
Чтобы вы могли контролировать выполнение программы и наблюдать её состояние, нужно запустить её под управлением отладчика Visual C++. Для этой цели используются команды из меню Build->Start Debug . Первые три из них ( Go , Step Into и Run to Cursor ) запускают тот процесс, который указан в настройках отладки.
Подключение к уже запущенному процессу
Команда Attach to Process из меню Debug открывает одноименный диалог, позволяющий подключить отладчик к любому уже запущенному процессу (рис. 3). Например, если написанная вами программа вдруг «зависла», можно тут же подключиться к ней и выяснить причину ошибки. Вы можете даже подключиться к оболочке Windows ( explorer.exe ), чтобы изучить её работу с помощью отладчика. Правда, в этом случае вам придётся работать с ассемблером, так как Микрософт не поставляет исходные тексты своей оболочки.
Рисунок 3. Окно Attach To Process
Выбрать нужный процесс можно по заголовку его главного окна (колонка Title) или имени его exe-файла (колонка Process), а если этого недостаточно – по уникальному идентификатору процесса (колонка Process Id). Можно отсортировать процессы по любому из этих признаков, щёлкнув по заголовку соответствующего столбца. Обратите внимание на галочку Show System Processes . Если её установить, в список процессов будут включены системные процессы, такие, как сервисы Windows NT.
Just-in-time debugging
В Visual C++ начиная с версии 4.2 появилась возможность отладки «на лету» (Just-in-time debugging). Благодаря этой возможности отладчик можно подключить к программе именно в тот момент, когда она «упала» (например, из-за ошибки доступа). Вот как выглядит окно Application Error в Windows 2000 (рис. 4).
Рисунок 4. Окно Application Error
Если нажать кнопку Cancel, операционная система запустит отладчик, подключит его к сбойному процессу и предоставит вам возможность найти ошибку в момент её возникновения. Кроме этого, в Windows NT/2000 существует ещё один способ подключить отладчик к существующему процессу. Откройте Task Manager , найдите нужный процесс на закладке Processes , подсветите его в списке и выберите из контекстного меню команду Debug .
Just-in-time debugging работает следующим образом. Путь к отладчику запоминается операционной системой в параметре Debugger . В Windows NT/2000 этот параметр хранится в реестре под ключом HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AeDebug , а в Windows 9x – в файле win.ini в секции [AeDebug]. Одновременно на машине может быть только один отладчик, зарегистрированный для Just-in-time debugging. Чтобы прописать туда отладчик Visual C++, откройте окно Tools->Options , перейдите на закладку Debug и установите галочку Just-in-Time Debugging .
Завершение отладки
Сеанс отладки автоматически заканчивается, когда завершается отлаживаемая программа. Кроме этого, отладку можно прекратить в любой момент, вызвав команду Stop Debugging из меню Debug или нажав Shift+F5.
| ПРИМЕЧАНИЕ
Здесь и далее для команд отладчика приводятся клавиатурные сокращения, выбранные в Visual C++ по умолчанию. При желании их можно изменить на любые другие. Точки остановаКак я уже говорил, точки останова играют важную роль в процессе отладки приложения. Visual C++ поддерживает множество разновидностей точек останова. Условием для прерывания программы может быть достижение некоторой команды, изменение глобальной переменной, приход заданного сообщения Windows и т. п. Приостановленную программу можно выполнять в пошаговом режиме, анализировать текущие значения переменных и даже вносить в программу изменения прямо «на лету», не прерывая сеанса отладки.
|


