Справочное руководство по языку Lua 5.1 :: 3.8 - Псевдо-индексы
3.8 – Интерфейсы отладки
Lua не имеет встроенных удобных средств отладки. Вместо этого существует специальный интерфейс посредством функции и hook -функций. С его помощью можно создавать различные отладчики, профайлеры и другие инструменты, требующие «внутренней информации», предоставляемой интерпретатором.
lua_Debug
typedef struct lua_Debug {
int event;
const char *name; /* (n) */
const char *namewhat; /* (n) */
const char *what; /* (S) */
const char *source; /* (S) */
int currentline; /* (l) */
int nups; /* (u) number of upvalues */
int linedefined; /* (S) */
int lastlinedefined; /* (S) */
char short_src[LUA_IDSIZE]; /* (S) */
/* private part */
other fields
} lua_Debug;
Эта структура используется для предоставления информации об активной функции. lua_getstack используется для заполнения только private-части этой структуры. Для того, чтобы заполнить остальные поля lua_Debug используйте lua_getinfo.
Поля структуры lua_Debug имеют следующее значение:
- source: Если функция была определена в строке, то source будет содержать эту строку. Если же функция была определена в файле, тогда source начинается с символа '@' за которым следует имя файла.
- short_src: «пригодная для печати» версия source, используемая в сообщениях об ошибках.
- linedefined: номер строки, в которой начинается описание функции.
- lastlinedefined: номер строки, в которой заканчивается описание функции.
- what: Строка "Lua", если функция является функцией LUA>, строка "C" если «Си-шная», "main" если это основная часть chunk и "tail" если это функция, которая совершает завершающий вызов (if it was a function that did a tail call). В последнем случае, Lua не имеет более никакой информации об этой функции.
- currentline: Текущая строка, где данная функция выполняется. Когда информация о текущей строке недоступна, currentline устанавливается равной -1.
- name: Подходящее имя (a reasonable) для данной функции name. Поскольку функции в Lua являются first class объектами, они не имеют фиксированного имени: одни функции могут быть значениями множества глобальный переменных, в то время как другие могут храниться только в полях таблицы. Функция lua_getinfo проверяет как функция была вызвана для того, чтобы найти подходящее имя. Если имя найти не удалось, то значение поля name устанавливается в NULL.
- namewhat: Объясняет поле name. Может принимать значения "global", "local", "method", "field", "upvalue", или "" (пустая строка), в соответствии с тем, как функция была вызвана. (Lua использует пустую строку, когда никакие другие значения не подходят)
- nups: число внешних локальных переменных функции.
lua_gethook
lua_Hook lua_gethook (lua_State *L);
Возвращает текущую hook-функцию.
lua_gethookcount
int lua_gethookcount (lua_State *L);
Возвращает текущее количество инструкций, после которых происходит вызов hook-функций.
lua_gethookmask
int lua_gethookmask (lua_State *L);
Возвращает текущую маску hook’а.
lua_getinfo
int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar);
Возвращает информацию об определенной функции или вызовах функции.
Для получения информации о вызовах функции параметр ar должен быть активирующей записью, которая была заполнена предыдущим вызовом lua_getstack или передана в качестве аргумента hook’у (см. lua_Hook).
Для того, чтобы получить информацию о функции, вы должны ее поместить в стек и в начало строки what добавить символ '>'. (В этом случае, lua_getinfo помещает функцию на вершину стека). Например, для того чтобы узнать, на какой строке определена функция f, можно использовать следующий код:
lua_Debug ar;
lua_getfield(L, LUA_GLOBALSINDEX, "f"); /* get global 'f' */
lua_getinfo(L, ">S", &ar);
printf("%d\n", ar.linedefined);
Каждый символ строки what определяет, какие поля структуры ar должны быть заполнены, или какое значение должно быть помещено в стек:
- 'n': заполнять поля name и namewhat;
- 'S': заполнять поля source, short_src, linedefined, lastlinedefined, и what;
- 'l': заполнить поле currentline;
- 'u': заполнить поле nups;
- 'f': поместить в стек функцию, которая выполняется на заданном уровне;
- 'L': поместить в стек таблицу, индексы которой являются номерами функциональных строк функции. (Функциональная строка – это такая строка, которая содержит некоторый код, и на которой можно поставить точку останова. Не функциональными строками являются пустые строчки и комментарии)
Функция возвращает 0 при ошибке. (Например, при неправильной опции в строке what).
lua_getlocal
const char *lua_getlocal (lua_State *L, lua_Debug *ar, int n);
Получает информацию о локальной переменной данной структуры активации. Параметр ar должен быть структурой активации, которая была заполнена предыдущим вызовом lua_getstack или передана в качестве аргумента hook’у (см. lua_Hook). Параметр n определяет какую локальную переменную необходимо рассматривать. (1 означает первый параметр или активную локальную переменную и так далее до последней активной локальной переменной). lua_getlocal помещает значение переменной в стек и возвращает ее имя.
Переменные, имена которых начинаются с '(' (открывающаяся круглая скобка) представляют собой внутренние переменные (счетчики циклов, временные переменные, и локальные переменные функций на C).
Возвращает NULL (и ничего не помещает в стек) когда значение индекса больше чем количество активных локальных переменных.
lua_getstack
int lua_getstack (lua_State *L, int level, lua_Debug *ar);
Получает информацию о стеке времени выполнения.
Функция заполняет часть структуры lua_Debug с идентификацией структуры активации функции, выполняемой на заданном уровне. Уровень 0 – это выполняемая в данный момент функция, тогда как уровень n+1 это функция, которая была вызвана с уровня n.. Когда не было обнаружено ошибок, lua_getstack возвращает 1; когда значение уровня больше чем высота стека – будет возвращен 0.
lua_getupvalue
const char *lua_getupvalue (lua_State *L, int funcindex, int n);
Получает информацию о внешней локальной переменной (upvalue) экземпляра (closure) функции. (Функции Lua используют такие переменные и, следовательно, включают их в экземпляр). Функция lua_getupvalue получает индекс n внешней локальной переменной, извлекает ее значение в стек и возвращает ее имя. Значение funcindex указывает на положение экземпляра в стеке. (Внешние локальные переменные не имеют своего порядка, так как они активны в течение всего времени выполнения функции. Поэтому, они имеют случайный порядок.)
Возвращает NULL (и ничего не помещает в стек) когда индекс больше чем число внешних локальных переменных. Для функций, написанных на C, используется пустая строка “”в качестве имени всех внешних локальных переменных
lua_Hook
typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar);
Тип данных для отладки hook-функций.
Каждый раз, когда вызывается hook, у аргумента ar поле event принимает значение события, которое инициировало запуск. Lua определяет эти события при помощи следующих констант: LUA_HOOKCALL, LUA_HOOKRET, LUA_HOOKTAILRET, LUA_HOOKLINE, и LUA_HOOKCOUNT>. Кроме того, если произошло событие LUA_HOOKLINE, заполняется еще и поле currentline. Для получения значение любого другого поля в структуре ar, hook должен вызвать lua_getinfo. Для возвращения событий, event может быть LUA_HOOKRET, обычное значение или LUA_HOOKTAILRET. В последнем случае, Lua имитирует возвращение из функции, которая совершает завершающий вызов, при этом вызывать функцию lua_getinfo бесполезно.
Пока Lua выполняет hook, другие обращения к нему блокируются. Поэтому, если hook обращается обратно к Lua для выполнения функции или chunk, это выполнение произойдет без каких-либо обращений к hook-ам.
lua_sethook
int lua_sethook (lua_State *L, lua_Hook f, int mask, int count);
Устанавливает отладочную hook функцию.
Аргумент f – это hook-функция. Параметр mask определяет, при каких события эта функция будет вызвана: Он формируется из констант LUA_MASKCALL, LUA_MASKRET, LUA_MASKLINE и LUA_MASKCOUNT побитовым «или». Аргумент count имеет смысл только если маска содержит константу LUA_MASKCOUNT. Для каждого другого события, hook вызывается согласно тому, как это объяснено ниже:
- Hook вызова: выполняется, когда интерпретатор вызывает функцию сразу после того как Lua входит в новую функцию, но перед тем, как функция получит свои аргументы.
- Hook возвращения: выполняется когда интерпретатор выходит из функции.Hook вызывается сразу после того, как Lua покидает функцию, при этом нет никакого доступа к значение, которые функция возвратила.
- Hook строки: выполняется, когда интерпретатор собирается начать выполнение новой строки кода или когда переходит назад в коде (даже на ту же строчку). (Это событие происходит только, когда Lua выполняет функции Lua)
- Hook подсчета: выполняется после того, как интерпретатор выполнит каждую count–ую инструкцию. (Это событие происходит только, когда Lua выполняет функции Lua)
Для того, чтобы запретить hook, необходимо установить mask в ноль.
lua_setlocal
const char *lua_setlocal (lua_State *L, lua_Debug *ar, int n);
Устанавливает значение локальной переменной данной активационной структуры. Параметры ar и n are такие же как и в lua _getlocal (см. lua_getlocal). lua_setlocal назначает значение, находящееся на вершине стека переменной и возвращает ее имя, при этом значение из стека извлекается.
Возвращает NULL (и ничего не выталкивает из стека) когда индекс больше чем количество активных локальных переменных.
lua_setupvalue
const char *lua_setupvalue (lua_State *L, int funcindex, int n);
Устанавливает значение внешней локальной переменной экземпляра функции.Назначает значение, находящееся на вершине стека внешней локальной переменной и возвращает ее имя. Назначенное значение из стека выталкивается.. Параметры funcindex и n are такие же как и в lua_getupvalue (см. lua_getupvalue).
Возвращает NULL (и ничего из стека не выталкивает) когда значение индекса больше чем количество внешних локальных переменных.