Библиотека отладчика MySQL


Библиотека отладчика, используемая MySQL была первоначально написана Фредом Фишом (Fred Fish). Она будет очень полезна, если Вы планируете отлаживать и/или добавлять функциональные возможности к СУБД MySQL.

Автор зачем-то приводит заголовок файла dbug.c из исходников пакета (вместе со всеми комментариями к нему). Приведу его и я, поскольку это может быть продиктовано какими-либо юридическими проблемами с копирайтом. Поскольку я не юрист, привожу этот заголовок без какого-либо перевода (во избежание ошибок или искажения смысла юридического документа при переводе).

/*************************************************************************
 *                              N O T I C E                              *
 *                                                                       *
 *                 Copyright Abandoned, 1987, Fred Fish                  *
 *                                                                       *
 *   This previously copyrighted work has been placed into the  public   *
 *   domain  by  the  author  and  may be freely used for any purpose,   *
 *   private or commercial.                                              *
 *                                                                       *
 *   Because of the number of inquiries I was receiving about the  use   *
 *   of this product in commercially developed works I have decided to   *
 *   simply make it public domain to further its unrestricted use.   I   *
 *   specifically  would  be  most happy to see this material become a   *
 *   part of the standard Unix distributions by AT&T and the  Berkeley   *
 *   Computer  Science  Research Group, and a standard part of the GNU   *
 *   system from the Free Software Foundation.                           *
 *                                                                       *
 *   I would appreciate it, as a courtesy, if this notice is  left  in   *
 *   all copies and derivative works.  Thank you.                        *
 *                                                                       *
 *   The author makes no warranty of any kind  with  respect  to  this   *
 *   product  and  explicitly disclaims any implied warranties of mer-   *
 *   chantability or fitness for any particular purpose.                 *
 *************************************************************************
*/

/*
 *  FILE
 *      dbug.c   runtime support routines for dbug package
 *
 *  SCCS
 *      @(#)dbug.c      1.25    7/25/89
 *
 *  DESCRIPTION
 *      These are the runtime support routines for the dbug package.
 *      The dbug package has two main components; the user include
 *      file containing various macro definitions, and the runtime
 *      support routines which are called from the macro expansions.
 *
 *      Externally visible functions in the runtime support module
 *      use the naming convention pattern "_db_xx...xx_", thus
 *      they are unlikely to collide with user defined function names.
 *
 *  AUTHOR(S)
 *      Fred Fish               (base code)
 *      Enhanced Software Technologies, Tempe, AZ
 *      asuvax!mcdphx!estinc!fnf
 *
 *      Binayak Banerjee        (profiling enhancements)
 *      seismo!bpa!sjuvax!bbanerje
 *
 *      Michael Widenius:
 *      DBUG_DUMP       - To dump a piece of memory.
 *      PUSH_FLAG "O"   - To be used instead of "o" if we don't
 *                        want flushing (for slow systems)
 *      Check of malloc on entry/exit (option "S")
*/

Функции библиотеки отладчика

_db_push_

Поместить в стек текущее состояние отладчика, и установить новое.

СИНТАКСИС:

  VOID _db_push_ (control)
  char *control;

ОПИСАНИЕ:

По указателю в параметре "control" на строку управления отладкой помещает в стек текущее состояние отладки, анализирует строку управления и устанавливает новое состояние отладки.

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

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

<field_1><field_2><field_N>

Каждое поле состоит из обязательного символа флажка отладки, сопровождаемого факультативным "," и списком параметров, разделенных запятыми:

flag[,modifier,modifier,...,modifier]

Символы флажка отладки:

