программы, а по команде i этот сигнал игнорируется.

переменная$m счетчик
адрес:m счетчик
Аналогично s, но выполняется до тех пор, пока по указанному адресу не будет занесено новое значение. Переменная должна быть доступна из текущей процедуры. Если счетчик не указан, его можно считать бесконечно большим. Так как данная команда выполняется программно, она работает крайне медленно.

уровень v
Задать полноту выводимой информации при выполнении команд s, S, m. Если уровень опущен, то выводится только название подпрограммы и исходного файла. Если уровень 1 или больше, то при выполнении выводится также исходная строка. Если уровень 2 или больше, то также выводятся все команды ассемблера, соответствующие данной строке.

k
Терминировать процесс, выполняющий отлаживаемую программу.

процедура(арг1, арг2, ... )
процедура(арг1, арг2, ... )/m
Выполнить указанную процедуру с заданными аргументами. Аргументы могут быть целыми числами, символами, цепочками символов или именами переменных, доступных из текущей процедуры. Во втором варианте результат выполнения процедуры выводится в формате m (по умолчанию d). Выполнить отдельную процедуру можно, лишь если редактирование связей осуществлялось командой cc -g.

номер_строки b команды_отладчика
Установить точку прерывания на указанную строку. Если указано имя процедуры без номера_строки (например, proc:), точка прерывания устанавливается на первую строку процедуры, даже если она компилировалась без опции -g. Если номер_строки не указан, то точка прерывания устанавливается на текущую строку. Если команды_отладчика не указаны, то выполнение приостанавливается перед точкой прерывания и управление возвращается sdb. Иначе при достижении точки прерывания выполняются указанные команды_отладчика и работа программы продолжается. Если команд несколько, они разделяются точкой с запятой. Если в качестве команды используется k, то управление передается sdb.

B
Вывести список точек прерывания.

номер_строки d
Снять точку прерывания с заданной строки. Если номер_строки не указан, то запрашивается подтверждение на удаление каждой точки прерывания: выдается ее местоположение и читается ответ (со стандартного ввода). Если ответ начинается с y или d, то точка прерывания снимается.

D
Удалить все точки прерывания.

l
Вывести последнюю выполненную строку.

номер_строки a
Оповещение. Если номер_строки имеет вид процедура:номер, то выполняется команда номер_строки b l. Если номер_строки имеет вид процедура:, то выполняется команда процедура: b T.

Прочие команды

!команда
Команда интерпретируется shell'ом [см. sh(1)].

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

CTRL+D
"Прокрутить". Вывести следующие 10 строк исходного текста, команд или данных в зависимости от того, что выводилось в последний раз.

<имя_файла
Читать команды из указанного файла; по достижении его конца читать команды со стандартного ввода. Эта команда не может быть вложенной.

M
Вывести тройки, управляющие отображениями адресов.

М [?/] [*] b e f
Изменить тройку, управляющую отображением адресов. Аргументы ? и / указавают на отображения, ассоциированные с объектным_файлом и образом_памяти соответственно. Если не указана *, то изменяется первая тройка (b1, e1, f1), иначе - вторая. Если задано меньше трех значений, то оставшиеся элементы тройки остаются неизменными.

"строка
Вывести указанную строку. Разрешается использовать управляющие последовательности языка C \символ, где символ не есть цифра.

q
Выйти из отладчика.

Команды отладки отладчика

V
Вывести версию отладчика.

Q
Вывести список отлаживаемых файлов и процедур.

Y
Переключить режим выдачи внутренней отладочной информации.

ФАЙЛЫ

	a.out
	core

СМ. ТАКЖЕ
cc(1), f77(1), sh(1).
a.out(4), core(4), syms(4) в Справочнике программиста.

ПРЕДОСТЕРЕЖЕНИЯ
При выводе значения внешней переменной, для которой отсутствует отладочная информация, перед ее значением выводится предупреждение. Ее типом по умолчанию считается int.

Данные, хранящиеся в секции команд, недоступны из функций.

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

СЮРПРИЗЫ
Если процедура вызвана, когда программа не остановилась на точке прерывания (например, при отладке образа памяти), то перед началом выполнения процедуры все переменные инициализируются. Это делает невозможным использование процедур, которые осуществляют форматный вывод данных из образа памяти.

