[Содержание]   [Назад]   [Пред]   [Вверх]   [След]   [Вперед]  


7. Исследование данных

DDD предоставляет несколько средств для исследования данных.

  • Самый быстрый способ исследования переменных -- навести указатель мыши на появление переменной в исходном тексте. Значение показывается исходной строке: спустя секунду появляется всплывающее окно (называемое подсказкой для значения) со значением переменной. Это полезно для быстрого просмотра нескольких простых значений.
  • Если вы хотите иметь возможность позже ссылаться на значения переменных, вы можете напечатать значение в консоли отладчика. Это позволяет отображать и исследовать большие структуры данных.
  • Если вы хотите исследовать сложные структуры данных, вы можете графически отобразить их в окне данных. Отображения остаются до тех пор, пока вы их не удалите; они обновляются при каждом останове программы. Отображения полезны для больших, динамических структур.
  • Если вы хотите исследовать массивы численных значений, вы можете построить график в отдельном окне. График обновляется при каждом останове программы. Это бывает полезно для больших численных массивов.
  • При использовании GDB или DBX вы также можете исследовать содержимое памяти в нескольких форматах, независимо от типов данных вашей программы.

7.1 Просмотр простых значений с помощью подсказок

Чтобы увидеть значение простой переменной, поместите указатель мыши над ее именем. Спустя секунду всплывет маленькое окно (называемое подсказкой для значения), показывающее значение этой переменной. Окно исчезает, как только вы уберете указатель с имени переменной. Значение также показывается в строке состояния.

PICS/ddd-value-tip

Подсказки для значений можно выключить через `Edit => Preferences => General => Automatic display of variable values as popup tips'.

Показ значений в строке состояния выключается через `Edit => Preferences => General => Automatic display of variable values in the status line'.

Эти настройки привязаны к следующим ресурсам:

Ресурс: valueTips (класс Tips)
Включены ли подсказки для значений (`on', по умолчанию) или выключены (`off'). Подсказки для значений влияют на производительность DDD и могут раздражать некоторых опытных пользователей.

Ресурс: valueDocs (класс Docs)
Следует ли отображать значения переменных в строке состояния (`on', по умолчанию) или нет (`off').

7.2 Печать простых значений в консоли отладчика

Значение переменной можно также напечатать в консоли отладчика, что делает его доступным для будущих операций. Чтобы напечатать значение какой-то переменной, выберите ее, щелкнув первой кнопкой мыши на ее имени. Имя переменной будет скопировано в поле аргумента. Если теперь щелкнуть на кнопке `Print', значение напечатается в консоли отладчика. Кроме того, значение показывается в строке состояния.

Есть более быстрый вариант: вы можете просто нажать на имени переменной третью кнопку мыши и выбрать из всплывающего меню пункт `Print'.

PICS/ddd-print-popup

При использовании GDB кнопка `Print' генерирует команду print, у которой есть еще несколько параметров. См. раздел `Examining Data' в Debugging with GDB, о специфичных для GDB выражениях, переменных и выходных форматах.

7.3 Отображение сложных значений в окне данных

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

7.3.1 Основы отображения

В этом разделе рассказывается как создавать и удалять отображения и манипулировать ими. Базовые операции:

  • Чтобы отобразить переменную из `()', щелкните на `Display'.
  • Чтобы выделить отображение, щелкните на нем.
  • Чтобы удалить выделенное отображение, щелкните на `Undisplay'.

7.3.1.1 Создание единичных отображений

Чтобы создать новое отображение, показывающее некую переменную, выберите эту переменную, щелкнув на ее имени первой кнопкой мыши. Имя переменной будет скопировано в поле аргумента. Если теперь щелкнуть на кнопке `Display', в окне данных появится новое отображение. Окно данных открывается автоматически, как только вы создаете отображение.

PICS/ddd-display

Есть более короткий способ: вы можете просто нажать на имени переменной третью кнопку мыши и выбрать из всплывающего меню пункт `Display'.

В качестве еще более быстрого способа, можно также дважды щелкнуть на имени переменной.

Еще один способ: можно ввести выражение, которое нужно отобразить, в поле аргумента и нажать кнопку `Display'.

И наконец: вы также можете набрать команду в подсказке отладчика:

graph display выражение [clustered] [at (x, y)] 
    [dependent on отображение] [[now or] when in область]

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

clustered
Если задано, новое отображение создается в группе. См. раздел 7.3.1.8 Группировка отображений, обсуждение этой темы.
at (x, y)
Если это задано, новое отображение создается в позиции (x, y). Иначе используется принимаемая по умолчанию.
dependent on отображение
Если это задано, создается связка от отображения с указанным номером или именем. В противном случае связка не создается. См. раздел 7.3.4.1 Отображение зависимых значений, для получения дополнительной информации.
when in область
now or when in область
Если задано `when in', создание отображения откладывается до тех пор, пока выполнение не достигнет указанной области (это имя функции, как в выводе следа вызовов). Если задано `now or when in', DDD сначала пытается создать отображение сразу. Отображение откладывается, только если его создание неуспешно. Если не задан суффикс `when in' или `now or when in', отображение создается сразу.

7.3.1.2 Выбор отображения

У каждого отображения в окне данных есть заголовок, содержащий его номер и отображаемое выражение (имя отображения). Под заголовком показывается значение отображения.

Вы можете выделить отображение, щелкнув на нем первой кнопкой мыши.

Можно расширить существующее выделение, нажав во время выбора клавишу Shift. Также можно переключить существующее выделение, удерживая клавишу Shift при выборе уже выделенных отображений.

Отдельные отображения можно также выделять, используя курсорные стрелки Up, Down, Left и Right.

Для выделения нескольких отображений нажмите и удерживайте первую кнопку мыши где-нибудь на заднем плане окна. При перемещении указателя показывается прямоугольник выделения; все отображения внутри этого прямоугольника будут выделены, когда вы отпустите кнопку мыши.

Если в процессе выделения нажата клавиша Shift, существующее выделение расширяется.

Двойной щелчок на заголовке отображения автоматически выделяет это отображение и все соединенные с ним.

PICS/ddd-select-display

7.3.1.3 Показ и скрывание подробностей

Составные значения (например, записи, структуры, классы и массивы) могут отображаться в развернутом виде, то есть со всеми подробностями, или скрыто, в виде `{...}'.

Чтобы увидеть подробности составной величины, выберите эту величину, щелкнув на ее имени или значении первой кнопкой мыши и нажмите кнопку `Show'. Подробности показываются как для самой составной величины, так и для содержащихся в ней подструктур.

Чтобы скрыть подробности составной величины, выберите эту величину, щелкнув на ее имени или значении первой кнопкой мыши и нажмите кнопку `Hide'.

PICS/ddd-hide-display

При нажатии и удержании первой кнопки мыши на кнопке `Show/Hide' всплывает меню с другими альтернативами:

Show More ()
Показать подробности всех составных величин, которые в данный момент скрыты, но не для содержащихся в них подструктур. Вы можете выбирать этот пункт несколько раз, чтобы выводить все больше и больше деталей выделенной составной величины.
Show Just ()
Показать подробности выделенной составной величины, но скрыть все подструктуры.
Show All ()
Показать все подробности выделенной составной величины и ее подструктур. Этот пункт эквивалентен кнопке `Show'.
Hide ()
Скрыть все подробности выделенной составной величины. Этот пункт эквивалентен кнопке `Hide'.

Есть более быстрый способ: вы можете также нажать на составной величине третью кнопку мыши и выбрать нужный пункт меню.

Еще более быстрый вариант: можно дважды щелкнуть на значении первой кнопкой мыши. Если какая-то часть значения скрыта, будет показано больше подробностей; если видимо все значение целиком, двойной щелчок скрывает значение. Таким способом вы можете дважды щелкать на значении до тех пор, пока не получите нужную степень подробности.

Если скрыты все подробности отображения, то такое отображение называется выключенным; на это указывает строка `(Disabled)'.

Отображения также можно включать и выключать с помощью команды DDD, вводимой в подсказке отладчика:

graph disable display отображения...

выключает заданные отображения.

graph enable display отображения...

включает заданные отображения.

В этих командах отображения... -- это либо разделенный пробелами список номеров отображений, либо имя одного отображения. Если вы задаете отображение по имени, затрагиваются все отображения с этим именем.

Для отмены включения или выключения отображений используйте `Edit => Undo'.

7.3.1.4 Поворот отображений

Массивы, структуры и списки могут быть ориентированы горизонтально или вертикально. Чтобы изменить ориентацию отображения, выделите его, а затем щелкните на кнопке `Rotate'.

Есть более быстрый способ: вы можете нажать на массиве третью кнопку мыши и выбрать из всплывающего меню пункт `Rotate'.

PICS/ddd-rotate-display

Если структура или список ориентированы горизонтально, DDD автоматически не показывает имена членов. Это может быть удобно для экономии места.

Последняя выбранная ориентация используется при создании новых отображений. Если в последний раз вы повернули массив горизонтально, следующий массив будет также ориентирован горизонтально. Эти установки сохраняются через `Edit => Save Options'; они связаны с такими ресурсами:

Ресурс: arrayOrientation (класс Orientation)
Ориентация массивов. Возможны значения `XmVERTICAL' (по умолчанию) и `XmHORIZONTAL'.

Ресурс: showMemberNames (класс ShowMemberNames)
Показывать имена членов структур или не показывать. По умолчанию `on'.

Ресурс: structOrientation (класс Orientation)
Ориентация структур. Возможны значения `XmVERTICAL' (по умолчанию) и `XmHORIZONTAL'.

7.3.1.5 Отображение локальных переменных

Вы можете отобразить все локальных переменные сразу, выбрав `Data => Display Local Variables'. При использовании DBX, XDB, JDB или Perl это отобразит все локальные переменные, включая аргументы текущей функции. При использовании GDB или PYDB аргументы содержатся в отдельном отображении, которое активизируется через `Data => Display Arguments'.

Отображением, показывающим локальные переменные, можно манипулировать точно так же, как любым другим. Отдельные переменные можно выделять и получать их значения.

PICS/ddd-locals

7.3.1.6 Отображение состояния программы

Вы можете создать отображение из вывода произвольной команды отладчика. Если ввести

graph display `команда`

вывод команды превращается в отображение состояния, которое обновляется при каждом останове программы.

К примеру, команда

graph display `where`

создает отображение состояния с именем `Where', которое показывает текущий след вызовов.

Если вы используете GDB, DDD предоставляет панель, где вы можете выбрать полезные отображения состояния. Нажмите `Data => Status Displays' и подберите нужное отображение из списка.

PICS/ddd-status-displays

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

7.3.1.7 Обновление окна данных

Окно данных автоматически обновляется при каждом останове программы. Значения, которые изменились с последнего обновления, подсвечиваются.

Однако, могут быть ситуации, когда вам нужно обновить окно данных вручную. Чаще всего такое случается, когда вы изменили установки отладчика, которые могут повлиять на формат данных, и хотите, чтобы в окне данных отразились эти установки.

Вы можете обновить окно данных, выбрав `Data => Refresh Displays'.

В качестве альтернативы, вы можете нажать третью кнопку мыши на фоне окна данных и выбрать пункт `Refresh Displays'.

Ввод

graph refresh

в подсказке отладчика приводит к тому же результату.

7.3.1.8 Группировка отображений

Если вы исследуете несколько переменных одновременно, выделение для каждой из них отдельного отображения займет много места на экране. Поэтому DDD поддерживает группы. Группа объединяет несколько логических отображений данных в одно физическое отображение, сберегая экранное место.

Есть два способа создания групп:

  • Вы можете создавать группы вручную. Для этого нужно выделить группируемые отображения и выбрать `Undisp => Cluster ()'. Для всех выделенных отображений создается группа. Если выделена существующая группа, выделенные отображения будут сгруппированы в нее.
  • Вы можете создавать группы автоматически для всех независимых отображений данных, так что все новые отображения будут автоматически сгруппированы. Это делается через `Edit => Preferences => Data => Cluster Data Displays'.

PICS/ddd-clusters

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

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

  • Можно разгруппировать отображения вручную, выделив группу и нажав `Undisp => Uncluster ()'.
  • Можно разгруппировать все текущие и будущие отображения, сняв установку `Edit => Preferences => Data => Cluster Data Displays'.

7.3.1.9 Создание нескольких отображений

Чтобы отобразить несколько последовательных объектов одного типа (часть массива или массив динамической длины), вы можете использовать в выражениях для отображения запись `от..до'.

от и до -- это числа, которые обозначают первое и последнее выражение из тех, что следует отобразить. Таким образом,

graph display argv[0..9]

создает 10 новых отображений для `argv[0]', `argv[1]', ..., `argv[9]'. Эти отображения автоматически группируются (см. раздел 7.3.1.8 Группировка отображений), так что вы можете легко обращаться с этим набором, как с массивом.

Запись `от..до' можно также применять несколько раз. Например,

graph display 1..5 * 1..5

создает удобную маленькую таблицу умножения.

Запись `от..до' создает несколько отображений; для их создания и обновления затрачивается некоторое время. Если вы хотите отобразить только часть массива, более эффективным будет использование фрагментов массива. См. раздел 7.3.2.1 Фрагменты массива, обсуждение этой темы.

7.3.1.10 Редактирование всех отображений

Вы можете просмотреть состояние всех отображений, выбрав `Data => Displays'. Это вызывает редактор отображений.

PICS/ddd-edit-displays

Редактор отображений показывает свойства каждого отображения с такими полями:

`Num'
Номер отображения.
`Expression'
Отображаемое выражение.
`State'
Одно из
`enabled'
Нормальное состояние.
`disabled'
Выключено; все подробности скрыты. Для включения используйте `Show'.
`not active'
Вне области видимости.
`deferred'
Будет создано при достижении области видимости (см. раздел 7.3.1.1 Создание единичных отображений).
`clustered'
Часть группы (см. раздел 7.3.1.8 Группировка отображений). Для разгруппировки используйте `Undisp => Uncluster'.
`alias of отображение'
Скрытый псевдоним для отображения (см. раздел 7.3.4.3 Разделяемые структуры).
`Scope'
Область видимости, в которой было создано данное отображение. Для отложенных отображений это область, в которой оно будет создано.
`Address'
Адрес отображаемого выражения. Используется для раскрытия псевдонимов (см. раздел 7.3.4.3 Разделяемые структуры).

7.3.1.11 Удаление отображений

Чтобы удалить одно отображение, выделите его и нажмите кнопку `Undisp'. Или вы можете нажать на этом отображении третью кнопку мыши и выбрать пункт меню `Undisplay'.

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

Чтобы удалить несколько отображений за один раз, используйте кнопку `Undisp' в редакторе отображений (вызывается через `Data => Displays'). Выберите любое число отображений и удалите их, нажав `Undisp'.

Или вы можете применить такую команду DDD:

graph undisplay отображения...

В данном случае, отображения... -- это либо разделенный пробелами список номеров отображений, либо имя одного отображения. Если вы задаете отображение по имени, затрагиваются все отображения с этим именем.

Если вы используете объединенные окна, то при удалении последнего отображения из окна данных это окно автоматически закрывается. (Вы можете изменить это через `Edit => Preferences => Data => Close data window when deleting last display'.)

Если вы удалили отображение по ошибке, используйте `Edit => Undo', чтобы снова создать его.

Наконец, вы можете также вырезать, копировать и вставлять отображения с помощью пунктов `Cut', `Copy' и `Paste' из меню `Edit'. Буфер обмена хранит команды, используемые для создания отображений; `Paste' вставляет команду в консоль отладчика. Это позволяет вам сохранять отображения для будущего использования или копировать их между разными экземплярами DDD.

7.3.1.12 Настройка отображений

Вы можете использовать следующие ресурсы для управления внешним видом отображений:

Ресурс: autoCloseDataWindow (класс AutoClose)
Если это `on' (по умолчанию), а DDD работает в режиме с объединенными окнами, то при удалении последнего отображения окно данных автоматически закрывается. Если это `off', окно данных остается даже после удаления последнего отображения.

Ресурс: bumpDisplays (класс BumpDisplays)
Если некоторое отображение d изменяет размер, и этот ресурс установлен в значение `on' (по умолчанию), DDD присваивает новые положения отображениям, находящимся ниже и правее d, так что расстояние между отображениями остается неизменным. Если это `off', другие отображения не передвигаются.

Ресурс: clusterDisplays (класс ClusterDisplays)
Если это `on', новые независимые отображения автоматически группируются. По умолчанию `off', то есть новые отображения не группируются.

Ресурс: hideInactiveDisplays (класс HideInactiveDisplays)
Если какое-то отображение выходит из области видимости, и значение этого ресурса равно `on' (по умолчанию), DDD удаляет его. Если это `off', отображение просто становится выключенным.

Ресурс: showBaseDisplayTitles (класс ShowDisplayTitles)
Следует ли придавать базовым (независимым) отображениям заголовки или нет. По умолчанию `on'.

Ресурс: showDependentDisplayTitles (класс ShowDisplayTitles)
Следует ли придавать зависимым отображениям заголовки или нет. По умолчанию `off'.

7.3.2 Отображение массивов

В DDD есть специальные средства для обращения с массивами.

7.3.2.1 Фрагменты массива

Часто бывает нужно напечатать несколько последовательных объектов одного типа; фрагмент (секцию) массива или массив динамически определяемой длины, для которого в программе существует только указатель.

В DDD вы можете отображать фрагменты с помощью записи `от..до' (см. раздел 7.3.1.9 Создание нескольких отображений). Но это подразумевает, что вы заранее знаете значения от и до; кроме того, создавать несколько одиночных отображений неэффективно. Если вы используете GDB, у вас есть другой способ.

При использовании GDB вы можете отображать последовательные объекты, ссылаясь на непрерывную область памяти как на искусственный массив с помощью бинарного оператора `@'. Левая часть `@' должна быть первым элементом желаемого массива и самостоятельным объектом. Правая часть -- это желаемая длина массива. Результатом является значение-массив, чьи элементы принадлежат типу первого аргумента. Первый элемент -- это на самом деле левый аргумент оператора; второй элемент состоит из байт памяти, непосредственно следующих после первого, и так далее.

Вот пример. Если в программе сказано

int *array = (int *) malloc (len * sizeof (int));

вы можете напечатать содержимое array с помощью

print array[0]@len

и отобразить его, введя команду

graph display array[0]@len

Таким образом, общий вид отображения фрагмента массива такой:

graph display массив[первый]@число-элементов

где массив -- это имя отображаемого массива, первый -- это индекс первого элемента, а число-элементов -- это число отображаемых элементов.

Левый операнд `@' должен находиться в памяти. Значения-массивы, созданные таким методом при помощи оператора `@', ведут себя в отношении индексирования так же, как любые другие массивы, а при использовании в выражениях приводятся к типу указателей.

7.3.2.2 Повторяющиеся значения

При использовании GDB значение массива, которое повторяется 10 и более раз, отображается только один раз. Это значение показывается с добавленным постфиксом `<nx>', где n -- это число повторений. Таким образом, отображение `0x0 <30x>' обозначает массив из 30 элементов, каждый из которых равен `0x0'. Это значительно экономит экранное место, особенно в случае с однообразными массивами.

PICS/ddd-repeats

По умолчанию порог для повторяющихся элементов массива равен 10. Вы можете изменить эго через `Edit => GDB Settings => Threshold for repeated print elements'. Если установить порог в значение 0, GDB (и DDD) будут отображать все элементы массива по отдельности. После изменения установок GDB не забывайте обновить окно данных с помощью `Data => Refresh Displays'.

Вы также можете настроить DDD для раздельного отображения элементов массивов:

Ресурс: expandRepeatedValues (класс ExpandRepeatedValues)
GDB может печатать повторяющиеся элементы массива в форме `значение <repeated n times>'. Если `expandRepeatedValues' равен `on', DDD будет вместо этого отображать n экземпляров значения. Если `expandRepeatedValues' равен `off' (по умолчанию), DDD отображает значение, добавляя к нему `<nx>' для обозначения повторения.

7.3.2.3 Массивы в виде таблиц

По умолчанию DDD располагает двумерные массивы в виде таблиц, так чтобы все элементы массива были выровнены относительно друг друга.(27) Чтобы выключить это средство, снимите установку `Edit => Preferences => Data => Display Two-Dimensional Arrays as Tables'. Она связана с таким ресурсом:

Ресурс: align2dArrays (класс Align2dArrays)
Если `on' (по умолчанию), DDD размещает двумерные массивы в виде таблиц, так чтобы все элементы массива были выровнены относительно друг друга. Если `off', DDD понимает двумерный массив как массив одномерных массивов, и выравнивает их по-отдельности.

7.3.3 Присваивание переменных

Во время работы программы вы можете изменять значения любых переменных.(28)

Чтобы изменить значение переменной, введите ее имя в `()' --- например, выбрав отображение или появление переменной в исходном тексте программы. Затем щелкните на кнопке `Set'. В появившемся диалоговом окне вы можете отредактировать значение переменной; щелчок на кнопке `OK' или `Apply' применяет ваше изменение и присваивает переменной новое значение.

PICS/ddd-set

Чтобы изменить отображаемое значение, вы также можете выбрать пункт `Set Value' из всплывающего меню.

Если вы сделали ошибку, можно применить `Edit => Undo' и снова присвоить переменной старое значение.

7.3.4 Исследование структур

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

7.3.4.1 Отображение зависимых значений

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

Чтобы создать зависимое отображение, выделите начальное отображение или его часть и введите в поле аргумента `():' зависимое выражение. Затем щелкните на кнопке `Display'.

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

По умолчанию DDD не распознает разделяемые структуры данных (то есть объект, на который ссылаются несколько других объектов). См. раздел 7.3.4.3 Разделяемые структуры, для получения подробной информации о том, как исследовать такие структуры.

7.3.4.2 Получение значения по указателю

Есть специальные средства для создания зависимых отображений, показывающих значение, на которое ссылается указатель. Это позволяет быстро исследовать структуры данных, основанные на указателях.

Чтобы получить значение по указателю, выделите значение или имя начального указателя и щелкните на кнопке `Disp *'. Появится новое отображение, показывающее значение по этому указателю.

Более быстрый способ: вы можете нажать на значении или имени начального указателя третью кнопку мыши и выбрать пункт меню `Display *'.

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

Функция `Display *()' также доступна по нажатию и удержанию кнопки `Display'.

7.3.4.3 Разделяемые структуры

По умолчанию DDD не распознает разделяемые структуры данных -- то есть объект, на который ссылаются несколько других объектов. Например, если два указателя `p1' и `p2' ссылаются на один и тот же объект `d', отображения `d', `*p1' и `*p2' будут различными, хотя они и обозначают один и тот же объект.

DDD предоставляет специальный режим, в котором такие ситуации детектируются. DDD замечает, когда два или более отображения расположены по одному физическому адресу, и если это так, объединяет все эти псевдонимы в одно отображение, оригинальное отображение данных. Этот режим называется режимом детектирования псевдонимов; включается через `Data => Detect Aliases'.

Когда включено детектирование псевдонимов, DDD проверяет адреса всех отображений после каждого шага программы. Если два отображения имеют одинаковый адрес, они объединяются в одно. Точнее, остается только одно, которое не изменялось дольше (это оригинальное отображение данных); все остальные псевдонимы подавляются, то есть полностью скрываются. Ведущие к псевдонимам связки заменяются на связки, ведущие к оригинальному отображению.

При детектировании псевдонимов создаются особенные связки: вместо того, чтобы непосредственно соединять два отображения, они проходят через подсказку, которая описывает данную дугу.

В каждой подсказке связки есть место для скрытого псевдонима; выделение подсказки эквивалентно выделению этого псевдонима. Таким образом, вы можете легко удалять отображения-псевдонимы, просто выделяя подсказку и нажимая `Undisp'.

PICS/ddd-aliases

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

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

Пожалуйста, обратите внимание на следующие возможные проблемы, связанные с детектированием псевдонимов:

  • Для детектирования псевдонимов необходимо, чтобы текущий язык программирования предоставлял средства для определения адреса произвольного объекта. На данный момент поддерживаются только Си, Си++ и Java.
  • Некоторые подчиненные отладчики (например, SunOS DBX) выдают некорректный вывод для адресных выражений. Если есть указатель p, вы можете проверить правильность работы вашего подчиненного отладчика сравнив значения p и `&p' (если только p не ссылается на самом деле сам на себя). Также можно посмотреть, какие адреса показывают для отображений данных в редакторе отображений.
  • Детектирование псевдонимов слегка замедляет работу DDD, поэтому по умолчанию оно выключено. Возможно, его стоит включать только при необходимости -- к примеру, когда вы исследуете какую-то сложную структуру данных -- и выключать во время исследования передачи управления (то есть при пошаговом проходе программы). При переключении режимов DDD автоматически восстановит отображения и связки.

Детектирование псевдонимов управляется следующими ресурсами:

Ресурс: deleteAliasDisplays (класс DeleteAliasDisplays)
Если это `on' (по умолчанию), кнопка `Undisplay ()' удаляет все псевдонимы выделенных отображений. Если это `off', удаляются только сами выделенные отображения; псевдонимы остаются, и один из них становится видимым.

Ресурс: detectAliases (класс DetectAliases)
Если `on', DDD пытается распознавать разделяемые структуры данных. По умолчанию `off', что означает, что разделяемые структуры не распознаются.

Ресурс: typedAliases (класс TypedAliases)
Если `on' (по умолчанию), для распознавания разделяемых структур DDD требует структурной эквивалентности. Если это `off', два отображения с одинаковым адресом считаются псевдонимами друг друга, независимо от их структуры.

7.3.4.4 Быстрое создание отображений

В DDD есть быстрое меню часто используемых выражений для работы с отображениями. Это меню активизируется нажатием и удержанием кнопки `Display', или нажатием на некотором отображении третьей кнопки мыши и выбором `New Display', или щелчком на отображении третьей кнопки мыши при нажатой клавише Shift.

Пункт быстрого меню `Other' позволяет создавать новое отображение, которое расширяет быстрое меню.

В качестве примера предположим, что вы выделили отображение с именем `date_ptr'. Если выбрать `Display => Other', появится диалоговое окно, позволяющее ввести новое отображаемое выражение -- к примеру, вы можете преобразовать отображение `date_ptr' в новое отображение `(char *)date_ptr'. Если был активизирован переключатель `Include in `New Display' Menu', быстрое меню теперь будет включать новый пункт `Display (char *)()', который преобразует любое выделенное отображение отображение в `(char *)отображение'. Такие быстрые операции могут сэкономить много времени при исследовании сложных структур данных.

PICS/ddd-shortcuts

Вы можете отредактировать содержимое меню `New Display', выбрав его пункт `Edit Menu'. Появится редактор быстрых операций, содержащий все быстрые выражения, которые вы можете отредактировать по своему усмотрению. Каждая строка содержит выражение для ровно одного пункта меню. Если щелкнуть на `Apply', в соответствии с этим текстом будет заново создано меню `New Display'. Если текст пуст, меню `New Display' тоже будет пустым.

PICS/ddd-shortcut-editor

DDD также позволяет задавать отдельные метки для определенных пользователем кнопок. Вы можете записать такую метку после выражения, отделив ее знаками `//'. Эта возможность используется по умолчанию в меню `New Display' для GDB, где у каждого преобразования есть своя метка:

/t ()   // Convert to Bin
/d ()   // Convert to Dec
/x ()   // Convert to Hex
/o ()   // Convert to Oct

Если хотите, можете добавить свои преобразования. DDD поддерживает до двадцати пунктов в меню `New Display'.

Быстрое меню контролируется следующими ресурсами:

Ресурс: dbxDisplayShortcuts (класс DisplayShortcuts)
Разделяемый переводами строки список выражений для создания отображений, включаемых в меню `New Display' для DBX.

Если строка содержит разделитель метки(29), то строка до разделителя используется в качестве выражения, а строка после разделителя --- в качестве метки. Иначе, меткой будет `Display выражение'. При вызове строка `()' в выражении заменяется на имя текущего выделенного отображения.

Ресурс: gdbDisplayShortcuts (класс DisplayShortcuts)
Разделяемый переводами строки список выражений для создания отображений, включаемых в меню `New Display' для GDB. Смотрите описание ресурса `dbxDisplayShortcuts' выше.

Ресурс: jdbDisplayShortcuts (класс DisplayShortcuts)
Разделяемый переводами строки список выражений для создания отображений, включаемых в меню `New Display' для JDB. Смотрите описание ресурса `dbxDisplayShortcuts' выше.

Ресурс: perlDisplayShortcuts (класс DisplayShortcuts)
Разделяемый переводами строки список выражений для создания отображений, включаемых в меню `New Display' для Perl. Смотрите описание ресурса `dbxDisplayShortcuts' выше.

Ресурс: pydbDisplayShortcuts (класс DisplayShortcuts)
Разделяемый переводами строки список выражений для создания отображений, включаемых в меню `New Display' для PYDB. Смотрите описание ресурса `dbxDisplayShortcuts' выше.

Ресурс: xdbDisplayShortcuts (класс DisplayShortcuts)
Разделяемый переводами строки список выражений для создания отображений, включаемых в меню `New Display' для XDB. Смотрите описание ресурса `dbxDisplayShortcuts' выше.

7.3.5 Компоновка графа

Если у вас одновременно есть несколько отображений, вы можете организовать их по своему вкусу. В этом разделе рассказывается как это сделать.

7.3.5.1 Перемещение отображений

Время от времени бывает нужно переместить отображение на другое место в окне данных. Вы можете переместить одно отображение, нажимая и удерживая на его заголовке первую кнопку мыши. Перемещая указатель при удержании кнопки, вы перемещаете все выделенные отображения.

Подсказки связок можно выделять и перемещать точно так же, как отображения. Если дуга проходит через подсказку связки, вы можете изменить форму этой дуги, передвигая подсказку.

Для точного перемещения выделенных отображений можно также воспользоваться курсорными стрелками. При нажатой клавише Shift курсорные стрелки перемещают по одному пикселю, а при нажатом Ctrl --- по узлам сетки.

7.3.5.2 Прокрутка окна данных

Если окно данных становится слишком маленьким, и все отображения в нем не умещаются, создаются полоски прокрутки. Если DDD у вас настроен на использование панели прокрутки, то в нижнем правом углу создается панель прокрутки. Когда вы перемещаете панель прокрутки, соответственно перемещается видимая часть окна.

Чтобы перейти от полосок прокрутки к панели прокрутки, используйте `Edit => Startup => Data Scrolling' и выберите либо `Panner', либо `Scrollbars'.

Эта установка привязана к следующему ресурсу:

Ресурс: pannedGraphEditor (класс PannedGraphEditor)
Управляющий элемент, применяемый для прокрутки графа.
  • Если это `on', используется панель прокрутки Athena (вроде двумерной полоски прокрутки).
  • Если это `off' (по умолчанию), используются две полоски прокрутки Motif.

См. раздел 2.1.2 Ключи DDD, о ключах --scrolled-graph-editor и --panned-graph-editor.

7.3.5.3 Выравнивание отображений

Вы можете выровнять все отображения по ближайшим узлам сетки, выбрав `Data => Align on Grid'. Это бывает полезно, если вы хотите, чтобы все связки были строго горизонтальны или вертикальны.

Если установить `Edit => Preferences => Data => Auto-align Displays on Nearest Grid Point', отображения выравниваются автоматически. Когда эта установка включена, отображения можно перемещать только по сетке.

7.3.5.4 Автоматическая компоновка

Вы можете скомпоновать весь граф как дерево, выбрав `Data => Layout Graph'.

PICS/ddd-layout

Компоновка графа может создать подсказки связок; то есть связки становятся не прямыми линиями, а ведут к подсказке, а от нее уже к месту назначения. Подсказки отображений можно перемещать так же, как любые отображения.

Чтобы включить более компактную компоновку, можно установить `Edit => Preferences => Data => Compact Layout'. Эта установка реализует альтернативный алгоритм компоновки, где потомки помещаются рядом со своими предками. Этот алгоритм подходит только для гомогенных структур.

Вы можете включить принудительную компоновку, выставив `Edit => Preferences => Data => Automatic Layout'. Если задействована автоматическая компоновка, граф компонуется после каждого изменения.

7.3.5.5 Поворот графа

Вы можете повернуть весь граф на 90 градусов по часовой стрелке, выбрав `Data => Rotate Graph'.

Если граф ранее был скомпонован, может понадобиться перекомпоновать его. Последующие компоновки будут учитывать направление последнего поворота.

7.3.6 Печать графа

DDD позволяет распечатывать граф на PostScript-принтерах или в файлы. Это полезно для документирования состояний программы.

PICS/ddd-print-graph

Чтобы напечатать граф на PostScript-принтере, выберите `File => Print Graph'. Введите в поле `Print Command' команду печати. Чтобы начать печать, нажмите кнопку `OK' или `Apply'.

Еще можно распечатать граф в файл. Щелкните на кнопке `File' и введите в поле `File Name' имя файла. Чтобы создать файл, щелкните на кнопке `Print'.

Когда граф печатается в файл, возможны два формата:

  • `PostScript' -- подходит для включения графа в другой документ;
  • `FIG' -- подходит для последующей обработки с помощью графического редактора xfig или для преобразования в другие форматы (в том числе в @acronym{IBMGL}, TeX, @acronym{PIC}) с помощью программ transfig или fig2dev.

PICS/ddd-print-output

Пожалуйста, обратите внимание на следующие возможные проблемы, связанные с печатью графов:

  • Если во время вызова диалога `Print' были выделены какие-либо отображения, устанавливается параметр `Selected Only'. Тогда DDD печатает только эти выделенные отображения.
  • Параметры `Color', `Orientation' и `Paper Size' имеют смысл только для PostScript.

Эти установки связаны с такими ресурсами:

Ресурс: printCommand (класс PrintCommand)
Команда для печати PostScript-файла. Обычно это `lp' или `lpr'.

Ресурс: paperSize (класс PaperSize)
Размер бумаги, в формате `ширина x высота'. По умолчанию используется формат ISO A4 или `210mm x 297mm'.

7.3.7 Как создаются отображения

В этом разделе обсуждается, как DDD на самом деле создает отображения из данных.

7.3.7.1 Обработка боксов

Все данные, отображаемые в окне данных DDD, предоставляются подчиненным отладчиком. GDB, к примеру, предоставляет список отображений, содержащий символьные выражения, которые следует вычисляют т печатать на стандартный вывод при каждом останове программы. Команда GDB `display tree' добавляет к списку отображений `tree' и заставляет GDB печатать значение `tree', например, в виде `tree = (Tree *)0x20e98', при каждом останове программы. DDD обрабатывает этот вывод GDB и показывает его в окне данных.

Каждый элемент списка отображений, в том виде, в каком он передается от подчиненного отладчика, считывается в DDD и переводится в бокс. Боксы -- это такие прямоугольники с определенным содержимым, которые можно отображать в окне данных. Различают атомарные и составные боксы. Атомарный бокс содержит белый или черный пробел, линию или строку. Составные боксы -- это горизонтальные или вертикальные группы других боксов. Каждый бокс обладает размером и протяженностью, которые определяют его положение во внешнем пространстве.

Составляя все большие и большие боксы DDD создает из структуры данных GDB узел графа, подобно тому, как системы набора текстов вроде TeX строят из букв слова, а из абзацев страницы.

Такие конструкции легко выражаются посредством функций, задающих зависимость бокса от других боксов. Эти функции отображения могут задаваться пользователем, а потом интерпретироваться в DDD, с помощью функционального языка VSL, что означает visual structure language. Пользователь может сам задавать VSL-функции, это оставляет большие пространство для расширений и настроек. VSL-функция отображения, которая помещает вокруг своего аргумента рамку, выглядит так:

// Поместить рамку вокруг текста TEXT
frame(text) = hrule() 
  | vrule() & text & vrule() 
  | hrule();

Здесь hrule() и vrule() -- это примитивы, возвращающие, соответственно, горизонтальную и вертикальную линии. Операторы `&' и `|' создают горизонтальное и вертикальное выравнивание своих аргументов.

VSL предоставляет базовые средства, такие как сопоставление с образцом и функции с переменным числом аргументов. Функция halign(), к примеру, строит горизонтальное выравнивание для произвольного числа аргументов, которым соответствуют три точки (`...'):

// Горизонтальное выравнивание
halign(x) = x;
halign(x, ...) = x & halign(...);

Часто используемые функции, вроде halign(), собраны в стандартную библиотеку VSL.

7.3.7.2 Построение боксов из данных

Чтобы визуализировать структуры данных, каждому атомарному типу и каждому типу-конструктору языка программирования присваивается VSL-функция отображения. Атомарные значения, такие как числа, знаки, перечисления или строки, отображаются с помощью строковых боксов, содержащих их значение; VSL-функция для их отображения оставляет их без изменений:

// Атомарные значения
simple_value(value) = value;

Составные значения требуют большего внимания. Массив, к примеру, можно отобразить при помощи горизонтального выравнивания:

// Массив
array(...) = frame(halign(...));

Когда GDB посылает DDD значение массива, вызывается VSL-функция `array()' с элементами этого массива в качестве значений. Таким образом, выражение-массив GDB `{1, 2, 3}' вычисляется в VSL как

array(simple_value("1"), simple_value("2"), simple_value("3"))

что эквивалентно

"1" & "2" & "3"

составному боксу, содержащему три горизонтально выровненных строковых бокса. VSL-функция, которая используется в DDD на самом деле, также помещает между элементами разделители, и у нее есть вертикальный вариант.

Вложенные структуры, вроде многомерных массивов, отображаются путем последовательного применения функции array() внизу вверх. Сначала array() применяется к наиболее глубоко вложенным структурам; затем результирующие боксы передаются в качестве аргументов в еще один вызов array(). Вывод GDB

{{"A", "B", "C"}, {"D", "E", "F"}}

представляющий массив строк размером 2 на 3, вычисляется в VSL как

array(array("A", "B", "C"), array("A", "B", "C"))

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

Структуры-записи строятся похожим способом, с использованием функции отображения struct_member, для отрисовки членов записи. Имена и значения разделяются знаком равенства:

// Член структуры-записи
struct_member (name, value) = 
  name & " = " & value;

Функция отображения struct рисует саму запись с помощью функции valign().(30)

// Структура-запись
struct(...) = frame(valign(...));

Это простой пример; VSL-функция, которая на самом деле используется в DDD, еще пытается выровнять знаки равенства; кроме того, она гарантирует, что применяются разделители для правильного языка, что свернутые структуры отрисовываются правильно, и так далее.

7.3.7.3 Настройка внешнего вида отображений

С DDD поставляется встроенная библиотека VSL, которой должно быть достаточно для большинства, если не для всех, нужд. Используя следующие ресурсы можно изменять и улучшать определения VSL:

Ресурс: vslBaseDefs (класс VSLDefs)
Строка с дополнительными VSL-определениями, которые добавляются ко встроенной библиотеке VSL. Этот ресурс добавляется перед ресурсом `vslDefs', который описан ниже; он устанавливается в файле ресурсов по умолчанию DDD. Не изменяйте его.

Ресурс: vslDefs (класс VSLDefs)
Строка с дополнительными VSL-определениями, которые добавляются ко встроенной библиотеке VSL. Его значение по умолчанию -- пустая строка. Этот ресурс можно применять для переопределения некоторых определений VSL, затрагивающих отображение данных.

Общий шаблон для замены определения функции функция на новое определение нов_опр такой:

#pragma replace функция
function(аргументы...) = нов_опр;

Часто используются такие VSL-функции:

color(бокс, цвет-текста [, цвет-фона])
Устанавливает цвет-текста и цвет-фона заданного бокса.
display_color(бокс)
Цвет для отображения данных. По умолчанию: `color(бокс, "black", "white")'
title_color(бокс)
Цвет заголовка. По умолчанию: `color(бокс, "black")'
disabled_color(бокс)
Цвет для выключенных боксов. По умолчанию: `color(бокс, "white", "grey50")'
simple_color(бокс)
Цвет для простых значений. По умолчанию: `color(бокс, "black")'
pointer_color(бокс)
Цвет для указателей. По умолчанию:`color(бокс, "blue4")'
struct_color(бокс)
Цвет для структур. По умолчанию: `color(бокс, "black")'
array_color(бокс)
Цвет для массивов. По умолчанию: `color(бокс, "blue4")'
reference_color(бокс)
Цвет для ссылок. По умолчанию: `color(бокс, "blue4")'
changed_color(бокс)
Цвет для измененных значений. По умолчанию: `color(бокс, "black", "#ffffcc")'
stdfontfamily()
Используемое семейство шрифтов. Одно из `family_times()', `family_courier()', `family_helvetica()', `family_new_century()' или `family_typewriter()' (по умолчанию).
stdfontsize()
Размер шрифта (в пикселях). 0 (по умолчанию) говорит, что следует применять `stdfontpoints()'.
stdfontpoints()
Размер шрифта (в десятых долях пункта). 0 говорит, что следует применять `stdfontsize()'. По умолчанию 90.
stdfontweight()
Насыщенность шрифта. Это либо `weight_medium()' (по умолчанию), либо `weight_bold()'.

Чтобы установить цвет указателей в значение "red4", напишите

Ddd*vslDefs: \
#pragma replace pointer_color\n\
pointer_color(box) = color(box, "red4");\n

Чтобы установить размер шрифта равным 10.0 пунктов, используйте

Ddd*vslDefs: \
#pragma replace stdfontsize\n\
#pragma replace stdfontpoints\n\
stdfontsize() = 0;\n
stdfontpoints() = 100;\n

Чтобы по умолчанию использовался 12-пиксельный шрифт courier, напишите

Ddd*vslDefs: \
#pragma replace stdfontsize\n\
#pragma replace stdfontfamily\n\
stdfontsize() = 12;\n\
stdfontfamily() = family_courier();\n

Другие определения, которые вы можете перекрыть с помощью ресурса `vslDefs', смотрите в файле `ddd.vsl'.

Ресурс: vslLibrary (класс VSLLibrary)
Какую библиотеку VSL следует использовать. `builtin' (по умолчанию) означает, что нужно применять встроенную библиотеку, а любое другое значение интерпретируется как имя файла.

Ресурс: vslPath (класс VSLPath)
Разделенный двоеточиями список каталогов, где проводится поиск включаемых VSL-файлов. По умолчанию это `.', текущий каталог.

Если дистрибутив исходников DDD у вас установлен в `/opt/src', вы можете использовать следующие установки, чтобы библиотека VSL считывалась из `/home/joe/ddd.vsl':

Ddd*vslLibrary: /home/joe/ddd.vsl
Ddd*vslPath:    .:/opt/src/ddd/ddd:/opt/src/ddd/vsllib

Включаемые VSL-файлы, на которые ссылается `/home/joe/ddd.vsl', сначала ищутся в текущем каталоге `.', потом в `/opt/src/ddd/ddd/', а потом в `/opt/src/ddd/vsllib/'.

Вместо того чтобы предоставлять еще одну библиотеку VSL, часто бывает проще задать какие-то незначительные изменения для встроенной библиотеки. Подробности смотрите выше, в описании ресурса `vslDefs'.

7.4 Построение графика значений

Если вам нужно исследовать огромный объем числовых данных, рисунок часто может сказать больше, чем тысяча чисел. Поэтому DDD позволяет вам рисовать числовые значения в виде двух- и трехмерных графиков.

7.4.1 Построение графиков массивов

DDD может строить графики двух типов числовых значений:

  • Одномерные массивы. Изображаются в двумерном пространстве x/y, где x обозначает индекс массива, а y --- значение элемента.
  • Двумерные массивы. Изображаются в трехмерном пространстве x/y/z, где x и y обозначают индексы массивы, а z -- значение элемента.

Чтобы построить график массива фиксированного размера, выделите его имя, щелкнув на нем первой кнопкой мыши. Имя массива будет скопировано в поле аргумента. Если щелкнуть на кнопке `Plot', в окне данных появится новое отображение, а потом будет создано новое окно верхнего уровня, содержащее график значений.

Для построения графика массива динамического размера вы должны использовать фрагмент массива (см. раздел 7.3.2.1 Фрагменты массива). Введите в поле аргумента

массив[первый]@число-элементов

где массив -- это имя отображаемого массива, первый -- это индекс первого элемента, а число-элементов -- это число отображаемых элементов. Затем щелкните на `Plot', чтобы начать построение графика.

Также вы можете получить график значений введя в подсказке отладчика такую команду:

graph plot выражение

Она работает подобно `graph display выражение' (и принимает такие же аргументы; см. раздел 7.3.1.1 Создание единичных отображений), но еще дополнительно показывает значение в окне графика.

Каждый раз, когда во время выполнения программы значение изменяется, график обновляется по текущим значениям. Окно графика остается активным до тех пор, пока вы не закроете его (через `File => Close'), или пока не будет удалено соответствующее ему отображение.

7.4.2 Изменение внешнего вида графика

На самом деле DDD не сам строит график. Вместо этого он полагается на внешнюю программу gnuplot.

DDD добавляет к окну графика Gnuplot полоску меню, которая позволяет вам изменять внешний вид графика:

  • Меню `View' переключает необязательные части графика, такие как рамки или сетку.
  • Меню `Plot' изменяет стиль графика. Параметр `3-D Lines' полезен для построение графиков двумерных массивов.
  • Меню `Scale' позволяет использовать логарифмические шкалы, а также включать и выключать засечки шкал.
  • Меню `Contour' добавляет к трехмерным графикам линии контура.

При просмотре трехмерного графика можно менять точку наблюдения с помощью полосок прокрутки. Горизонтальная полоска прокрутки поворачивает график вокруг оси z, то есть вправо или влево. Вертикальная полоска прокрутки поворачивает вокруг оси y, то есть вверх или вниз.

PICS/ddd-plots

Вы также можете, если хотите, изменять размер окна графика.

7.4.3 Построение графиков скалярных и составных значений

Кроме графиков массивов, DDD может также строить графики скаляров (простых числовых величин). Делается это так же, как для массивов --- вы выбираете числовую переменную, щелкаете на `Plot', и появляется график. Однако, построение графика скаляра не так интересно. График, не содержащий ничего кроме скаляра, просто отображает значение этого скаляра в виде константы y -- то есть горизонтальную прямую.

Тогда зачем вообще беспокоиться о скалярах? DDD позволяет объединять на одном графике несколько значений. Основная идея такова: если вы хотите построить график чего-то, что не является ни массивом, ни скаляром, DDD берет из этого чего-то все числовые значения, какие может найти и чертит их графики в одном окне. Например, вы можете построить график всех локальных переменных, выбрав `Data => Display Local Variables' и нажав затем `Plot'. При этом создается график, содержащий все числовые переменные, найденные среди локальных переменных. Аналогично, вы можете получить график всех числовых членов какой-то структуры, выбрав ее и нажав `Plot'.

Если вы хотите точнее контролировать, что включать в график, а что нет, вы можете применить группы отображений (см. раздел 7.3.1.8 Группировка отображений). Довольно часто строят график одномерного массива вместе с текущим индексом. Это делается в три этапа:

  1. Отобразить массив и его индекс с помощью `Display'.
  2. Сгруппировать два этих отображения: выделить их и нажать `Undisp => Cluster ()'.
  3. Построить график группы, нажав `Plot'.

Отображаемые вместе в массивами скаляры могут отрисовываться в виде либо горизонтальных, либо вертикальных линий. По умолчанию скаляры рисуются в виде горизонтальных линий. Однако, если скаляр является индексом ранее начерченного массива, он показывается как вертикальная линия. Вы можете изменить первоначальную ориентацию, выделив отображение скаляра и нажав `Rotate'.

7.4.4 Построение графика истории отображений

При каждом останове программы DDD записывает значения всех отображаемых переменных, чтобы вы могли "отменить" выполнение программы (см. раздел 6.8 "Отмена" выполнения программы). Для таких историй отображений тоже можно построить график. Пункт меню `Plot => Plot history of ()' создает график, в котором показаны все записанные ранее значения выделенного отображения.

7.4.5 Печать графиков

Если вы хотите распечатать график, выберите `File => Print Plot'. Появится диалог для печати графиков. Так же, как для графов, у вас есть выбор между печатью на принтере или в файл, и вы можете установить нужные параметры.

Собственно печать производит опять же Gnuplot, используя подходящий драйвер. Пожалуйста, обратите внимание на следующие возможные проблемы, связанные с печатью:

  • Для создания `FIG'-файлов требуется, чтобы в Gnuplot был встроен соответствующий драйвер. В вашей программе Gnuplot может не быть такого драйвера. В этом случае вам придется перекомпилировать Gnuplot, включив в файл `term.h' строку `#define FIG'.
  • Параметр `Portrait' генерирует @acronym{EPS}-файл, который можно вставлять в другие документы. Параметр `Landscape' велит DDD печатать график такого размера, какой задан параметром `Paper Size'; это полезно для печати на принтере. В режиме `Portrait' параметр `Paper Size' игнорируется.
  • В драйверах устройств Gnuplot для PostScript и X11 разные наборы цветов, поэтому цвета на распечатке могут отличаться от того, что отображается на экране.
  • Параметр `Selected Only' по умолчанию установлен, так что печатается только выделенный в данный момент график. (Если вы выделите для печати несколько графиков, то на выводе они будут последовательно сцеплены в один, хотя вы, возможно, ожидали получить что-то другое.)

7.4.6 Ввод команд для построения графика

С помощью `File => Command' можно вводить команды Gnuplot напрямую. Каждая введенная в подсказку `gnuplot>' команда пересылается в Gnuplot, а после нее выдается команда `replot', которая обновляет изображение. Это полезно для выполнения в Gnuplot более сложных задач.

Вот простой пример. Команда Gnuplot

set xrange [xmin:xmax]

устанавливает диапазон отображения по горизонтали в значение xmin...xmax. Чтобы построить график только элементов от 10 до 20, введите:

gnuplot> set xrange [10:20]

После ввода каждой команды DDD добавляет команду replot, поэтому график обновляется автоматически.

А вот более сложный пример. Следующая последовательность команд Gnuplot сохраняет график в формате TeX:

gnuplot> set output "plot.tex" # Устанавливает имя выходного файла
gnuplot> set term latex        # Задает выходной формат
gnuplot> set term x11          # Снова показывает первоначальное изображение

Из-за неявной команды replot вывод автоматически записывается в файл `plot.tex' после команды set term latex.

Диалоговое окно запоминает введенные команды; чтобы восстановить ранее введенное, используйте курсорные стрелки. Сообщения об ошибках от Gnuplot (если они были), также показываются в области истории.

Диалог между DDD и Gnuplot сохраняется в файле `~/.ddd/log' см. раздел 10.12.1 Запись протокола). Ключ DDD --trace печатает этот диалог на стандартный вывод.

7.4.7 Экспорт графика

Если вы хотите обработать данные графика с помощью какой-то внешней программы (отдельной программой Gnuplot или программой xmgr, например), вы можете записать данные графика в файл, используя `File => Save Data As'. При этом появится диалоговое окно, позволяющее выбрать файл, в котором будут сохранены данные.

Генерируемый файл начинается несколькими строками комментариев. Затем идут сами данные в формате X/Y или X/Y/Z. Это тот же самый файл, какой обрабатывает Gnuplot.

7.4.8 Анимирование графиков

Если вы хотите увидеть, как ваши данные меняются с течением времени, вы можете создать точку останова, последовательность команд которой завершается командой cont (см. раздел 5.1.8 Команды точек останова). Каждый раз, когда достигается эта точка останова "с продолжением", DDD обновляет отображаемые значения, в том числе и графики. Затем DDD выполняет последовательность команд точки останова, продолжая выполнение.

Таким способом вы можете установить точку останова с "продолжением" в каком-то характерном месте внутри обрабатывающего массив алгоритма, и DDD будет отображать процесс графически. Когда ваша программа остановится на самом деле, вы можете применить `Undo' и `Redo', чтобы снова отобразить и исследовать предыдущие ее состояния. См. раздел 6.8 "Отмена" выполнения программы, для дополнительной информации.

7.4.9 Настройка графиков

Вы можете указать, как вызывается программа Gnuplot, и настроить некоторые базовые установки.

7.4.9.1 Вызов Gnuplot

С помощью `Edit => Preferences => Helpers => Plot' вы можете указать, как вызывается программа Gnuplot. Это привязано к такому ресурсу:

Ресурс: plotCommand (класс PlotCommand)
Имя исполняемого файла Gnuplot. По умолчанию это `gnuplot' с несколькими ключами, задающими цвета и начальную геометрию.

С помощью `Edit => Preferences => Helpers => Plot Window' вы можете указать, следует ли использовать для графика окно Gnuplot (`External') или окно DDD (`builtin'). Это привязано к такому ресурсу:

Ресурс: plotTermType (класс PlotTermType)
Тип терминала Gnuplot. Может принимать одно из двух значений:
  • Если это `x11', DDD "поглощает" внешнее выходное окно Gnuplot в своем собственном интерфейсе. Некоторые программы для управления окнами, в частности mwm, плохо справляются с методами поглощения.
  • Если установить этот ресурс равным `xlib' (по умолчанию), то DDD предоставляет встроенное окно графика. В этом режиме графики строятся нормально с любым оконным менеджером, но они возможности настройки меньше (ресурсы Gnuplot не воспринимаются).

Можно и дальше управлять взаимодействием с внешним окном графика:

Ресурс: plotWindowClass (класс PlotWindowClass)
Класс выходного окна Gnuplot. При запуске Gnuplot DDD ожидает появления окна с этим классом и интегрирует его в свой пользовательский интерфейс (если только `plotTermType' не равен `xlib'; смотрите выше). По умолчанию `Gnuplot'.

Ресурс: plotWindowDelay (класс WindowDelay)
Время ожидания (в миллисекундах) окна Gnuplot. До истечения этой задержки DDD проверяет каждое вновь созданное окно, не является ли оно окном с графиком, которое нужно поглотить. Дешевый метод, но к сожалению, некоторые оконные менеджеры не передают DDD событие создания окна. После задержки, если DDD не нашел окно графика, он просматривает все существующие окна, что весьма дорого. По умолчанию 2000.

7.4.9.2 Установки Gnuplot

Чтобы изменить установки Gnuplot, используйте такие ресурсы:

Ресурс: plotInitCommands (класс PlotInitCommands)
Команды, которые DDD посылает программе Gnuplot первым делом. По умолчанию они такие:
set parametric
set urange [0:1]
set vrange [0:1]
set trange [0:1]

Установка `parametric' необходима, чтобы Gnuplot понимал генерируемые DDD файлы данных. Команды, задающие диапазоны, используются для построения графиков скаляров.

Дополнительные команды смотрите в документации по Gnuplot.

Ресурс: plot2dSettings (класс PlotSettings)
Дополнительные начальные установки для двумерных графиков. По умолчанию `set noborder'. Вы можете изменять эти установки по желанию.

Ресурс: plot3dSettings (класс PlotSettings)
Дополнительные начальные установки для трехмерных графиков. По умолчанию `set border'. Вы можете изменять эти установки по желанию.

7.5 Исследование памяти

При использовании GDB или DBX вы можете просматривать содержимое памяти в нескольких форматах, независимо от типов данных вашей программы. Пункт меню `Data => Memory' выводит панель, где вы можете выбрать нужный формат.

PICS/ddd-examine

В этой панели вы можете ввести

  • счетчик повторов, десятичное целое, указывающее, какой объем памяти следует показывать
  • формат отображения -- одно из
    `octal'
    Печатать в виде восьмеричного целого.
    `hex'
    Считать биты значения целым числом и печатать это число в шестнадцатеричной форме.
    `decimal'
    Печатать в виде знакового десятичного целого.
    `unsigned'
    Печатать в виде беззнакового десятичного целого.
    `binary'
    Печатать в виде двоичного целого.
    `float'
    Считать биты значения числом с плавающей запятой и печать это число с использованием типичного синтаксиса для таких значений.
    `address'
    Печатать в виде адреса: абсолютный адрес в шестнадцатеричной форме и сдвиг от ближайшего предшествующего символа.
    `instruction'
    Печатать в виде машинной инструкции. В этом формате размер единицы измерения игнорируется.
    `char'
    Считать целым числом и печатать в виде знаковой константы.
    `string'
    Печатать в виде ограниченной нулем строки. В этом формате размер единицы измерения игнорируется.
  • единица измерения -- одно из
    `bytes'
    Байты.
    `halfwords'
    Полуслова (два байта).
    `words'
    Слова (четыре байта).
    `giants'
    Гигантские слова (восемь байт).
  • адрес -- начальный адрес. Значение этого выражения не обязано быть указателем (хотя может); оно всегда интерпретируется как целочисленный адрес байта памяти.

Есть два способа исследования значений:

  • Вы можете сбросить содержимое памяти в консоль отладчика (с помощью `Print'). Если повторить результирующую команду `x', нажав в консоли Return (см. раздел 10.1.2 История команд), будет показана следующая область памяти.
  • Также можно отобразить дамп памяти в окне данных (с помощью `Display'). Если вы решили отобразить значения, они будут автоматически обновляться при каждом останове программы.


[Содержание]   [Назад]   [Пред]   [Вверх]   [След]   [Вперед]  

Наш баннер
Вы можете установить наш баннер на своем сайте или блоге, скопировав этот код:
RSS новости