d Разрешает вывод из макроса DBUG_ для текущего состояния. Может сопровождаться списком ключевых слов, который разрешает вывод только для DBUG макрокоманд с соответствующим ключевым словом. Пустой список ключевых слов подразумевает вывод для всех макрокоманд.
D Ждать после каждой выведенной отладчиком строки. Аргумент задает число десятых долей секунды, которое нужно ждать. Например, -#D,20 задает паузу в 2 секунды.
f Ограничивает отладку и/или трассировку списком имен функций. Обратите внимание, что пустой список отключит все функции. Соответствующий флажок "d" или "t" должен все же быть дан, поскольку этот флажок только ограничивает их действие, если они включены.
F Идентифицируют имя исходного файла для каждой строки отладки или трассирует вывод.
i Идентифицируют процесс с pid для каждой строки отладки или трассирует вывод.
g Включить профилирование. Создайте файл 'dbugmon.out', содержащий информацию, которая может использоваться, чтобы профилировать программу. Может сопровождаться списком ключевых слов, которые выбирают профилирование только для функций в этом списке. Пустой список подразумевает, что все функции подлежат профилированию.
L Идентифицирует номер строки исходного файла для каждой строки отладки или трассирует вывод.
n Выводит текущую глубину вложенности функции для каждой строки отладки или трассирует вывод.
N Номер каждой строки вывода отладки.
o Переназначает выходной поток отладчика в файл. По умолчанию задан stderr.
O То же, что и o, но файл сбрасывается между записями. То есть, после каждой записи файл закрывается, и снова открывается только перед следующей записью. Тормозит, конечно, кошмарно, но зато гарантирует сохранность данных в этом файле на случай слета системы. Что при отладке не бесполезно...
p Ограничивает действия отладчика определенными процессами. Процесс должен быть указан в макросе DBUG_PROCESS и совпадать с одной из записей в списке действий отладчика.
P Выводит имя текущего процесса для каждой строки отладки или трассирует вывод.
r При установке нового состояния отладки не наследует предыдущее состояние вложенности функции. Полезно, когда вывод должен начаться в левом поле.
S Функция _sanity(_file_, _line_) для каждой отлаживаемой функции до _sanity() возвращает отличное от 0 значение. Обычно используется с safemalloc. Как задается это значение, и что оно вообще значит в документации не сказано (!!!), а опытным путем это установить не удалось.
t Включить функцию трассировки строк вызова и выхода (call/exit). Может сопровождаться списком, содержащим число номер максимального уровня трассировки, вне которого никакого вывода не произойдет для отладочных или трассировочных макрокоманд. Умолчание задается при компиляции.

Некоторые примеры строк управления отладкой:

  -#d:t
  -#d:f,main,subr1:F:L:t,20
  -#d,input,output,files:n

_db_pop_

ОПИСАНИЕ:

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

_db_enter_

СИНТАКСИС:

  VOID _db_enter_ (_func_, _file_, _line_, _sfunc_, _sfile_, _slevel_,
                   _sframep_)
  char *_func_;           points to current function name
  char *_file_;           points to current file name
  int _line_;             called from source line number
  char **_sfunc_;         save previous _func_
  char **_sfile_;         save previous _file_
  int *_slevel_;          save previous nesting level
  char ***_sframep_;      save previous frame pointer

ОПИСАНИЕ:

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

Также печатает строку трассировки, если трассировка включена и увеличивает текущее значение глубины вложения функций.

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

_db_return_

СИНТАКСИС:

  VOID _db_return_ (_line_, _sfunc_, _sfile_, _slevel_)
  int _line_;             current source line number
  char **_sfunc_;         where previous _func_ is to be retrieved
  char **_sfile_;         where previous _file_ is to be retrieved
  int *_slevel_;          where previous level was stashed

ОПИСАНИЕ:

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

_db_pargs_

Параметры файла протокола для последующего использования _db_doprnt_().

СИНТАКСИС:

  VOID _db_pargs_ (_line_, keyword)
  int _line_;
  char *keyword;

ОПИСАНИЕ:

Новая универсальная макрокоманда печати DBUG_PRINT, которая заменяет все формы макрокоманд DBUG_N, нуждается в двух обращениях к подпрограммам поддержки во время выполнения. Первая, это функция, которая запоминает параметры, которые используются последующим обращением для _db_doprnt_().

_db_doprnt_

Печать дескриптора строк отладки.

СИНТАКСИС:

  VOID _db_doprnt_ (format, va_alist)
  char *format;
  va_dcl;

ОПИСАНИЕ:

Когда вызывается через одну из DBUG макрокоманд, проверяет текущий набор ключевых слов, вызывая _db_pargs_() чтобы узнать, была ли эта макрокоманда выбрана для обработки через строку управления отладчика, и если так, печатает аргументы с помощью форматированной строки. Номер строки DBUG макрокоманды в источнике найден в u_line.

Обратите внимание, что строка формата (format) НЕ ДОЛЖНА включить завершение строки (\n), это делается автоматически.

_db_dump_

Выполняет дамп строки, пока не найдет '\0'.

