Выходные функции отладки
DirectShow базовые классы предоставляют несколько макросов для отображения отладочной информации.
| Функция | Описание |
|---|---|
| дбгчеккмодулелевел | Проверяет, включено ли ведение журнала для заданных типов сообщений и уровней. |
| дбгдумпобжектрегистер | Отображает сведения об активных объектах. |
| дбгинитиалисе | Инициализирует библиотеку отладки. |
| дбглог | Отправляет строку в расположение выходных данных отладки, если ведение журнала включено для указанного типа и уровня. |
| дбгаутстринг | Отправляет строку в расположение выходных данных отладки. |
| дбгсетмодулелевел | Задает уровень ведения журнала для одного или нескольких типов сообщений. |
| дбгтерминате | Очищает библиотеку отладки. |
| дисплайтипе | Отправляет сведения о типе мультимедиа в расположение выходных данных отладки. |
| думпграф | Отправляет сведения о графе фильтра в расположение выходных данных отладки. |
| гуиднамес | Глобальный массив, содержащий строки, представляющие идентификаторы GUID, определенные в UUID. h. |
| БЕЗЫМЯН | Создает строку только для отладки. |
| МЕТИМ | Отправляет строку в расположение выходных данных отладки. |
| Вам | Создает напоминание во время компиляции. |
Разделы реестра
функция вывода отладки в DirectShow использовать набор разделов реестра. Расположение этих разделов реестра зависит от версии Windows.
до Windows Vista ключи отладки находятся по следующему пути:
HKey _ _ \ \ Отладка по локального компьютера
в Windows Vista и более поздних версий они находятся по следующему пути:
HKey _ _ \ программное обеспечение локального компьютера — \ \ \ отладка Microsoft DirectShow
для фильтров сторонних производителей расположение зависит от того, какая версия базовых классов DirectShow использовалась для построения фильтра. версия, входящая в Windows SDK для Windows Vista, использует более новый путь. В предыдущих версиях использовался старый путь.
В следующих комментариях метка используется для указания этих двух путей. замените правильный путь в зависимости от версии Windows или версии базовых классов.
Ведение журнала отладки
DirectShow определяет несколько типов сообщений, как показано в следующей таблице.
| Значение | Описание |
|---|---|
| _Ошибка журнала | Уведомление об ошибке. |
| _Блокировка журнала | Блокировка и разблокировка критических разделов. |
| _память журнала | Выделение памяти, создание и уничтожение объектов. |
| время ведения журнала _ | Измерения времени и производительности. |
| _Трассировка журнала | Общая трассировка вызовов. |
| CUSTOM1 через CUSTOM5 | Доступно для настраиваемых сообщений отладки |
каждая из функций ведения журнала отладки DirectShow указывает тип сообщения и уровень ведения журнала. Сообщение отладки отображается только в том случае, если текущий уровень отладки для этого типа сообщений равен уровню, указанному в функции ведения журнала, или больше него. В противном случае сообщение игнорируется.
Например, следующий код выводит строку «это сообщение отладки», если _ уровень трассировки журнала равен 3 или выше:
HKey _ MessageType на локальном _ компьютере \ \ \
где — это тип сообщения минус начальный «журнал _ «, например Блокировка сообщений о _ блокировке журнала. При загрузке модуля библиотека отладки находит в реестре уровни ведения журнала модуля. Если разделы реестра не существуют, Библиотека отладки создаст их.
Кроме того, можно указать глобальные уровни ведения журнала с помощью следующего раздела реестра:
Отладочная библиотека использует уровень выше, глобальный уровень или уровень модуля.
Расположение выходных данных отладки
Расположение выходных данных отладки определяется другим ключом реестра:
HKey _ Локальный _ компьютер \ \ \ логтофиле
Learn OpenGL. Урок 7.1 – Отладка
Графическое программирование — не только источник веселья, но еще и фрустрации, когда что-либо не отображается так, как задумывалось, или вообще на экране ничего нет. Видя, что большая часть того, что мы делаем, связана с манипулированием пикселями, может быть трудно выяснить причину ошибки, когда что-то работает не так, как полагается. Отладка такого вида ошибок сложнее, чем отладка ошибок на CPU. У нас нет консоли, в которую мы могли бы вывести текст, мы не можем поставить точку останова в шейдере и мы не можем просто взять и проверить состояние программы на GPU.
В этом уроке мы познакомимся с некоторыми методами и приемами отладки вашей OpenGL-программы. Отладка в OpenGL не так сложна, и изучение некоторых приемов обязательно окупится.
glGetError()
Эта функция возвращает флаг ошибки или вообще никакую ошибку. Список возвращаемых значений:
| Флаг | Код | Описание |
|---|---|---|
| GL_NO_ERROR | 0 | Никакой ошибки не сгенерировано после последнего вызова glGetError |
| GL_INVALID_ENUM | 1280 | Установлено, когда параметр перечисления недопустим |
| GL_INVALID_VALUE | 1281 | Установлено, когда значение недопустимо |
| GL_INVALID_OPERATION | 1282 | Установлено, когда команда с заданными параметрами недопустима |
| GL_STACK_OVERFLOW | 1283 | Установлено, когда операция проталкивания данных в стек (push) вызывает переполнение стека. |
| GL_STACK_UNDERFLOW | 1284 | Установлено, когда операция выталкивания данных из стека (pop) происходит с наименьшей точки стека. |
| GL_OUT_OF_MEMORY | 1285 | Установлено, когда операция выделения памяти не может выделить достаточное количество памяти |
| GL_INVALID_FRAMEBUFFER_OPERATION | 1286 | Установлено, когда происходит чтение/запись в/из буфер кадра (framebuffer), который не завершен |
Заметьте, что когда OpenGL работает распределенно, как это часто бывает на системах с X11, другие ошибки могут генерироваться, пока у них различные коды. Вызов glGetError тогда просто сбрасывает только один из флагов кодов ошибки вместо всех. Из-за этого и рекомендуют вызывать эту функцию в цикле.
Отличительной особенностью glGetError является то, что она позволяет относительно легко определить, где может быть любая ошибка, и проверить правильность использования OpenGL. Скажем, что у вас ничего не отрисовывается, и вы не знаете, в чем причина: неправильно установленный кадровый буфер? Забыл установить текстуру? Вызывая glGetError везде, вы сможете быстро понять, где возникает первая ошибка.
По умолчанию, glGetError сообщает только номер ошибки, который нелегко понять, пока вы не заучиваете номера кодов. Часто имеет смысл написать небольшую функцию, помогающую напечатать строку с ошибкой вместе с местом, откуда вызывается функция.
glGetError не сильно помогает, поскольку возвращаемая информация относительно проста, но часто помогает отловить опечатки или отловить место возникновения ошибки. Это простой, но эффективный инструмент для отладки.
Отладочный вывод
Инструмент менее известный, но полезнее, чем glCheckError — расширение OpenGL «debug output» (Отладочный вывод), вошедшее в OpenGL 4.3 Core Profile. С этим расширением OpenGL отошлет сообщение об ошибке пользователю с деталями ошибки. Это расширение не только выдает больше информации, но и позволяет отловить ошибки там, где они возникают, используя отладчик.
Чтобы начать использовать отладочный вывод, нам надо у OpenGL запросить отладочный контекст во время инициализационного процесса. Этот процесс отличается на разных оконных системах, но здесь мы обсудим только GLFW, но в конце статьи в разделе «Дополнительные материалы» вы можете найти информацию насчет других оконных систем.
Отладочный вывод в GLFW
Запросить отладочный контекст в GLFW на удивление просто: нужно всего лишь дать подсказку GLFW, что мы хотим контекст с поддержкой отладочного вывода. Нам надо сделать это до вызова glfwCreateWindow :
Как только мы проинициализировали GLFW, у нас должен появиться отладочный контекст, если мы используем OpenGL 4.3 или выше, иначе нам надо попытать удачу и надеяться на то, что система все еще может создать отладочный контекст. В случае неудачи нам надо запросить отладочный вывод через механизм расширений OpenGL.
Отладочный контекст OpenGL бывает медленнее, чем обычный, так что во время работ над оптимизациями или перед релизом следует убрать или закомментировать эту строчку.
Чтобы проверить результат инициализации отладочного контекста, достаточно выполнить следующий код:
Как работает отладочный вывод? Мы передаем callback-функцию обработчик сообщений в OpenGL (похоже на callback’и в GLFW) и в этой функции мы можем обрабатывать данные OpenGL как нам угодно, в нашем случае — отправка полезных сообщений об ошибках на консоль. Прототип этой функции:
Когда расширение определяет ошибку OpenGL, оно вызовет эту функцию и мы сможем печатать огромное количество информации об ошибке. Заметьте, мы проигнорировали некоторые ошибки, так как они бесполезны (к примеру, 131185 в драйверах NVidia говорит о том, что буфер успешно создан).
Теперь, когда у нас есть нужный callback, самое время инициализировать отладочный вывод:
Так мы сообщаем OpenGL, что хотим включить отладочный вывод. Вызов glEnable(GL_DEBUG_SYNCRHONOUS) говорит OpenGL, что мы хотим сообщение об ошибке в тот момент, когда только она произошла.
Фильтрация отладочного вывода
С функцией glDebugMessageControl вы можете выбрать типы ошибок, которые хотите получать. В нашем случае мы получаем все виды ошибок. Если бы мы хотели только ошибки OpenGL API, типа Error и уровня значимости High, мы бы написали следующий код:
С такой конфигурацией и отладочным контекстом каждая неверная команда OpenGL будет отправлять много полезной информации:
Находим источник ошибки через стек вызовов
Еще один трюк с отладочным выводом заключается в том, что вы можете относительно просто установить точное место возникновения ошибки в вашем коде. Устанавливая точку останова в функции DebugOutput на нужном типе ошибки (или в начале функции если вы хотите отловить все ошибки) отладчик отловит ошибку и вы сможете переместиться по стеку вызовов, чтобы узнать, где произошла ошибка:
Это требует некоторого ручного вмешательства, но если вы примерно знаете, что ищете, невероятно полезно быстро определить, какой вызов вызывает ошибку.
Свои ошибки
Наряду с чтением ошибок, мы можем их посылать в систему отладочного вывода с помощью glDebugMessageInsert :
Это очень полезно, если вы подключаетесь к другому приложению или к коду OpenGL, который использует отладочный контекст. Другие разработчики смогут быстро выяснить любую сообщенную ошибку, которая происходит в вашем пользовательском коде OpenGL.
В общем, отладочный вывод (если доступен) очень полезен для быстрого отлова ошибок и определенно стоит потраченных усилий на настройку, так как экономит значительное время разработки. Вы можете найти копию исходного кода здесь с использованием glGetError и отладочного вывода. Есть ошибки, попробуйте их исправить.
Отладочный вывод шейдера
Когда дело доходит до GLSL, у нас нет доступа к функции типа glGetError или возможности пройтись по коду по шагам в отладчике. Когда вы встречаетесь с черным экраном или совершенно неправильным отображением, бывает очень сложно понять, что происходит, если проблема в шейдере. Да, ошибки компиляции сообщают о синтаксических ошибках, но отлов семантических ошибок — та еще песня.
Один из часто используемых приемов для выяснения того, что не так с шейдером, состоит в том, чтобы отправить все соответствующие переменные в шейдерной программе непосредственно в выходной канал фрагментного шейдера. Выводя шейдерные переменные напрямую в выходной канал с цветом мы можем узнать интересную информацию проверяя картинку на выходе. К примеру, нам надо узнать, правильные ли нормали у модели. Мы можем отправить их (трансформированными или нет) из вершинного в фрагментный шейдер, где мы выведем нормали как-то так:
(прим. пер: почему нет подсветки синтаксиса GLSL?)
Выводя нецветовую переменную в выходной канал с цветом как сейчас, мы можем быстро проверить значение переменной. Если, к примеру, результатом стал черный экран, то ясно, что нормали неправильно переданы в шейдеры, а когда они отображаются, сравнительно легко проверить их на правильность:
Из визуальных результатов мы можем видеть, что нормали верны, так как правая сторона костюма преимущественно красная (что говорит, что нормали примерно показывают в направлении полощительной оси x) и также передняя сторона костюма окрашена в направлении положительной оси z (в синий цвет).
Этот подход можно расширить на любую переменную, которую вы хотите протестировать. Каждый раз, когда вы застряли и предполагаете, что ошибка в шейдерах, попробуйте отрисовывать несколько переменных или промежуточных результатов и выяснить, в какой части алгоритма есть ошибка.
OpenGL GLSL reference compiler
В каждом видеодрайвере свои причуды. К примеру, драйвера NVIDIA немного смягчают требования спецификации, а драйвера AMD лучше соответствую спецификациям (что лучше, как мне кажется). Проблема в том, что шейдеры работающие на одной машине, могут не заработать на другой из-за отличий в драйверах.
За несколько лет опыта вы могли выучить все отличия между различными GPU, но если вы хотите быть уверены в том, что ваши шейдеры будут работать везде, то вы можете сверить ваш код с официальной спецификацией с помощью GLSL reference compiler. Вы можете скачать так называемый GLSL lang validator тут (исходник).
С этой программой вы можете проверить свои шейдеры, передавая их как 1-й аргумент к программе. Помните, что программа определяет тип шейдера по расширению:
Запустить программу легко:
Заметьте, что если нет ошибок, то программа ничего не выведет. На сломанном вершинном шейдере вывод будет похож на:
Программа не покажет различий между компиляторами GLSL от AMD, NVidia или Intel, и даже не может сообщить обо всех багах в шейдере, но он хотя бы проверяет шейдеры на соответствие стандартам.
Вывод буфера кадра
Еще один метод для вашего инструментария — отобразить содержимое кадрового буфера в определенной части экрана. Скорее всего, вы часто используете кадровые буферы и, поскольку вся магия происходит за кадром, бывает трудно определить, что происходит. Вывод содержимого кадрового буфера — полезный прием, чтобы проверить правильность вещей.
Заметьте, что содержимое кадрового буфера, как тут объясняется, работает с текстурами, а не с объектами буферов отрисовки
Используя простой шейдер, который отрисовывает одну текстуру, мы можем написать небольшую функцию, быстро отрисовывающую любую текстуру в правом верхнем углу экрана:
Это даст вам небольшое окошко в углу экрана для отладочного вывода кадрового буфера. Полезно, к примеру, когда пытаешься проверить корректность нормалей:
Вы также можете расширить эту функцию так, чтобы она отрисовывала больше 1 текстуры. Это быстрый путь получить непрерывную отдачу от чего угодно в кадровых буферах.
Внешние программы-отладчики
Когда ничего не помогает, есть еще один прием: воспользоваться сторонними программами. Они встраиваются в драйвера OpenGL и могут перехватывать все вызовы OpenGL, чтобы дать вам очень много интересных данных о вашем приложении. Эти приложения могут профилировать использование функций OpenGL, искать узкие места, наблюдать за кадровыми буферами, текстурами и памятью. Во время работы над (большим) кодом, эти инструменты могут стать бесценными.
Я перечислил несколько популярных инструментов. Попробуйте каждый и выберите тот, который лучше всего вам подходит.
RenderDoc
RenderDoc — хороший (полностью опенсорсный) отдельный отладочный инструмент. Чтобы начать захват, выберите исполняемый файл и рабочую папку (working directory). Ваше приложение работает как обычно, и когда вы хотите понаблюдать за отдельным кадром, вы позволяете RenderDoc снять несколько кадров вашего приложения. Среди захваченных кадров вы можете просмотреть состояние конвейера, все команды OpenGL, хранилище буферов и используемые текстуры.
CodeXL
CodeXL — инструмент отладки GPU, работает как отдельное приложение и плагин к Visual Studio. CodeXL Дает много информации и отлично подходит для профилирования графических приложений. CodeXL также работает на видеокартах от NVidia и Intel, но без поддержки отладки OpenCL.
Я не так много использовал CodeXL, поскольку RenderDoc мне показался проще, но я включил CodeXL в этот список, потому что он выглядит довольно надежным инструментом и в основном разработан одним из крупных производителей графических процессоров.
NVIDIA Nsight
Nsight — популярный инструмент отладки GPU от NUIDIA. Является не только плагином к Visual Studio и Eclipse, но еще и отдельное приложение. Плагин Nsight — очень полезная вещь для графических разработчиков, поскольку собирает много статистик в реальном времени относительно использования GPU и покадрового состояния GPU.
В тот момент, когда вы запускаете свое приложение через Visual Studio или Eclipse с помощью команд отладки или профилирования Nsight, он запустится сам внутри приложения. Хорошая вещь в Nsight: рендер ГИП-системы (GUI, графический интерфейс пользователя) поверх запускаемого приложения, которую можно использовать для собирания информации всех видов о вашем приложении в реальном времени или покадровом анализе.
Nsight — очень полезный инструмент, который, по моему мнению, превосходит вышеперечисленные инструменты, но имеет один серьезный недостаток: работает только на видеокартах от NVIDIA. Если вы работаете на видеокартах от NVIDIA и используете Visual Studio — определенно стоит попробовать Nsight.
Я уверен, что есть еще инструменты для отладки графических приложений (к примеру, VOGL и APItrace), но я считаю, что этот список уже предоставил вам достаточно инструментов для экспериментов. Я не эксперт в вышеупомянутых инструментах, так что если есть ошибки, то пишите мне (переводчику) в личные сообщения и в комментарии к оригинальной статье (если конечно же, там еще осталась эта ошибка).
Debug
Запуск Debug.exe, программы для проверки и отладки исполнительных файлов MS-DOS. Выполненная без параметров команда debug запускает программу Debug.exe и выводит приглашение команды debug,
представленное дефисом (-).
Синтаксис
Параметры
Примечания
Команда debug это команда подсистемы MS-DOS, которая выполняется в среде WOW/NTVDM.
Параметры можно вводить через запятые или пробелы, но это требуется только для шестнадцатеричных значений. Например, следующие команды эквивалентны:
Существует несколько команд debug, которыми можно воспользоваться.
Debug: a (assemble)
Создание двоичного кода процессоров 8086/8087/8088 непосредственно в памяти. Выполненная без параметров команда a начинает работу с точки последнего останова.
Синтаксис
Параметры
Примечания
Адрес состоит из двух частей: первая содержит буквенное обозначение сегментного регистра или адрес сегмента из четырех цифр, а вторая содержит значение смещения. Адрес сегмента или сегментный регистр можно пропустить. По умолчанию для команд debug a, g, l, t, u и w адрес сегмента содержится в регистре CS. Для других подкоманд по умолчанию используется сегмент DS. Все числовые значения при этом представлены в шестнадцатеричном формате. Между именем сегмента и значением смещения следует вставлять двоеточие. Примеры правильных адресов:
Задайте мнемонику префикса инструкции перед кодом операции (т. е. opcode), к которой она относится. Команда a создает исполняемый машинный код из инструкций на языке ассемблера. Все числовые значения должны быть представлены в шестнадцатеричном формате и записаны как набор от 1 до 4 символов.
Мнемоники cs:, ds:, es: и ss:. Мнемоникой, вызывающей возврат управления в другой сегмент кода (far return), является retf. Мнемоники для работы со строками должны точно определять размер элементов строк. Например, для перемещения строк из слов (16 бит) следует использовать movsw, а для перемещения строк из байтов (8 бит) следует использовать movsb.
Ассемблер автоматически обрабатывает переходы и вызовы (т. е. префиксы short, near или far ) в зависимости от смещения байтов. Имеется возможность переопределить переходы или вызовы с помощью префиксов near или far. Например:
-a0100:0500
0100:0500 jmp 502 ; короткий (short) переход на 2 байта
0100:0502 jmp near 505 ; ближний (near) переход на 3 байта
0100:0505 jmp far 50a ; длинный (far) переход на 5 байтов
Вместо префикса near можно использовать сокращение ne.
Если операнды ссылаются на адреса слов или байтов в памяти, тип данных должен быть задан с использованием префикса word ptr или byte ptr, которые можно сократить до wo для word ptr и до by для byte ptr. Например:
dec wo [si]
neg byte ptr [128]
В программе Debug.exe используется общее соглашение о том, что операнды, указывающие на адрес в памяти, заключаются в квадратные скобки ([ ]). Это единственный способ, который позволяет различать непосредственные операнды и ссылки на области в памяти в Debug.exe. Например:
mov ax,21 ; загрузить число 21h в регистр AX
mov ax,[21] ; загрузить содержимое
; памяти по адресу 21h
; в регистр AX
С командой a часто используются две псевдоинструкции: операция db, которая размещает байты непосредственно в памяти, и операция dw, которая размещает в памяти слова. Например:
db 1,2,3,4,»ЭТО ПРИМЕР»
db ‘ЭТО КАВЫЧКА: «‘
db «ЭТО КАВЫЧКА: ‘»
dw 1000,2000,3000,»BACH»
Примеры
Команда a допускает различное использование ссылок на регистры. Например:
add bx,34[bp+2].[si-1]
pop [bp+di]
push [si] )
Кроме того, команда a поддерживает использование синонимов дополнительных кодов операций: Например:
loopz 100
loope 100
ja 200
jnbe 200
Для дополнительных кодов операций процессора 8087 необходимо задать префиксы wait или fwait. Например:
fwait fadd st,st(3) ; эта строка вставляет
; в код префикса fwait
Debug: c (compare)
Сравнение двух блоков памяти.
Синтаксис
Параметры
Примечания
Параметр диапазон используется в командах debug для задания диапазона памяти. Для задания диапазона можно использовать один из следующих форматов: начальный и конечный адрес или начальный адрес и длина (разделяются символом l) диапазона. Например, обе следующих команды задают 16-разрядный диапазон, начинающийся с адреса CS:100:
Адрес состоит из двух частей: первая содержит буквенное обозначение сегментного регистра или адрес сегмента из четырех цифр, а вторая содержит значение смещения. Адрес сегмента или сегментный регистр могут быть пропущены. По умолчанию для команд debug a, g, l, t, u и w адрес сегмента содержится в регистре CS. Для других подкоманд по умолчанию используется сегмент DS. Все числовые значения при этом представлены в шестнадцатеричном формате. Между именем сегмента и значением смещения следует вставлять двоеточие. Следующие адреса являются допустимыми:
адрес1 байт1 байт2 адрес2
Примеры
Чтобы сравнить блок памяти от 100h до 10Fh с блоком памяти от 300h до 30Fh, введите следующую команду:
Обе эти команды выведут следующие данные (предполагается, что DS = 197F):
197F:0100 4D E4 197F:0300
197F:0101 67 99 197F:0301
197F:0102 A3 27 197F:0302
197F:0103 35 F3 197F:0303
197F:0104 97 BD 197F:0304
197F:0105 04 35 197F:0305
197F:0107 76 71 197F:0307
197F:0108 E6 11 197F:0308
197F:0109 19 2C 197F:0309
197F:010A 80 0A 197F:030A
197F:010B 36 7F 197F:030B
197F:010C BE 22 197F:030C
197F:010D 83 93 197F:030D
197F:010E 49 77 197F:030E
197F:010F 4F 8A 197F:030F
Адреса 197F:0106 и 197F:0306 отсутствуют в списке. Это означает, что значения, расположенные по этим адресам, совпадают.
Debug: d (dump)
Просмотр содержимого заданного диапазона адресов памяти. Выполненная без параметров команда d выводит на экран содержимое 128 байт, начиная с конца диапазона адресов, заданного в предыдущей команде d.
Синтаксис
Параметры
Примечания
Параметр диапазон используется в подкомандах debug для задания диапазона памяти. Параметр диапазон можно задать в одном из следующих форматов: начальный адрес и конечный адрес или начальный адрес и длина (обозначаемая l) диапазона. Например, оба следующих выражения задают диапазон из 16 байтов, начинающийся с адреса CS:100:
Примеры
Введите следующую команду:
Команда debug.exe выводит содержимое диапазона в следующем формате:
04BA:0100 54 4F 4D 00 53 41 57 59-45 52 00 00 00 00 00 00.
Команда Debug.exe выводит сведения в таком формате, если подкоманда d выполнена без параметров. Каждая строка на экране начинается с адреса, который отстоит от адреса предыдущей строки на 16 байт (или на 8 байт для экрана с 40 колонками). Для каждой последующей подкоманды d, вводимой без параметров, Debug.exe выводит следующую часть сведений непосредственно за предыдущей.
Чтобы вывести содержимое 20h байт, начиная с CS:100, введите следующую команду:
Чтобы вывести содержимое всех байт в диапазоне от 100h до 115h в сегменте CS, введите следующую команду:
Debug: e (enter)
Ввод данных в память по заданному адресу.
Синтаксис
Параметры
Примечания
Адрес состоит из двух частей: первая содержит буквенное обозначение сегментного регистра или адрес сегмента из четырех цифр, а вторая содержит значение смещения. Адрес сегмента или сегментный регистр могут быть пропущены. По умолчанию для подкоманд a, g, l, t, u и w команды debug адрес сегмента содержится в регистре CS. Для других подкоманд по умолчанию используется сегмент DS. Все числовые значения при этом представлены в шестнадцатеричном формате. Между именем сегмента и значением смещения следует вставлять двоеточие. Следующие адреса являются допустимыми:
При задании параметра адрес без указания параметра список Debug.exe выведет на экран адрес и его содержимое, затем повторит адрес на следующей строке и будет ждать ввода новой команды. В этот момент можно выполнить одно из следующих действий.
Если введен параметр список, подкоманда e последовательно заменяет существующие значения значениями из списка. При возникновении ошибки никакие значения не будут изменены.
Список может быть задан как шестнадцатеричными числами, так и строкой. При этом числа разделяются пробелами, запятыми или символами табуляции. Строки необходимо заключать в апострофы (т. е. ‘строка‘) или кавычки (т. е. «строка«).
Примеры
Введите следующую команду:
Debug.exe выведет содержимое первого байта в следующем формате:
Чтобы заменить это значение числом 41, введите 41 в позицию курсора, как показано ниже:
Последовательность байтов можно ввести в одной подкоманде e. Вместо нажатия клавиши Enter после нового значения, нажмите клавишу ПРОБЕЛ. Программа Debug.exe выведет следующее значение. В данном примере, если клавиша ПРОБЕЛ нажата три раза, Debug.exe выведет на экран следующие значения:
04BA:0100 EB.41 10. 00. BC._
Чтобы заменить шестнадцатеричное значение BC числом 42, введите 42 в позицию курсора, как показано ниже:
04BA:0100 EB.41 10. 00. BC.42_
Чтобы изменить значение 10 на 6F, дважды нажмите клавишу МИНУС для возврата к адресу 0101 (значение 10). Программа Debug.exe выводит следующие сведения:
04BA:0100 EB.41 10. 00. BC.42-
04BA:0102 00.-
04BA:0101 10._
Введите 6F в позицию курсора для изменения значения, как показано ниже:
Нажмите клавишу ENTER для завершения выполнения подкоманды e и возврата к приглашению программы debug.
Рассмотрим пример ввода строковой величины:
eds:100 «Это пример текста»
Эта строка будет занимать 24 байта, начиная с адреса DS:100.
Debug: f (fill)
Заполнение адресов в определенной области памяти заданными значениями.
Синтаксис
Параметры
Примечания
Параметр диапазон используется в подкомандах debug для задания диапазона памяти. Параметр диапазон можно задать в одном из следующих форматов: начальный адрес и конечный адрес или начальный адрес и длина (обозначаемая l) диапазона. Например, оба следующих выражения задают диапазон из 16 байтов, начинающийся с адреса CS:100:
Данные можно задать в шестнадцатеричном или текстовом формате. Данные, ранее находившиеся по данному адресу, будут удалены.
Список может состоять из шестнадцатеричных чисел или строки, заключенной в кавычки (т. е. «строка«).
Примеры
Чтобы заполнить область памяти с 04BA:100 по 04BA:1FF пятью определенными значениями (например 42, 45, 52, 54, 41) и повторять этот набор, пока 100h байт не будут заполнены программой Debug.exe, введите следующую команду:
f04ba:100l100 42 45 52 54 41
Debug: g (go)
Выполнение загруженной программы. Запущенная без параметров подкоманда g начинает выполнение с текущего адреса в реестрах CS:IP.
Синтаксис
Параметры
Примечания
Адрес состоит из двух частей: первая содержит буквенное обозначение сегментного регистра или адрес сегмента из четырех цифр, а вторая содержит значение смещения. Адрес сегмента или сегментный регистр могут быть пропущены. По умолчанию для подкоманд a, g, l, t, u и w команды debug адрес сегмента содержится в регистре CS. Для других подкоманд по умолчанию используется сегмент DS. Все числовые значения при этом представлены в шестнадцатеричном формате. Между именем сегмента и значением смещения следует вставлять двоеточие. Следующие адреса являются допустимыми:
Введите знак равенства (=) перед параметром адрес, чтобы отличить адрес от адресов точек останова (точки_останова).
Выполнение программы будет остановлено в первой встретившейся точке останова, независимо от расположения этой точки останова в списке параметра точки_останова. Debug.exe заменяет код, находящийся в точках останова, на инструкции прерывания.
Когда выполнение программы дошло до точки останова, Debug.exe восстанавливает код в точках останова и выводит на экран содержимое всех регистров, все флаги состояния и деассемблированную инструкцию, которая была выполнена последней. Debug.exe выводит те же сведения, которые получают при использовании полкоманды r (регистр) и указании адреса данной точки останова.
Если программа не остановлена ни в одной точке, Debug.exe не заменяет коды прерываний первоначальными инструкциями.
Точки останова могут быть установлены только по адресам, содержащим первый байт кода операции 8086 (opcode). Если установлено больше 10 точек останова, выводится следующее сообщение:
Указатель на стек, задаваемый пользователем, должен быть допустимым, а емкость стека должна быть не менее 6 байт для подкоманды g. Для перехода к тестируемой программе в подкоманде g используется инструкция iret. Debug.exe устанавливает указатель на стек пользователя, помещает туда пользовательские флаги состояния, значение регистра кодового сегмента и указатель на текущую команду. (Если заданный пользователем стек неверен или имеет недостаточный объем, возможен сбой в операционной системе). Debug.exe записывает код прерывания (т. е. 0CCh) в указанные точки останова или адреса.
Не перезапускайте программу при получении следующего сообщения:
Program terminated normally
Чтобы правильно запустить программу, перезагрузите ее с помощью подкоманд n (name) и l (load).
Примеры
Чтобы запустить текущую программу и выполнить ее до точки останова по адресу 7550 в сегменте CS, введите следующую команду.
Debug.exe выведет на экран содержимое регистров и состояние флагов, а затем остановит подкоманду g.
Чтобы установить две точки останова, введите следующую команду:
Если подкоманда g введена снова после остановки в точке останова, выполнение начнется с инструкции, следующей за точкой останова, а не с обычного адреса начала программы.
Debug: h (hexadecimal)
Выполнение шестнадцатеричных арифметических операций над двумя заданными числами.
Синтаксис
Параметры
Заметки
Примеры
Введите следующую команду:
Результаты вычислений Debug.exe будут выведены в виде:
Debug: i (input)
Считывание и вывод на экран одного байта из указанного порта ввода.
Синтаксис
Параметры
Примеры
Введите следующую команду:
Если находящаяся в порту величина равна 42h, Debug.exe считает ее и выведет в следующем виде:
Debug: l (load)
Загрузка файла или содержимого сектора диска в память. Выполненная без параметров подкоманда l загружает файл, указанный в командной строке программы debug, в память, начиная с адреса CS:100. В регистрах BX и CX указывается количество загруженных байт. Если имя файла не было задано в командной строке debug, используется файл, ранее заданный при вызове последней подкоманды n.
Синтаксис
Параметры
Заметки
Адрес состоит из двух частей: первая содержит буквенное обозначение сегментного регистра или адрес сегмента из четырех цифр, а вторая содержит значение смещения. Адрес сегмента или сегментный регистр могут быть пропущены. По умолчанию для подкоманд a, g, l, t, u и w команды debug адрес сегмента содержится в регистре CS. Для других подкоманд по умолчанию используется сегмент DS. All numeric values are in hexadecimal format. Между именем сегмента и значением смещения следует вставлять двоеточие. Следующие адреса являются допустимыми:
При вызове подкоманды l с указанием параметра адрес Debug.exe загрузит файл или содержимое сектора диска в область памяти, начиная с адреса.
При вызове подкоманды l со всеми параметрами Debug.exe загружает содержимое сектора диска, а не файла.
Каждый сектор в указанном диапазоне считывается с диска, заданного параметром диск. Debug.exe начинает загрузку с первого_сектора и последовательно загружает сектора в память, пока не будет загружено заданное число секторов.
Примеры
В командной строке введите:
Введите следующую команду:
Чтобы загрузить файл File.com, введите следующую команду:
Debug.exe загружает этот файл и выводит приглашение debug.
Чтобы загрузить содержимое 109 (6Dh) секторов диска C, начиная с логического сектора 15 (0Fh), в область памяти, начиная с адреса 04BA:0100, введите следующую команду:
Debug: m (move)
Копирование содержимого одного блока памяти в другой.
Синтаксис
Параметры
Примечания
Параметр диапазон используется в подкомандах debug для задания диапазона памяти. Параметр диапазон можно задать в одном из следующих форматов: начальный адрес и конечный адрес или начальный адрес и длина (обозначаемая l) диапазона. Например, оба следующих выражения задают диапазон из 16 байтов, начинающийся с адреса CS:100:
Адрес состоит из двух частей: первая содержит буквенное обозначение сегментного регистра или адрес сегмента из четырех цифр, а вторая содержит значение смещения. Адрес сегмента или сегментный регистр могут быть пропущены. По умолчанию для подкоманд a, g, l, t, u и w команды debug адрес сегмента содержится в регистре CS. Для других подкоманд по умолчанию используется сегмент DS. Все числовые значения при этом представлены в шестнадцатеричном формате. Между именем сегмента и значением смещения следует вставлять двоеточие. Следующие адреса являются допустимыми:
Если адреса в копируемом блоке памяти заданы так, что в этот блок не записываются новые данные, то информация в этом блоке не изменяется. Если же операция копирования является перекрывающей, перекрывающиеся данные перезаписываются. (Операция копирования является перекрывающей, если два блока памяти имеют общую часть).
Подкоманда m выполняет перекрывающее копирование без потери данных в области назначения. Содержимое адресов, которые будут перезаписаны, копируется в первую очередь. Если данные копируются из старших адресов в младшие адреса, операция копирования начинается с младшего адреса исходного блока и продолжается в направлении старшего адреса. И наоборот, если данные копируются из младших адресов в старшие, копирование начинается со старших адресов исходного блока и продолжается в направлении младшего адреса.
Примеры
Чтобы скопировать содержимое адресов с CS:110 по CS:510, а затем с CS:10F по CS:50F и так далее, пока все содержимое адресов с CS:100 по CS:500 не будет скопировано, введите следующую команду:
Чтобы просмотреть результаты, воспользуйтесь подкомандой d (dump), указав адреса, заданные в подкоманде m.
Debug: n (name)
Задание имени исполняемого файла для команд debug l (load) или w (write) или задание параметров для отлаживаемого исполняемого файла. Выполненная без параметров подкоманда n очищает текущие значения.
Синтаксис
Параметры
Примечания
Подкоманду n можно использовать двумя способами. Во-первых, для задания имени файла для последующих подкоманд l (load) или w (write). Если программа Debug.exe вызвана без задания имени файла для отладки, команда n имя_файла должна быть вызвана перед использованием команды l для загрузки файла. Имя файла форматируется соответствующим образом для контрольного блока файла (FCB) по адресу CS:5C. Во-вторых, подкоманда n может использоваться для задания параметров и ключей командной строки отлаживаемого файла.
В следующей таблице перечислены четыре области памяти, которые используются командой n.
| Область памяти | Contents |
|---|---|
| CS:5C | Блок управления файлом (FCB) для файла 1 |
| CS:6C | Блок управления файлом (FCB) для файла 2 |
| CS:80 | Длина строки команды n (в символах) |
| CS:81 | Начало строки команды n |
Первое имя файла, задаваемое командой n, размещается в блоке управления файлом по адресу CS:5C. Если задано второе имя, оно помещается в блок управления файлом по адресу CS:6C. Количество символов в командной строке команды n (кроме первого символа, n) сохраняется по адресу CS:80. Собственно командная строка n (снова без символа n) сохраняется, начиная с адреса CS:81. Эти символы могут быть любыми параметрами и разделителями, которые допустимо вводить с командной строки в Windows 2000.
Примеры
В этом примере запускается команда debug и загружается программа Prog.com для отладки. Чтобы указать два параметра для программы Prog.com и запустить эту программу, введите следующую команду:
debug prog.com
nparam1 param2
g
В этом случае подкоманда g (go) запускает программу так, как если бы она была запущена с командной строки в виде:
prog param1 param2
При тестировании и отладке создается среда времени исполнения для программы Prog.com.
В следующей последовательности команд первая подкоманда n задает имя файла File1.exe для последующей подкоманды l (load), которая загружает файл File1.exe в память. Вторая подкоманда n задает параметры для файла File1.exe. Наконец, подкоманда g запускает File1.exe так, как если бы с командной строки было бы введено File1 File2.dat File2.dat.
nfile1.exe
l
nfile2.dat file3.dat
g
После команды l во втором экземпляре команда n не используется. Если подкоманда w (write) используется во втором экземпляре подкоманды n, файл File1.exe (т. е. отлаживаемый) сохраняется под именем File2.dat. Чтобы этого не произошло, всегда вызывайте команду l или w сразу же после команды n в первой форме.
Debug: o (output)
Вывод байта в порт вывода.
Синтаксис
Параметры
Примеры
Чтобы отправить байт 4Fh в порт вывода по адресу 2F8h, введите следующую команду:
Debug: p (proceed)
Выполнение цикла, строковой инструкции, программного прерывания или процедур, а также вход в другую инструкцию. Выполненная без параметров команда p выводит список реестров и их текущих значений.
Синтаксис
Параметры
Примечания
Адрес состоит из двух частей: первая содержит буквенное обозначение сегментного регистра или адрес сегмента из четырех цифр, а вторая содержит значение смещения. Адрес сегмента или сегментный регистр могут быть пропущены. По умолчанию для подкоманд a, g, l, t, u и w команды debug адрес сегмента содержится в регистре CS. Для других подкоманд по умолчанию используется сегмент DS. Все числовые значения при этом представлены в шестнадцатеричном формате. Между именем сегмента и значением смещения следует вставлять двоеточие. Следующие адреса являются допустимыми:
Если в параметре адрес не указан сегмент, Debug.exe использует регистр CS тестируемой программы. Если параметр адрес опущен, выполнение программы начинается с адреса, указываемого регистрами CS:IP. Чтобы отличить параметр адрес от параметра число, перед адресом обязательно должен быть введен знак равенства (=). В случае если инструкция по заданному адресу не является циклом, строковой инструкцией, программным прерыванием или процедурой, подкоманда p работает также, как подкоманда t (trace).
Если в программе Debug.exe управление передано тестируемой программе с помощью команды p, выполнение продолжается до тех пор, пока цикл, строковая инструкция, программное прерывание или процедура не будут закончены или пока не будет выполнено заданное количество инструкций. Затем управление возвращается к Debug.exe.
После запуска подкоманды p Debug.exe выводит на экран содержимое регистров, флаги состояния и следующую инструкцию в деассемблированном виде.
Примеры
В этом примере тестируемая программа содержит инструкцию call по адресу CS:143F. Чтобы выполнить процедуру, указанную в call, и возвратиться в программу Debug.exe, введите следующую команду:
Результаты программы Debug.exe будут выведены в следующем формате:
AX=0000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=2246 ES=2246 SS=2246 CS=2246 IP=1443 NV UP EI PL NZ AC PO NC
2246:1442 7505 JNZ 144A
Debug: q (quit)
Окончание работы программы Debug.exe без сохранения тестируемого файла и возврат в командную строку.
Синтаксис
Параметры
Debug: r (register)
Редактирование содержимого одного или нескольких регистров ЦПУ. Выполненная без параметров команда r выводит содержимое всех регистров и флагов из временного хранилище регистра, состояния всех флагов и декодированную инструкцию в текущей области.
Синтаксис
Параметры
Примечания
Если задан регистр, Debug.exe выводит на экран его 16-разрядное значение в шестнадцатеричном формате и двоеточие в качестве приглашения. Если требуется изменить значение содержащееся в регистре, введите новое значение и нажмите клавишу ENTER. В противном случае нажмите клавишу ENTER для возврата к приглашению программы debug.
В следующей таблице перечислены допустимые регистры x86 для параметра регистр.
| Значение |
|---|
| ax |
| bp |
| bx |
| cs |
| cx |
| di |
| ds |
| dx |
| es |
| f |
| ip |
| pc |
| si |
| sp |
| ss |
Если задан недопустимый регистр, выводится следующее сообщение:
Если указать f вместо регистра, Debug.exe выводит на экран текущее значение каждого флага состояния в виде двухбуквенного кода и приглашение debug. Для изменения значения флага введите соответствующий двухбуквенный код, воспользовавшись следующей таблицей.
| Флаг | Установлен | Снят |
|---|---|---|
| Переполнение | ov | nv |
| Направление | dn (уменьшение) | up (увеличение) |
| Прерывание | ei (включено) | di (выключено) |
| Знак | ng (отрицательный) | pl (положительный) |
| Ноль | zr | nz |
| Добавочный перенос | ac | na |
| Четность | pe (четный) | po (нечетный) |
| Перенос | cy | nc |
Новые значения флагов могут быть введены в любой последовательности. Между этими значениями не нужно вводить пробел. Чтобы завершить выполнение подкоманды r, нажмите клавишу ENTER. Флаги, новые значения для которых не вводились, останутся неизмененными.
При задании более одного значения для флага выводится следующее сообщение:
При вводе кода, не содержащегося в таблице, выводится следующее сообщение:
В обоих случаях Debug.exe пропустит все значения, следующие после неверного ввода.
Когда запускается программа Debug.exe, сегментный регистр указывает на нижнюю границу свободной памяти, указатель инструкций устанавливается равным 0100h, все флаги состояния очищаются, оставшиеся регистры обнуляются, за исключением sp, который устанавливается равным FFEEh.
Примеры
Если текущее положение указателя инструкций равно CS:11A, выводятся следующие сведения:
AX=0E00 BX=00FF CX=0007 DX=01FF SP=039D BP=0000 SI=005C DI=0000
DS=04BA ES=04BA SS=04BA CS=O4BA IP=011A NV UP DI NG NZ AC PE NC
04BA:011A CD21 INT 21
Чтобы просмотреть только состояния флагов, введите следующую команду:
Результаты программы Debug.exe выводятся в следующем формате:
Введите одно и несколько допустимых значений флагов с пробелами или без них. Например:
Debug.exe завершит выполнение подкоманды r и выведет приглашение debug. Для просмотра изменений воспользуйтесь командой r или rf. Программа Debug.exe выводит следующие сведения:
Нажмите клавишу ENTER для возврата к приглашению программы debug.
Debug: t (trace)
Выполнение одной инструкции с выводом содержимого регистров, флагов состояния и декодированной формы выполняемой инструкции. При запуске подкоманды t без параметров выполнение начинается с адреса, указанного в регистрах CS:IP программы.
Синтаксис
Параметры
Примечания
Адрес состоит из двух частей: первая содержит буквенное обозначение сегментного регистра или адрес сегмента из четырех цифр, а вторая содержит значение смещения. Адрес сегмента или сегментный регистр могут быть пропущены. По умолчанию для подкоманд a, g, l, t, u и w команды debug адрес сегмента содержится в регистре CS. Для других подкоманд по умолчанию используется сегмент DS. Все числовые значения при этом представлены в шестнадцатеричном формате. Между именем сегмента и значением смещения следует вставлять двоеточие. Следующие адреса являются допустимыми:
Подкоманда t использует аппаратный режим трассировки микропроцессоров 8086 и 8088. Следовательно, также можно трассировать инструкции, хранимые в ПЗУ.
Примеры
Если текущая позиция указателя кода является 04BA:011A, Debug.exe выведет следующие сведения:
AX=0E00 BX=00FF CX=0007 DX=01FF SP=039D BP=0000 SI=005C DI=0000
DS=04BA ES=04BA SS=04BA CS=O4BA IP=011A NV UP DI NG NZ AC PE NC
04BA:011A CD21 INT 21
Debug: u (unassemble)
Деассемблирование байтов и просмотр соответствующего исходного кода, включая адреса и двоичные значения. Деассемблированный код выводится в формате, похожем на распечатку ассемблерного файла. Выполненная без параметров подкоманда u деассемблирует 20h байт (значение по умолчанию), начиная с первого адреса после адреса, использованного в предыдущей подкоманде u.
Синтаксис
Параметры
Примечания
Параметр диапазон используется в подкомандах debug для задания диапазона памяти. Параметр диапазон можно задать в одном из следующих форматов: начальный адрес и конечный адрес или начальный адрес и длина (обозначаемая l) диапазона. Например, оба следующих выражения задают диапазон из 16 байтов, начинающийся с адреса CS:100:
Примеры
Чтобы деассемблировать 16 (10h) байт, начиная с адреса 04BA:0100, введите следующую команду:
Результаты программы Debug.exe выводятся в следующем формате:
04BA:0100 206472 AND [SI+72],AH
04BA:0103 69 DB 69
04BA:0104 7665 JBE 016B
04BA:0106 207370 AND [BP+DI+70],DH
04BA:0109 65 DB 65
04BA:010A 63 DB 63
04BA:010B 69 DB 69
04BA:010C 66 DB 66
04BA:010D 69 DB 69
04BA:010E 63 DB 63
04BA:010F 61 DB 61
Чтобы просмотреть сведения только об адресах с 04BA:0100 по 04BA:0108, введите следующую команду:
Программа Debug.exe выводит следующие сведения:
04BA:0100 206472 AND [SI+72],AH
04BA:0103 69 DB 69
04BA:0104 7665 JBE 016B
04BA:0106 207370 AND [BP+DI+70],DH
Debug: w (write)
Запись файла или определенных секторов на диск. При запуске подкоманды w без параметров запись начинается с адреса CS:100.
Синтаксис
Параметры
Примечания
Адрес состоит из двух частей: первая содержит буквенное обозначение сегментного регистра или адрес сегмента из четырех цифр, а вторая содержит значение смещения. Адрес сегмента или сегментный регистр могут быть пропущены. По умолчанию для подкоманд a, g, l, t, u и w команды debug адрес сегмента содержится в регистре CS. Для других подкоманд по умолчанию используется сегмент DS. Все числовые значения при этом представлены в шестнадцатеричном формате. Между именем сегмента и значением смещения следует вставлять двоеточие. Следующие адреса являются допустимыми:
Если используются подкоманды g (go), t (trace), p (proceed) или r (register), перед использованием команды w без параметров значения регистров BX:CX необходимо сбросить.
Если файл был изменен, но имя, размер и начальный адрес не менялись, Debug.exe позволяет записать файл в его исходное расположение на диске.
Примеры
Чтобы записать содержимое области памяти, начиная с адреса CS:100, на диск B и собрать данные из 2Bh секторов, начиная с логического сектора диска под номером 37h, введите следующую команду:
После окончания операции записи выводится приглашение программы debug.
Debug: xa (allocate expanded memory)
Выделение заданного количества страниц памяти EMS. Выполненная без параметров подкоманда xa проверяет наличие или отсутствие поддержки дополнительной памяти (EMS).
Синтаксис
Параметры
Примечания
Примеры
Чтобы выделить восемь страниц дополнительной памяти, введите следующую команду:
Если команда успешно выделит память, выводятся следующие сведения:
Debug: xd (deallocate expanded memory)
Освобождение дескриптора памяти EMS. Выполненная без параметров подкоманда xd проверяет наличие или отсутствие поддержки дополнительной памяти (EMS).
Синтаксис
Параметры
Примечания
Примеры
Чтобы освободить дескриптор 0003, введите следующую команду:
При успешном выполнении программы Debug.exe будет выведено сообщение:
Дескриптор 0003 освобожден
Debug: xm (мар expanded memory pages)
Отображение логической страницы памяти EMS, соответствующей заданному дескриптору, в физическую страницу памяти EMS. Выполненная без параметров подкоманда xm проверяет наличие или отсутствие поддержки памяти EMS.
Синтаксис
xm [лог_страница] [физ_страница] [ дескриптор]
Параметры
Примечания
Примеры
Чтобы отобразить логическую страницу 5 дескриптора 0003 в физическую страницу 2, введите следующую команду:
При успешном выполнении программы Debug.exe будет выведено сообщение:
Логическая страница 05 отображена на физическую страницу 02
Debug: xs (display expanded memory status)
Вывод сведений о состоянии памяти EMS.
Синтаксис
Параметры
Примечания
Для дескриптора xx выделено xx страниц
Физическая страница xx = Сегмент EMS xx
Выделено xx из xx страниц EMS
Выделено xx из xx дескрипторов EMS
Примеры
Чтобы вывести сведения о состоянии памяти EMS, введите следующую команду:
Подкоманда xs выводит сведения в следующем виде:
Для вопросов, обсуждений, замечаний, предложений и т. п. можете использовать раздел форума этого сайта (требуется регистрация).
Новый раздел о средствах командной строки в рамках этого же проекта расположен здесь



