Справочное руководство по языку 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 (и ничего из стека не выталкивает) когда значение индекса больше чем количество внешних локальных переменных.