СИНТАКСИС:

  void _db_dump_ (_line_,keyword,memory,length)
  int _line_;               current source line number
  char *keyword;
  char *memory;             Memory to print
  int length;               Bytes to print

ОПИСАНИЕ:

Выполняет дамп N символов в двоичный массив. Используется, чтобы исследовать разрушенную память или массивы.

ListParse

Анализ списка параметров в строке контроля отладки.

СИНТАКСИС:

  static struct link *ListParse (ctlp)
  char *ctlp;

ОПИСАНИЕ:

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

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

InList

Проверите данную строку на членство в данном списке.

СИНТАКСИС:

  static BOOLEAN InList (linkp, cp)
  struct link *linkp;
  char *cp;

ОПИСАНИЕ:

Проверяет строку, на которую указывает "cp" чтобы определить, находится ли эта строка в списке, на который указывает "linkp". Linkp указывает на первую строку в списке. Если linkp == NULL, то строка обрабатывается, как будто она находится в списке (все строки находятся в пустом списке). Это может казаться довольно странным сначала, но ведет к желательной операции, если никакой список не задан. Результатом является то, что все строки будут приняты, когда не имеется никакого списка, но когда имеется список, будут приняты только те строки, которые есть в списке.

PushState

Сохраняет текущее состояние в стеке и устанавливает новое.

СИНТАКСИС:

  static VOID PushState()

ОПИСАНИЕ:

Сохраняет текущее состояние в стеке и устанавливает новое. Единственным параметром, унаследованным из предыдущего состояния является уровень вложения функции. Это можно отменить флажком "r".

Стек состояния это связанный список состояний, с новым состоянием, добавленным в начало. Это позволяет стеку расти до самых границ памяти в случае необходимости.

DoTrace

Проверка разрешения на трассировку.

СИНТАКСИС:

  static BOOLEAN DoTrace (stack)

ОПИСАНИЕ:

Проверяет разрешена ли трассировка, не достигнута ли еще максимальная глубина трассировки, текущая функция выбрана и текущий процесс выбран. Возвращает TRUE, если все в порядке, и FALSE в противном случае.

DoProfile

Проверяет разрешено ли профилирование.

СИНТАКСИС:

  static BOOLEAN DoProfile()

ОПИСАНИЕ:

Проверяет разрешено ли профилирование, не достигнута ли еще максимальная глубина трассировки, текущая функция выбрана и текущий процесс выбран. Возвращает TRUE, если все в порядке, и FALSE в противном случае.

_db_keyword

Проверяет ключевое слово на членство в списке ключевых слов.

СИНТАКСИС:

  BOOLEAN _db_keyword_ (keyword)
  char *keyword;

ОПИСАНИЕ:

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

Возвращает TRUE, если ключевое слово входит в список, и FALSE в противном случае.

Indent

СИНТАКСИС:

  static VOID Indent (indent)
  int indent;

ОПИСАНИЕ:

Выравнивает строку на заданный уровень indent. Отступ может быть задан во время компиляции пакета в виде количества символов на один уровень вложения.

FreeList

Освободить всю память, занятую элементами списка.

СИНТАКСИС:

  static VOID FreeList (linkp)
  struct link *linkp;

ОПИСАНИЕ:

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

StrDup

Создает копию строки в новой области памяти.

СИНТАКСИС:

  static char *StrDup (string)
  char *string;

ОПИСАНИЕ:

Параметр string задает строку, копия которой нужна. Функция распределяет количество памяти, достаточное для создания копии строки и копирует строку в эту область памяти. Сбой при распределении памяти фатален.

DoPrefix

Вывести префикс строки отладки.

СИНТАКСИС:

  static VOID DoPrefix (_line_)
  int _line_;

ОПИСАНИЕ:

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

OpenFile

Открывает новый поток вывода для вывода отладчика.

СИНТАКСИС:

  static VOID OpenFile (name)
  char *name;

ОПИСАНИЕ:

Параметр name является именем нового файла (или "-" для stdout). Файл открывается, и в него назначается вывод отладчика.

OpenProfile

Открывает новый поток вывода для вывода профайлера.

СИНТАКСИС:

  static FILE *OpenProfile (name)
  char *name;

ОПИСАНИЕ:

Параметр name задает имя файла, который открывается и назначается в качестве вывода для профайлера.

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

CloseFile

Закрывает поток вывода отладчика.

СИНТАКСИС:

  static VOID CloseFile (fp)
  FILE *fp;

