Производственно-внедренческий кооператив
"И Н Т Е Р Ф Е Й С"
Диалоговая Единая Мобильная
Операционная Система
Демос/P 2.1
Отладчик программ системы ДЕМОС
adb.
Москва
1988
2
АННОТАЦИЯ
Описан отладчик программ в системе ДЕМОС adb. Рассматрива-
ются директивы отладчика, а также описывается его примене-
ние.
3
1. НАЗНАЧЕНИЕ ПРОГРАММЫ ADB
adb - отладочная программа системы ДЕМОС. Она позволяет
изучать образ памяти прерванной программы, запомненный в
файле core, и выполнять программы под управлением отладчика,
обеспечивая просмотр памяти в различных форматах, выполне-
ние программ с точками останова, а также изменение памяти
или файлов при необходимости. Предполагается, что пользова-
тель хорошо знаком с основными командами системы ДЕМОС.
2. РАБОТА С КОМПИЛЯТОРОМ СИ
Рассмотрим следующую программу на языке Си:
1 char *charp = "это предложение.";
2 main(argc, argv)
3 int argc;
4 char **argv;
5 {
6 int fd;
7 if (argc != 2) {
8 printf("отсутствие имени выходного файла\n");
9 exit(8);
10 }
11 if ((fd = creat(argv[1],0666)) < 0) {
12 printf("%s: не открывается\n", argv[1]);
13 exit(8);
14 }
15 charp = 'Э';
16 save(fd, charp);
17 }
18 save(fd, ptr)
19 int fd;
20 char *ptr;
21 {
22 int cc;
23 while (cc = *ptr++) {
24 write(fd, cc, 1);
25 }
26 }
Рис.1.
Программа иллюстрирует наиболее общие ошибки, допускаемые
программистами на языке Си. Цель программы - изменить малую
русскую букву "э" в начале строки, указанной charp и данную
строку поместить в файл, имя которого задается в командной
строке.
Пусть имя файла, содержащего текст данной программы будет
prog.c. Тогда команда трансляции будет иметь вид:
cc -O -o prog prog.c
4
Реально при этом пройдут следующие процессы:
/lib/c cpp prog.c /tmp/cc0663
/lib/c0 c0 /tmp/cc0663 /tmp/cc1663 /tmp/cc2663
/lib/c1 c1 /tmp/cc1663 /tmp/cc2663 /tmp/cc0663
/lib/c2 c2 /tmp/cc0663 /tmp/cc3663
/bin/as as -u -o prog.o /tmp/cc3663
/bin/ld ld -X /lib/crt0.o -o prog prog.o -lc
где:
cpp - препроцессорная обработка;
c0,c1
- собственно компиляция
c2 - оптимизация полученного кода
as - ассемблирование
ld - редактирование связей.
Следует отметить следующие моменты:
- Необязательный вызов оптимизатора c2 (т.к. указан
флаг -O) желателен при работе с adb, в противном слу-
чае понимание ассемблерного текста усложняется.
- Редактор связей ld подключает к программе стартер
/lib/ctr0.o и библиотеку -lc (/usr/lib/libc.a).
- В команде отсутствует флаг -s (уничтожение таблицы
меток в объектном модуле). Это позволяет adb исполь-
зовать мнемонические имена из программы на Си (типа
charp) вместо их значений.
Результатом работы команды cc будет файл prog. По команде
prog out
должен появиться файл out, содержащий текст
Это предложение.
Однако, этого не произойдет из-за ошибок в программе. Одним
из средств исследования подобных ситуаций и является отлад-
чик adb.
5
3. ВЫПОЛНЕНИЕ ПРОГРАММЫ ADB
3.1. Вызов программы
adb вызывается следующим образом:
adb обфайл обрпам
где обфайл является выполняемым файлом ДЕМОС, а обрпам явля-
ется образом памяти файла. В рассматриваемом примере вызов
adb будет иметь вид:
adb prog
т.к. образ памяти еще не создан. Значениями по умолчанию
являются файлы a.out и core соответственно. Если в качестве
имени файла используется знак минус "-", то данный аргумент
игнорируется, например:
adb - core
3.2. Исследование памяти
В adb имеются команды для исследования памяти в обоих фай-
лах. Командой ? исследуется содержание файла обфайл; коман-
дой / исследуется обрпам.
Основной формат команд изучения памяти:
или
3.3. Текущий адрес
adb поддерживает текущий адрес, (обозначаемый точкой), кото-
рый по своим функциям подобен текущему указателю редактора
ДЕМОС. Когда поступает новый адрес, текущий адрес устанавли-
вается в эту ячейку, так команда:
0126?i
устанавливает текущую точку в восьмеричное 126 и распечаты-
вает инструкцию ЭВМ по данному адресу. Команда:
.,10/d
печатает 10 десятичных чисел, начиная с текущей точки. В
6
конце текущим адресом становится адрес последнего напечатан-
ного слова.
3.4. Выражения
Адреса представлены выражениями. Выражения состоят из деся-
тичных, восьмеричных и шестнадцатеричных чисел и имен пере-
менных отлаживаемой программы. Они могут комбинироваться с
операторами +, -, *, % (целочисленное деление), & (поразряд-
ная конъюнкция), ! (поразрядная дизъюнкция), # (округление
до следующего кратного) и ~ (не) (все вычисления в adb явля-
ются 32-битовыми). Символический адрес для Си-программы
пользователь может напечатать в виде имя или _имя; adb приз-
нает обе формы.
3.5. Форматы
Для печати данных пользователь указывает набор букв и симво-
лов, описывающих формат вывода на печать. Форматы "запомина-
ются", в том смысле что ввод команды без формата производят
вывод информации в соответствии с предыдущим форматом. Ниже
приведены наиболее часто используемые форматы:
^ точка уменьшается на величину текущего инкремента.
a значение точки;
b один байт в восьмеричном коде;
c один байт как символ;
d одно слово в десятичном коде;
f два слова с плавающей запятой;
i команда СМ-4;
n печать символа новой строки;
o одно слово в восьмеричном коде;
r печать пробела;
s строка символов, заканчивающаяся нулевым символом;
u одно слово как десятичная цифра без знака;
Символы формата пригодны и для обозначения длинных (long)
величин, например, D - для длинных десятичных чисел, а F -
для длинных чисел с плавающей запятой (double).
7
3.6. Основные значения команд
В общем случае запрос к adb имеет следующий вид:
адрес,счетчик команда модификатор
который устанавливает точку на "адрес" и выполняет команду
"счетчик" раз.
Далее даны значения некоторых основных команд adb:
! - выполнение команды shell
$ - различные команды
/ - печатает содержимое файла core
: - управление "точкой" останова
; - разделитель команд
= - печатает значение "точки"
? - печатает содержимое файла a.out
adb воспринимает сигналы, поэтому нельзя использовать сиг-
налы прерывания для выхода из adb. Для выхода из adb должна
быть использована команда $q или $Q (или ctrl-d).
4. ОТЛАДКА СИ-ПРОГРАММ
4.1. Изучение образа памяти
Рассмотрим Си-программу, представленную на Рис. 1. Ошибки
заключаются в том, что символ э помещается в указатель charp
вместо строки, указанной charp, а в функции save вместо
адреса cc используется его значение.
adb вызывается командой:
adb prog
Простейшие действия с adb:
save+4:b
:r out
breakpoint ~save+04: tst -(sp)
$c
~save(03,0177774)
~main(02,0176672)
$C
~save(03,0177774)
8
fd: 03
ptr: 0177774
cc: 04542
~main(02,0176672)
argc: 02
argv: 0176672
fd: 03
Как видно из приведенного примера была задана точка останова
на входе в функцию save и команда prog запущена с аргументом
out. В заданной точке произошел останов (breakpoint).
Команда $c вывела стек вызовов функций и их аргументы,
Команда $C сверх этого вывела значения локальных переменных.
Эти значения приемлемы. Для main, например: 02 = два аргу-
мента, 0176672 = адрес в стеке вектора параметров.
Следующая команда распечатывает регистры, включая программ-
ный счетчик и команду в точке останова:
$r
ps 0170004
pc 0310 ~save+04
sp 0176624
r5 0176636
r4 0
r3 04716 _charp
r2 0177113
r1 06
r0 0310
~save+04: tst -(sp)
Команда:
$e
распечатывает значения всех внешних переменных:
$e
_charp: 0177774
Карта памяти существует для каждого файла, работающего под
управлением adb. Память для файла a.out распечатывается
командой ?, а для файла core - с помощью команды /. Более
9
того, существует хорошее правило: использовать ? для команд,
а / - для данных во время просмотра программ. Для того,
чтобы распечатать информацию о размещении переменных в
памяти, введите:
$m
Данная команда распечатывает содержимое карты памяти:
$m
? map `prog'
b1 = 0 e1 = 05510 f1 = 020
b2 = 0 e2 = 05510 f2 = 020
/ map `-'
b1 = 0 e1 = 0100000000 f1 = 0
В данном примере полезно просмотреть содержимое строки, ука-
занной ptr. Это можно сделать следующим образом:
*ptr/s
Данная команда использует ptr как указатель в файле core и
печатает информацию в виде символьной строки. Распечатка
ясно показывает, что ptr указывает не на нужную строку.
Проверим строку, на которую указывает charp:
*charp/s
Результат аналогичен.
Единственной операцией, изменяющей charp может быть присваи-
вание в строке 15. Ошибка состоит в использовании:
вместо
*charp = 'Э';
4.2. Задание точек останова
Точки останова задаются в программе с помощью команды:
Команды:
main+4:b
10
устанавливают точку останова в начало этих функций. Язык Си
не генерирует метки, поэтому, не зная кода, генерируемого
компилятором Си, точки останова можно вставлять только в
местах точек входа в функцию. Рассмотренные выше адреса
вводятся в виде: символ+4, с тем чтобы они появлялись в рас-
печатке стека вызовов функций, поскольку первая команда каж-
дой функции представляет собой вызов процедуры входа в функ-
цию Си (csv).
Для того, чтобы распечатать ячейку, содержащую точку оста-
нова, напечатайте:
$b
Будет указан "счетчик" полей. Точка останова, прежде чем
вызвать останов, прогоняется "счетчик"-1 раз. Поле "команда"
указывает adb, какая команда должна выполняться каждый раз,
когда сосчитана точка останова.
Следующая команда воспроизводит на экране пять команд, начи-
нающихся в main с адресов каждой воспроизведенной ячейки:
main,5?ia
или
main,5?i
Задание точки останова изменяет значение "точки"; при выпол-
нении программы под управлением adb значение "точки" не
изменяется.
4.3. Запуск программы на выполнение
Для выполнения программы наберите команду:
:r
Чтобы удалить точку останова, к примеру вход в функцию save,
напечатайте:
Для продолжения выполнения программы из точки останова,
напечатайте:
:c
Раз программа остановилась, команды adb могут быть использо-
ваны для воспроизведения на экран результата трассировки
стека:
$C
11
Выполнение программы можно продолжить командой:
:c
4.4. Сигналы
ДЕМОС отводит и прерывает сигналы, действующие в самом adb
иначе, чем в отлаживаемой программе. Если такой сигнал
появляется, то программа останавливается, а управление пере-
дается обратно к adb. Сигнал сохраняется adb и пропускается
в исследуемую программу, если используется команда:
:c
Это может быть полезно, когда исследование прерывает проце-
дуры программы управления. Сигнал не пропускается в исследу-
емую программу, если используется команда:
:c 0
4.5. Прочие свойства отладчика
Аргументы и изменения стандартного ввода и вывода вводятся в
программу в виде:
:r арг1 арг2 ... << ввфайл >> вывфайл
Что уничтожает любую тестируемую программу и запускает файл
a.out.
Отлаживаемой программе может быть задан единичный шаг:
:s
Если необходимо, данная команда будет запускать команду,
которая должна быть отлажена, и останавливать ее после
выполнения первой команды.
adb предоставляет возможность запуска программы с указанного
адреса, для этого используется команда:
Команда:
Программа может быть продолжена с адреса, отличного от точки
останова:
Отлаживаемая программа функционирует как отдельный процесс и
может быть удалена командой:
12
:k
Команда:
.=o
печатает в восьмеричном коде текущий адрес (но не его содер-
жимое). Текущий адрес (точка) используется adb для "запоми-
нания" текущей ячейки. Это позволяет пользователю обращаться
к ячейке, связанной с текущим адресом, например:
.-10/d
5. КАРТА ПАМЯТИ
ДЕМОС поддерживает несколько форматов выполняемых файлов.
Они используются для указания загрузчику о том, каким обра-
зом загружать программный файл. Файл 407, используемый в
наиболее типичных случаях, генерируется вызовом компилятора
Си:
cc prog.c
Файл 410 создается командой вида
cc -n prog.c
Файл 411 создается командой
cc -i prog.c.
adb интерпретирует различные форматы файла и обеспечивает
доступ к различным сегментам через поля карты памяти.
Для печати карты памяти используется команда:
В файлах 407 и текст (команды) и данные взаимосвязаны. Это
не позволяет adb отделять данные от команд, поэтому некото-
рые из напечатанных символических адресов выглядят некор-
ректно; например, печать адресов данных как отклонение от
процедур.
В файлах 410 (разделенный текст) команды отделяются от дан-
ных, а команда ?* разрешает доступ части данных файла a.out.
команда ?* говорит adb о том, что нужно использовать вторую
часть карты памяти в файле a.out. Доступные данные в файле
core представляют собой данные, модифицированные при выпол-
нении программы. Заметим также, что сегмент данных может
возрастать вовремя выполнения программы.
13
В файлах 411 (с разделенным i и d пространством) команды и
данные также отделены друг от друга. В этом случае, однако,
поскольку данные распределяются через отдельный набор сег-
ментирующих регистров, основание сегмента данных также соот-
ветствует адресному нулю. В этом случае, поскольку адреса
перекрываются, необходимо использовать оператор ?* для полу-
чения доступа к области данных файла a.out. в файлах 410 и
411 соответствующий файл core не содержит текста программы.
Пример показывает вывод на экран три распределения одной и
той же программы, связанной как 407, 410, 411 соответст-
венно:
adb map407 core407
$m
text map 'map407'
b1 = 0 e1 = 0256 f1 = 020
b2 = 0 e2 = 0256 f2 = 020
data map 'core407'
b1 = 0 e1 = 0300 f1 = 02000
b2 = 0175400 e2 = 0200000 f2 = 02300
$v
variables
d = 0300
m = 0407
s = 02400
$q
adb map410 core410
$m
text map 'map410'
b1 = 0 e1 = 0200 f1 = 020
b2 = 020000 e2 = 020116 f2 = 0220
data map 'core410'
b1 = 020000 e1 = 020200 f1 = 0200
b2 = 0175400 e2 = 0200000 f2 = 02200
$v
variables
b = 020000
d = 0200
m = 0410
s = 02400
t = 0200
$q
adb map411 core411
$m
text map 'map411'
b1 = 0 e1 = 0200 f1 = 020
b2 = 0 e2 = 0116 f2 = 0220
data map 'core411'
b1 = 0 e1 = 0200 f1 = 02000
b2 = 0175400 e2 = 0200000 f2 = 02200
$v
variables
14
d = 0200
m = 0411
s = 02400
t = 0200
$q
Поля b, e и f используются adb для распределения адресов по
адресам файлов. Поле f1 - это размер заголовка в начале каж-
дого файла (020 байтов для файла a.out и 02000 байтов для
файла core). Поле f2 представляет собой переход из начала
файла в область данных. Для файла 470 со смешанными текстом
и данными это является тем же, что и размер заголовка; для
файлов 410 и 411 - это размер заголовка плюс размер порции
текста.
Поля b и e начинают и заканчивают ячейки, отводимые под сег-
мент. Задающая адрес ячейка a в файле вычисляется следующим
образом:
если b1<=a<=e1, то адрес файла = (a-b1)+f1
если b2<=a<=e2, то адрес файла = (a-b2)+f2
Пользователь может получить ячейки, используя определенные
adb переменные. Команда $v печатает переменные, инициализи-
руемые adb:
b базовый адрес сегмента данных
d размер сегмента данных
s размер стека
t размер текста
m выполняемый тип (407, 410, 411)
В примере отсутствующие переменные полагаются равными нулю.
Данные переменные могут использоваться как выражения, для
этого в адресном поле применяется команда:
<<b
Подобным же образом значение переменной может быть изменено
с помощью команды:
02000>>b
устанавливающей b в значение 2000 (в восьмеричном коде).
Значения этих переменных полезно знать, если исследуемый
файл является выполняемым или файлом образа памяти core.
Для нахождения значений данных переменных adb считывает
заголовок файла образа памяти core. Если второй указанный
файл не является файлом core, или если он отсутствует, то
вместо него используется заголовок выполняемого файла.
15
6. ДОПОЛНИТЕЛЬНОЕ ИСПОЛЬЗОВАНИЕ
В adb существует возможность объединять команды форматирова-
ния для обеспечения заранее разработанного вывода. Ниже при-
ведено несколько примеров.
6.1. Сформатированный дамп
Строка:
<<b,-1/4o4^8Cn
печатает 4 слова в восьмеричном коде, за которыми следует их
интерпретация в КОИ-8, из области данных файла образа
памяти. Различные части команды означают:
<<b базовый адрес сегмента данных;
<<b,-1
печатает, начиная с базового адреса до конца файла.
Здесь и в остальных случаях отрицательный счетчик
используется для бесконечного цикла или пока не будет
обнаружено какое-либо ошибочное условие (как, например,
конец файла).
Формат 4o4^8Cn состоит из следующих компонент:
печатает 4 ячейки в восьмеричном коде
возвращает . на 4 слова назад
печатает 8 последовательных символов, используя выход-
ное отношение; каждый символ, находящийся в диапазоне
от 0 до 037 печатается как @, за которым следует соот-
ветствующий символ из диапазона 0140 - 0177. @ печата-
ется как @@.
печатает символ новой строки.
Команда:
<<b,<<d/4o4^8Cn
используется не для разрешения печати, а для остановки в
конце сегмента данных (<<d выдает размер сегмента данных в
байтах).
Команды редактирования могут быть объединены с возможностью
adb считывать команды из файла. adb вызывается следующим
образом:
adb a.out core<dump
16
Данная команда считывает dump. Пример такого файла:
120$w 4095$s $v =3n
$m =3n "обратная трассировка Си-стека"
$C =3n "внешние переменные Си" $e
=3n "регистры" $r 0$s =3n
"сегмент данных" <<b,-1/8ona
Команда 120$w устанавливает ширину вывода равной 120 симво-
лам (обычно, ширина равна 80 символам).
adb печатает адреса в виде:
символ+отклонение
Команда 4095$s сокращает максимально допустимое отклонение
до ближайшего символического адреса от 255 (по умолчанию) до
4095. Команда = может быть использована для печати дословных
строк. Заголовки в программе dump обеспечиваются командой
формы:
=3n обратная трассировка Си-стека""
которая пропускает три строки и печатает дословно строку.
Команда $v печатает все ненулевые значения переменных adb.
Команда 0$s устанавливает максимальное отклонение от соот-
ветствия символов на ноль, тем самым подавляя печать симво-
лических меток в восьмеричном коде. Обратите внимание: это
выполняется только для печати сегмента данных. Команда:
<<b,-1/8ona
печатает дамп начиная с базового адреса сегмента данных до
конца файла с адресным полем в восьмеричном коде и восемью
восьмеричными числами на строку.
6.2. Дамп каталога
В качестве еще одной иллюстрации рассматривается набор
команд, предназначенных для получения дампа содержимого
каталога (которые состоят из целочисленного i-узла (индекс
файла), за которым следует имя, состоящее из 14 символов):
adb dir -
=n8t"/fII-файл/fR"8t"/fIимя/fR"
0,-1?u8t14cn
В данном примере u печатает i-узел/fR как беззнаковое целое
десятичное число, 8t означает, что adb будет делать пропуски
до следующей выходной строки, номер которой кратен 8, а
14c/fB печатает имя файла, состоящее из 14 символов.
17
6.3. Преобразование значений
adb может использоваться для преобразования значений из
одного представления в другое. Например:
072=odx
Данная команда выводит на печать:
072 58 #3a
Что соответствует восьмеричному, десятичному и шестнадцате-
ричному представлениям числа 072 (в восьмеричном коде). Фор-
мат запоминается с тем, чтобы при печати последовательных
чисел, вывод на печать осуществлялся бы в данных форматах.
Значения символов могут быть преобразованы подобным же обра-
зом, например:
'a' = co
данная команда выводит на печать:
Это может также использоваться для оценки выражений, но
будьте осторожны, так как все бинарные операторы имеют оди-
наковый приоритет, который ниже, чем для унарных операторов.
7. ИСПРАВЛЕНИЕ ОШИБОК
Файлы исправления ошибок вызываются с отладчиком adb с
помощью команды write, w или W (которая, однако, не то же
самое, что команда write редактора ed). Эта команда часто
используется вместе с командой locate, l или L. В общем слу-
чае синтаксис команд l и w имеет вид:
?l значение
Команда l используется для проверки на соответствие двух
байтов, L используется для четырех байтов. Команда w
используется для записи двух байтов, тогда как W записывает
четыре байта. Поле "значение" в командах locate или write
представляет собой выражение. Следовательно, поддерживаются
десятичные и восьмеричные числа или строки символов.
С целью модификации файла, adb должен быть вызван в следую-
щем виде:
adb -w файл1 файл2
При вызове с данной опцией, если необходимо, файлы файл1 и
файл2 создаются и открываются для чтения и записи.
18
Для примера можно изменить слово this на the в выполняемом
файле используя следующие команды:
adb -w ex7 -
?l'th'
?W'the'
Команда ?l Стартует в текущем значении точки, а останавлива-
ется на первом появлении th, устанавливая точку на адрес
найденной ячейки. Обратите внимание на использование
команды ? Для записи в файл a.out. команда вида ?* будет
использоваться для файла 411.
Чаще всего команда будет иметь вид:
?l'th';?s
Она обнаруживает первое появление "th" и распечатывает всю
строку. Выполнение данной команды adb будет устанавливать
точку на адрес символов "th".
В качестве примера использования свойства исправления оши-
бок, рассмотрим Си-программу, имеющую внутренний логический
флаг. Флаг может устанавливаться пользователем через adb,
после этого происходит выполнение программы. Например:
adb a.out -
:s арг1 арг2
:c
Команда :c обычно используется для назначения единичного
шага прохождения процесса или запуска процесса в режиме еди-
ничного шага. В этом случае она запускает a.out Как подпро-
цесс с аргументами арг1 и арг2. Если функционирует подпро-
цесс, то adb записывает в него иначе, чем в файл, поэтому
команда w вызывает изменение флага в памяти подпроцесса.
8. ЗАМЕЧАНИЯ
Вызовы и аргументы функции помещаются в стек с помощью про-
цедуры сохранения. Помещение точек останова в точки входа в
процедуры означает, что функция появляется не для того,
чтобы быть вызванной при обнаружении точки останова.
При печати адресов adb использует символы либо текста, либо
данных из файла a.out. Это иногда вызывает печать неисследу-
емых символических имен вместе с данными (например,
savr5+022). Этого не случается, если используется команда ?
для текста (команд) и / для данных.
adb не может управлять регистровыми переменными языка Си в
самых последних случаях активизации функции.
19
СОДЕРЖАНИЕ
АННОТАЦИЯ ......................................... 2
1. НАЗНАЧЕНИЕ ПРОГРАММЫ ADB .......................... 3
2. РАБОТА С КОМПИЛЯТОРОМ СИ .......................... 3
3. ВЫПОЛНЕНИЕ ПРОГРАММЫ ADB .......................... 5
3.1. Вызов программы ................................. 5
3.2. Исследование памяти ............................. 5
3.3. Текущий адрес ................................... 5
3.4. Выражения ....................................... 6
3.5. Форматы ......................................... 6
3.6. Основные значения команд ........................ 7
4. ОТЛАДКА СИ-ПРОГРАММ ............................... 7
4.1. Изучение образа памяти .......................... 7
4.2. Задание точек останова .......................... 9
4.3. Запуск программы на выполнение .................. 10
4.4. Сигналы ......................................... 11
4.5. Прочие свойства отладчика ....................... 11
5. КАРТА ПАМЯТИ ...................................... 12
6. ДОПОЛНИТЕЛЬНОЕ ИСПОЛЬЗОВАНИЕ ...................... 15
6.1. Сформатированный дамп ........................... 15
6.2. Дамп каталога ................................... 16
6.3. Преобразование значений ......................... 17
7. ИСПРАВЛЕНИЕ ОШИБОК ................................ 17
8. ЗАМЕЧАНИЯ ......................................... 18
Популярность: 6, Last-modified: Mon, 29 Jun 1998 13:53:57 GmT