To help you find bugs in your programs, LuaGnome provides a few helpers. Note
that all of these are not available when you specify --disable-debug
when configuring the base library; this saves some memory but that is probably
not relevant in most cases, so I suggest you include the debugging code.
Runtime Debug Flags
There are a few flags you can set to aid debugging through two mechanisms.
One is to set the global variable gnome_debug_flags before loading
any LuaGnome related library, the other is to call
gnome.set_debug_flags. In both cases you should specify the flags
as strings as in the example below:
<%= inline_code [[
gnome_debug_flags = { "valgrind", "gmem" }
require "gtk"
gnome.set_debug_flags("memory", "trace")
gnome.unset_debug_flags "trace"
]] %>
A list of known debug flags follow. In the source, this list can be found
in src/gnome/debug.c, _debug_flag_list.
- trace
- Print a line on stdout before calling any library function,
similar to the Unix tool "strace". Note: Currently tracing doesn't
work for overrides, as this would require extra code in each such function.
- return
- Show a warning when a library function returns something
of type void* (not NULL), which could not be interpreted in any
way and therefore had to be discarded.
- memory
- Print a line on stdout when an object is allocated or
garbage collected.
- gmem
- Enables GLib's memory tracing functions, which collects
statistics at runtime and prints them at program exit. This flag has to
be enabled before loading the core library, i.e. through the global
variable gnome_debug_flags.
- valgrind
- Make it easier to run valgrind on LuaGnome to find
memory leaks. This flag has to be set before loading the core library,
i.e. through the global variable gnome_debug_flags.
- closure
- As explained on the Page on
Closures, these objects are sometimes tricky regarding their allocation
and freeing. This flag causes closures not to be freed on garbage
collection, so that accesses to freed closures can be detected.
Additionally information about closure allocation and freeing is
printed.
Debugging Functions
LuaGnome provides a set of functions to aid debugging; more might be
added in the future.
Some of these functions are obviously a hack and you shouldn't depend
on them to be available forever.
- function_sig(closure [, align])
- Computes the function signature of the given function as a string, i.e.
the return type, the function's name and the types of all arguments. If
align is given, the return type's width is at least that many
characters, useful to make a nice list of many functions. Example:
<%= inline_code [[
print(gnome.function_sig(gtk.window_new))
]] %>
- function_sig(module, func_name, [align])
- Same as above, but
doesn't require a closure to exist, so this is better to list lots of
functions (see script/funclist.lua). The function name can be given
with or without the module's function prefix. Examples:
<%= inline_code [[
print(gnome.function_sig(gtk, "window_new"))
print(gnome.function_sig(gtk, "gtk_window_new"))
]] %>
- set_debug_flags(flag, ...)
- Set all the given flags, which
must be strings from the list above. Some flags cannot be set at
runtime, but must be given in gnome_debug_flags. An error is
printed if you try it anyway.
- unset_debug_flags(flag, ...)
- Unset the given flags, e.g. to
stop function tracing.
- dump_struct(object)
- Print a complete structure on stdout, e.g.
a Gtk widget or similar. Can be helpful to see what fields exist;
unfortunately it doesn't show the current values (yet).
- dump_stack(everything)
- Display the Lua stack of the current
stack frame, or the complete Lua stack if everything is set.
- dump_memory()
- This function tries to list all currently allocated
Lua objects, starting with the global table and the registry.
- get_refcount(object)
- Returns the number of references the GObject has, followed by the
object's type name. For newly created widgets this usually is 1. You can
manipulate the refcount with object:ref(),
object:unref(), object:ref_sink() and similar methods.
- breakfunc
- A function that simply prints "BREAK" on stdout. The
idea is that you can set a breakpoint in lg_breakfunc in your
debugger and insert gnome.breakfunc() at some interesting point
in your program. This is useful to debug LuaGnome itself. Sample gdb
session:
$ gdb --args lua myprogram.lua
(gdb) b lg_breakfunc
Function "lg_breakfunc" not defined.
Breakpoint 1 (lg_breakfunc) pending.
(gdb) r
...
Breakpoint 1, lg_breakfunc (L=0x962e008) at src/gnome/debug.c:32
32 printf("BREAK\n");
(gdb)
- for k, v in pairs(gnome.aliases) do print(k, v, gnome.get_refcount(v))
end
- This loop shows all proxy objects along with their reference
counter. If you place this at the end of your program after a call to
collectgarbage "collect", this list should be almost empty. If
it is quite long, you better have a look at memory management. Hint:
be sure to unset global variables, and call :destroy() on top level
windows first.
- box_debug
- Returns the number of currently allocated boxed objects.
- dump_vwrappers
- Prints statistics about allocated void wrappers, followed by a list
of all currently allocated wrappers along with the location in the
Lua source where they were allocated.
- get_vwrapper_count
- Return the number of allocated void wrappers, total allocations so
far and the number of currently existing Lua wrappers for the void
wrappers.
External Tools
The following tools are useful to debug programs written with LuaGnome.
- gdb
- The GNU Debugger, which can be used to find tricky bugs.
Be sure to run configure with the argument --debug for
building, otherwise you'll not get any debug symbols.
- g-inspector
- A GTK+ object/class inspector, which can show the
widget list/tree, types etc. on a running program. Simply run
g-inspector program.lua. Note: on Debian, the package name
is ginspector.
- valgrind
- For subtle memory problems, valgrind can detect some
issues with malloc/free, buffer overruns etc. This is probably only useful
when debugging LuaGnome, not programs that use it.