ОПИСАНИЕ:

Закрывает поток вывода отладчика, если это не stdout или stderr.

DbugExit

Выводит сообщение об ошибке и завершает работу.

СИНТАКСИС:

  static VOID DbugExit (why)
  char *why;

ОПИСАНИЕ:

Выводит сообщение об ошибке, используя текущее имя процесса, причина прерывания выполнения (обычно мало памяти), и выходит с 1 состоянием. Это должно быть изменено, чтобы использовать при выходе код состояния, определенный в отладчике пользователя. Но это будет в следующих версиях.

DbugMalloc

Выделяет память для библиотек поддержки отладчика.

СИНТАКСИС:

  static long *DbugMalloc (size)
  int size;

ОПИСАНИЕ:

Выделяет дополнительную память для библиотек поддержки отладчика. Сбой при распределении запрошенного число байтов фатален для текущего процесса. Это довольно недружелюбное поведение. Лучше просто печатать предупреждающее сообщение, замораживать текущее состояние отладчика, и продолжать выполнение. Но это в следующей версии (может быть)...

static_strtok

СИНТАКСИС:

  static char *static_strtok (s1, separator)

ОПИСАНИЕ:

Аналог strtok, но 2 разделителя в строке заменены на 1 для совместимости с именами каталогов, принятыми в DOS.

BaseName

Удаляет путь из полного имени файла.

СИНТАКСИС:

  static char *BaseName (pathname)
  char *pathname;

ОПИСАНИЕ:

Параметр pathname является указателем на полное имя файла. Функция размещает в памяти короткое имя файла и возвращает указатель на него.

Writable

Проверяет возможность записи/создания файла.

СИНТАКСИС:

  static BOOLEAN Writable (pathname)
  char *pathname;

ОПИСАНИЕ

Поскольку отладчик может быть связан и с программой, которая выполняется с битом uid прав доступа (suid), мы должны быть внимательными относительно открытия заданного пользователем файла для вывода отладчика. Это состоит из проверки доступа к файлу на запись с реальным идентификатором пользователя, или проверкой каталога, где файл будет создан.

Вернет TRUE, если все в порядке и FALSE в противном случае.

ChangeOwner

Меняет владельца на реального пользователя для suid программ.

СИНТАКСИС:

  static VOID ChangeOwner (pathname)

ОПИСАНИЕ:

Для Unix-систем, меняет владельца недавно созданного файла отладки на реального владельца. Это нужно в случаях выполнения программ, запущенных с правом доступа set-user-id.

Обратите внимание, что владелец файла уже установлен на момент выдачи этой команды. Так что, если она выполняется без права доступа set-user-id, то эта команда смысла не имеет (но безобидна).

_db_setjmp_

Сохранить окружение отладчика.

СИНТАКСИС:

  VOID _db_setjmp_ ()

ОПИСАНИЕ:

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

_db_longjmp_

Восстановить предварительно сохраненное окружение отладчика.

СИНТАКСИС

  VOID _db_longjmp_ ()

ОПИСАНИЕ:

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

DelayArg

Преобразует параметр флажка D к системному стандарту.

СИНТАКСИС:

  static int DelayArg (value)
  int value;

ОПИСАНИЕ:

Преобразует время задержки, задаваемое в десятых долях секунды, к системному стандарту. Например, на Amiga, имеется системный вызов "Delay()" который получает параметр в импульсах таймера (50 в секунду). На Unix команда sleep работает с числом секунд. Таким образом, значение "10", для задержки в течение одной секунды, преобразуется в 50 на Amiga, и 1 на Unix. Другие системы будут должны использовать цикл синхронизации.

perror

Моделирование perror для систем, которые его не имеют.

СИНТАКСИС:

  static VOID perror (s)
  char *s;

ОПИСАНИЕ:

Perror выдает сообщение в стандартный поток ошибки, которое обеспечивает большее количество информации относительно библиотеки или ошибки системы. Выводится сообщение, заданное строкой s, затем ': ', сообщение об ошибке и перевод строки (\n).

Недокументированная возможность Unix perror сводится к тому, что если 's' является пустой строкой (но не NULL!), то не выводится ': '.

Эта версия выдает сообщение только о "неизвестной ошибке системы".

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

Локальное оглавление.

На главную страничку.

© 2000 Alexey Pautov rldp@ftp.botik.ru.
Information Club of the developers PHP