function debugging lua function-pointers visualizer

function - Accediendo al cuerpo de una función con Lua



debugging function-pointers (4)

Volveré a lo básico aquí, pero en Lua, puedes definir una tabla como esta:

myTable = {} myTable [1] = 12

La impresión de la referencia de la tabla le devuelve un puntero. Para acceder a sus elementos, debe especificar un índice (es decir, exactamente como lo haría con una matriz)

print(myTable ) --prints pointer print(myTable[1]) --prints 12

Ahora las funciones son una historia diferente. Puede definir e imprimir una función así:

myFunc = function() local x = 14 end --Defined function print(myFunc) --Printed pointer to function

¿Hay alguna manera de acceder al cuerpo de una función definida? Estoy tratando de armar un pequeño visualizador de código y me gustaría ''sembrar'' una función dada con funciones / variables especiales para permitir que un visualizador se ''enganche'' en el código, necesitaría poder redefinir la función ya sea desde una variable o una cadena.


Echa un vistazo a Lua Introspective Facilities en la biblioteca de depuración.

La principal función introspectiva en la biblioteca de depuración es la función debug.getinfo. Su primer parámetro puede ser una función o un nivel de pila. Cuando llamas a debug.getinfo (foo) para alguna función foo, obtienes una tabla con algunos datos sobre esa función. La tabla puede tener los siguientes campos:

El campo que querrías es func, creo.


No hay forma de obtener acceso al código fuente del cuerpo de una función determinada en Lua simple. El código fuente se descarta después de la compilación en el código de bytes.

Observe por cierto que esa función se puede definir en tiempo de ejecución con facilidad parecida a una cadena de carga.

Las soluciones parciales son posibles, dependiendo de lo que realmente desee lograr.

Puede obtener la posición del código fuente de la biblioteca de depuración, si la biblioteca de depuración está habilitada y los símbolos de depuración no se eliminan del bytecode. Después de eso, puede cargar el archivo de origen real y extraer el código de allí.

Puede decorar las funciones que le interesan manualmente con los metadatos necesarios. Tenga en cuenta que las funciones en Lua son teclas de tabla válidas, por lo que puede crear una tabla de función a metadatos. Le recomendamos que haga que esta tabla sea débil, de modo que no impida que GC recopile las funciones.

Si necesita una solución para analizar el código Lua, eche un vistazo a Metalua .


Puede lograr esto creando un entorno para cada función (vea setfenv ) y usando variables globales (versus locales). Las variables creadas en la función aparecerían en la tabla de entorno después de que se ejecuta la función.

env = {} myFunc = function() x = 14 end setfenv(myFunc, env) myFunc() print(myFunc) -- prints pointer print(env.x) -- prints 14

Alternativamente, puede hacer uso de la biblioteca de depuración :

> myFunc = function() local x = 14 ; debug.debug() end > myFunc() > lua_debug> _, x = debug.getlocal(3, 1) > lua_debug> print(x) -- prints 14

Probablemente sea más útil para usted recuperar las variables locales con una función de enlace en lugar de ingresar explícitamente al modo de depuración (es decir, agregar la llamada debug.debug ())

También hay una interfaz de depuración en la API Lua C.


Usar la biblioteca de depuración es su única apuesta. Usando eso, puede obtener la cadena (si la función está definida en un fragmento que se cargó con ''loadtring'') o el nombre del archivo en el que se definió la función; junto con los números de línea en los que comienza y termina la definición de la función. Ver la documentación .

Aquí, en mi trabajo actual, hemos parchado a Lua para que incluso le proporcione los números de columna para el inicio y el final de la función, para que pueda obtener el origen de la función usando eso. El parche no es muy difícil de reproducir, pero no creo que pueda publicarlo aquí :-(