Отладчик sdb плохо приспособлен для отладки Фортран-программ. Трудно получить доступ к элементам общих блоков и формальным аргументам, элементы многомерных массивов нумеруются по строкам, а не по столбцам. Кроме того, sdb несовместим с компилятором svs(1). Рекомендуем пользоваться отладчиком КРОТ.
Comments: Пример:
	opaque c[10];
По сравнению с Си, определения в языке RPCL имеют где сокращенную, где расширенную форму. Ограничения касаются невозможности описания многомерных массивов или вложенных указателей (хотя их можно определить с помощью оператора typedef). Два расширения:

  • Данные типа opaque описываются как вектор:
    	opaque идентификатор_объекта[размер]
    
    В соответствии с протоколом будет создан объект указанного размера (в байтах). Обратите внимание на то, что размер в байтах не равен размеру в символах, поскольку символы в XDR размещаются в 32 битах каждый. Определения типа opaque компилируются в выходном файле заголовков в описания массивов символов.
  • Строки описываются особо, по типу векторного определения:
    	string идентификатор_объекта[максимальный_размер]
    
    Если максимальный размер не указан, длина строки практически не ограничивается. Строковые определения преобразуются в:
    	char *идентификатор_объекта
    
    Описания типов
    Rpcgen используется для генерации процедуры XDR и/или файла заголовков, описывающего типы данных из входного файла. Для каждого описываемого zetype утилита rpcgen создает соответствующую процедуру XDR, именуемую xdr_zetype и обязательную для создания RPC-программ.

    Существуют шесть способов описания типа:

        описание_типа:
    	typedef
    	перечислимый_тип-def
    	структура-def
    	массив_переменной_длины-def
    	размеченное_объединение-def
    	программа-def
    

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

    Вложенность описаний типов в XDR не допускается. Например, следующая запись для rpcgen будет непонятна:

    	    struct dontdoit {
    		 struct ididit {
    		  int oops;
    		 } sorry;
    		 enum ididitagain { OOPS, WHOOPS } iapologize;
    	    };
    

    Оператор typedef в XDR выглядит следующим образом: typedef:

    	    typedef имя_типа идентификатор_объекта ;
    
    "Идентификатор объекта" является именем нового типа, в то время как "имя_типа" относится к исходному типу. Например:
    	    typedef longa;
    

    Синтаксис описания перечислимого типа:

    перечислимый_тип-def:
    	    enum идентификатор_типа {
    		   список_типов
    	    };
    список_типов:
    	    символьный_идентификатор [=присваивание]
    	    символьный_идентификатор [=присваивание], список_типов
    	    (в правой части оператора, после знака равенства может распо-
    	    лагаться целая или символьная константа)
    
    Если явного присваивания нет, неявно будет присвоено значение предыдущего элемента перечисления, увеличенное на 1. Первый элемент по умолчанию имеет нулевое значение. Структуры:
    структура-def:
    	    struct идентификатор_структуры {
    		 список_описаний
    	    };
    список_описаний:
    	    описание;
    	    описание; список_описаний
    
    Массивы переменной длины:
    массив_переменной_длины-def:
    	    array идентификатор_массива {
    		 unsigned идентификатор_длины ;
    		 векторное_определение ;
    	    };
    
    Описание массива переменной длины похоже на описание структуры. Пример:
    	    array mp_int {
    		 unsigned len;
    		 short val[MAX_MP_LENGTH];
    	    };
    
    Эта запись преобразуется компилятором в:
    	    struct mp_int {
    		 unsigned len;
    		 short *val;
    	    };
    	    typedef struct mp_int mp_int;
    
    Размеченное объединение:
    размеченное_объединение-def:
    	    union идентификатор_объединения switch (описание_дискриминанта) {
    		список_случаев
    		[default: описание;]
    	    };
    список_случаев:
    	    case идентификатор_случая : описание;
    	    case идентификатор_случая : описание; список_случаев
    описание_дискриминанта:
    	    описание
    

    Описание объединения похоже на пересечение Си-объединения с Си-переключателем. Пример:

    	    union net_object switch (net_kind kind) {
    	    case MACHINE:
    		 struct sockaddr_in sin;
    	    case USER:
    		 int uid;
    		    default:
    		 string whatisit;
    	    };
    
    Эта запись преобразуется компилятором в:
    	    struct net_object {
    		 net_kind kind;
    		 union {
    		  struct sockaddr_in sin;
    		  int uid;
    		  char *whatisit;
    		 } net_object;
    	    };
    	    typedef struct net_object net_object;
    

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

    программа-def:
    	    program идентификатор_программы {
    		  список_версий
    		    }=номер_программы;
    список_версий:
    	    версия
    	    версия список_версий
    версия:
    	    version идентификатор_версии {
    		  список_процедур
    		    }=номер_версии;
    список_процедур:
    	    описание_процедуры
    	    описание_процедуры список_процедур
    описание_процедуры:
    	    имя_типа идентификатор_процедуры(имя_типа)=номер_процедуры;
    

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

    	    program DATE_PROG {
    		  version DATE_VERS {
    		  date DATE_GET(timezone) = 1;
    		  void DATE_SET(date) = 2;  /* время по Гринвичу */
    		  } = 1;
    	    } = 100;
    
    В файле заголовков эта запись будет иметь следующий вид:
    	    #define DATE_PROG 100
    	    #define DATE_VERS 1
    	    #define DATE_GET 1
    	    #define DATE_SET 2
    

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

    Рассмотрим локальную процедуру реализации DATE_GET:

    	    date *  /* всегда возвращает указатель на результаты */
    	    date_get_l(tz)
    		 timezone *tz; /* всегда получает указатель на аргументы */
    		    {
    		 static date d;  /* должна быть статической! */
    		 /*
    		  * получение даты
    		  * и сохранение ее в d
    		  */
    		 return(&d);
    	    }
    

    Имя процедуры совпадает с именем, объявленным в #define, но записывается строчными буквами и оканчивается номером версии. XDR рекурсивно освобождает аргумент после получения результатов из локальной процедуры, поэтому всю необходимую вам информацию из аргумента следует скопировать между обращениями. При этом XDR не манипулирует вашими результатами. Вам следует позаботиться об их сохранении самим. Вывод правил компиляции заголовков
    Правила преобразования суффиксов в
    make(1) при компиляции процедур XDR и заголовков (по условию файлы протоколов RPCL имеют расширение .x):

    	    .SUFFIXES:.x
    	    .x.c:
    		 rpcgen -c $< -o $@
    	    .x.h:
    		 rpcgen -h $< -o $@
    
    Пример: Рассмотрим программу example, в которой описываются данные трех типов:
    	    const NFS_PORT       = 2059;
    	    enum nfsstat {
    		 NFS_OK=0
    		    };
    		    struct gnumbers {
    		 long g_assets;
    		 long g_liabilities;
    	    };
    
    Утилита rpcgen, вызванная без аргументов, создает файл заголовков example.h и файл XDR с именем example_xdr.c.
    	example.h
    	    #define NFS_PORT 2059
    	    enum nfsstat {
    	 NFS_OK = 0,
    	    };
    	    typedef enum nfsstat nfsstat;
    	    bool_t xdr_nfsstat();
    	    struct gnumbers {
    	 long g_assets;
    	 long g_liabilities;
    	    };
    	    typedef struct gnumbers gnumbers;
    	    bool_t xdr_gnumbers(); 
    	 
    	example_xdr.c
    	    #include <rpc/rpc.h>
    	    #include "infile.h" 
    	  
    	    bool_t
    	    xdr_nfsstat (xdrs, objp)
    	 XDR *xdrs;
    	 nfsstat *objp;
    	    {
    	 if (!xdr_enum(xdrs, (enum_t *)objp)) {
    	   return (FALSE);
    	 }
    	 return (TRUE);
    	    } 
    	  
    	    bool_t
    	    xdr_numbers (xdrs, objp)
    	 XDR *xdrs;
    	 gnumbers *objp;
    	    {
    	 if (!xdr_long(xdrs, &objp->g_assets)) {
    	   return (FALSE);
    	 }
    	 if (!xdr_long(xdrs, &objp->g_liabilities)) {
    	   return (FALSE);
    	 }
    	 return (TRUE);
    	    }
    

    СМ. ТАКЖЕ
    "Руководство программиста SCO NFS"

    ЗАМЕЧАНИЯ
    В программных определениях могут встретиться совпадающие имена, при этом сфера действия имен четко не разграничивается. Избежать подобных ситуаций поможет использование уникальных идентификаторов для программ, версий, процедур и типов.

    Вложенность также не поддерживается. Чтобы сымитировать эффект вложенности, объявление структур можно производить на верхнем уровне с тем, чтобы использовать их имена внутри других процедур.
    Comments: info@citmgu.ru
    Designed by Andrey Novikov
    Copyright © CIT