• Stars
    star
    729
  • Rank 61,605 (Top 2 %)
  • Language
    Lua
  • Created almost 12 years ago
  • Updated 3 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A dependency free, embeddable debugger for Lua in a single file (.lua or .c)

debugger.lua

A simple, embedabble debugger for Lua 5.x, and LuaJIT 2.x.

ExampleLog

debugger.lua is a simple, single file, pure Lua debugger that is easy to integrate with any project. The lua-users wiki lists a number of debuggers. clidebugger was closest to what I was looking for, but I ran into several compatibility issues, and the rest are pretty big libraries with a whole lot of dependencies. I just wanted something simple to integrate that would work through stdin/stdout. I also decided that it sounded fun to try and make my own!

Features

  • Trivial to "install". Can be integrated as a single .lua or .c file.
  • The regular assortment of commands you'd expect from a debugger: continue, step, next, finish, print/eval expression, move up/down the stack, backtrace, print locals, inline help.
  • Evaluate expressions, call functions interactively, and get/set variables.
  • Pretty printed output so you see {1 = 3, "a" = 5} instead of table: 0x10010cfa0
  • Speed! The debugger hooks are only set during the step/next/finish commands.
  • Conditional, assert-style breakpoints.
  • Colored output and line editing support when possible.
  • Drop in replacements for Lua's assert(), error(), and pcall() functions that trigger the debugger.
  • When using the C API, dbg_call() works as a drop-in replacement for lua_pcall().
  • IO can easily be remapped to a socket or window by overwriting the dbg.write() and dbg.read() functions.
  • Permissive MIT license.

Easy to use from C too!

debugger.lua can be easily integrated into an embedded project with just a .c and .h file. First though, you'll need to run lua embed/debugger.c.lua. This generates embed/debugger.c by inserting the lua code into a template .c file.

int main(int argc, char **argv){
	lua_State *lua = luaL_newstate();
	luaL_openlibs(lua);

	// The 2nd parameter is the module name. (Ex: require("debugger") )
	// The 3rd parameter is the name of a global variable to bind it to, or NULL if you don't want one.
	// The last two are lua_CFunctions for overriding the I/O functions.
	// A NULL I/O function  means to use standard input or output respectively.
	dbg_setup(lua, "debugger", "dbg", NULL, NULL);

	// Load some lua code and prepare to call the MyBuggyFunction() defined below...

	// dbg_pcall() is called exactly like lua_pcall().
	// Although note that using a custom message handler disables the debugger.
	if(dbg_pcall(lua, nargs, nresults, 0)){
		fprintf(stderr, "Lua Error: %s\n", lua_tostring(lua, -1));
	}
}

Now in your Lua code you can just use the global variable or require the module name you passed to the dbg_setup() call.

Debugger Commands:

If you have used other CLI debuggers, debugger.lua shouldn't be surprising. I didn't make a fancy parser, so the commands are just single letters. Since the debugger is pretty simple there are only a small handful of commands anwyay.

[return] - re-run last command
c(ontinue) - contiue execution
s(tep) - step forward by one line (into functions)
n(ext) - step forward by one line (skipping over functions)
p(rint) [expression] - execute the expression and print the result
f(inish) - step forward until exiting the current function
u(p) - move up the stack by one frame
d(own) - move down the stack by one frame
w(here) [line count] - print source code around the current line
t(race) - print the stack trace
l(ocals) - print the function arguments, locals and upvalues.
h(elp) - print this message
q(uit) - halt execution

If you've never used a command line debugger before, start a nice warm cozy fire, run tutorial.lua, and open it up in your favorite editor so you can follow along.

Debugger API

There are several overloadable functions you can use to customize debugger.lua.

  • dbg.read(prompt) - Show the prompt and block for user input. (Defaults to read from stdin)
  • dbg.write(str) - Write a string to the output. (Defaults to write to stdout)
  • dbg.shorten_path(path) - Return a shortened version of a path. (Defaults to simply return path)
  • dbg.exit(err) - Stop debugging. (Defaults to os.exit(err))
  • `dbg.pretty(obj)' - Output a pretty print string for an object. (Defaults to a reasonable version using __tostring metamethods and such)

Using these you can customize the debugger to work in your environment. For instance, you can divert the I/O over a network socket or to a GUI window.

There are also some goodies you can use to make debugging easier.

  • dbg.writeln(format, ...) - Basically the same as dbg.write(string.format(format.."\n", ...))
  • dbg.pretty_depth = int - Set how deep dbg.pretty() formats tables.
  • dbg.pretty(obj) - Will return a pretty print string of an object.
  • dbg.pp(obj) - Basically the same as dbg.writeln(dbg.pretty(obj))
  • dbg.auto_where = int_or_false - Set the where command to run automatically when the active line changes. The value is the number of context lines.
  • dbg.error(error, [level]) - Drop in replacement for error() that breaks in the debugger.
  • dbg.assert(error, [message]) - Drop in replacement for assert() that breaks in the debugger.
  • dbg.call(f, ...) - Drop in replacement for pcall() that breaks in the debugger.

Environment Variables:

Want to disable ANSI color support or disable GNU readline? Set the DBG_NOCOLOR and/or DBG_NOREADLINE environment variables.

Known Issues:

  • Lua 5.1 lacks the API to access varargs. The workaround is to do something like local args = {...} and then use unpack(args) when you want to access them. In Lua 5.2+ and LuaJIT, you can simply use ... in your expressions with the print command.
  • You can't add breakpoints to a running program or remove them. Currently the only way to set them is by explicitly calling the dbg() function explicitly in your code. (This is sort of by design and sort of because it's difficult/slow otherwise.)
  • Different interpreters (and versions) print out slightly different stack trace information.
  • Tail calls are handled silghtly differently in different interpreters. You may find that 1.) stepping into a function that does nothing but a tail call steps you into the tail called function. 2.) The interpreter gives you the wrong name of a tail called function (watch the line numbers). 3.) Stepping out of a tail called function also steps out of the function that performed the tail call. Mostly this is never a problem, but it is a little confusing if you don't know what is going on.
  • Coroutine support has not been tested extensively yet, and Lua vs. LuaJIT handle them differently anyway. -_-

License:

Copyright (c) 2023 Scott Lembcke and Howling Moon Software

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

More Repositories

1

Chipmunk2D

A fast and lightweight 2D game physics library.
C
2,167
star
2

Tina

Tina is a teeny tiny, header only, coroutine and job library.
C
254
star
3

Cocos2DShaderCookbook

A introductory guide to shaders with Cocos2D 3.1.
Objective-C
115
star
4

SpacePatrol

A high performance, large scale, deformable terrain example for Chipmunk Pro.
Objective-C
82
star
5

CocoRoids

Example game Cocos2D v3 using CCPhysics and SpriteBuilder.
Objective-C
63
star
6

CCPhysicsColorMatch

A simple CCPhysics based color matching game.
Objective-C
49
star
7

CloudBomber

Chipmunk Pro Autogeometry demo built on top of Cocos2D 2.0.
Objective-C
46
star
8

CCController

Use XBox, PlayStation (and other HID controllers) with Apple's GameController.framework.
Objective-C
32
star
9

ChipmunkShowcase

Chipmunk Pro Showcase app for iOS
Objective-C
28
star
10

UnofficialCocos2DTemplate

Cocos2D v3.4 template that does not require SpriteBuilder
Objective-C
26
star
11

veridian-expanse

Source code for the asteroid mining game I've been building.
C
20
star
12

ChipmunkColorMatch

A simple color matching game example for Chipmunk, Chipmunk Pro, Cocos2D and UIKit.
Objective-C
17
star
13

GalacticGuardian.spritebuilder

Open source Cocos2D/SpriteBuilder twin stick shooter.
Objective-C
15
star
14

LiFFT

The little FFT library
C
14
star
15

CausticCavern.spritebuilder

SpriteBuilder demo using some of the new 3.1 features.
Objective-C
14
star
16

critical-match

A hybrid platform/color matching game for NES.
C++
12
star
17

mini-lz4

A little lz4 implementation I made for fun.
Assembly
8
star
18

TwilightGolf

Open sourcing an old iPhone game we made.
C
8
star
19

love-debugger

A wrapper for debugger.lua for the Lรถve game engine.
Lua
8
star
20

Gemeralds

Pinball game using CocosBuilder and Chipmunk Pro to make the collision geometry.
Objective-C
7
star
21

InterglacticTransmissing

Interglactic Transmissing for NES
C
7
star
22

neslib-template

Template NES project in C using neslib.
C++
6
star
23

HotReloadingInC

C
5
star
24

AngryChipmunks

A simple Cocos2D/ChipmunkPro example project.
Objective-C
5
star
25

slembcke.github.io

Website
JavaScript
4
star
26

streamingtest

Playing around with memory mapped bandwith with lz4
C
4
star
27

Disasteroids2

Simple CCPhysics prototype game using GPL spritelib graphics.
Objective-C
3
star
28

flatpak-marathon

Flatpak build for Aleph One + Marathon 1, 2, and 3
Makefile
3
star
29

GCControllerTester

Extremely simple app that displays the values of an iOS 7 GCController (extended profile only).
Objective-C
3
star
30

elua.lua

ERB inspired templates for Lua.
Lua
2
star
31

pixler

C library for creating NES games.
Assembly
2
star
32

libpng

Temporary libpng Xcode project repository for Cocos2D.
C
2
star
33

PuzzleSnake

A little js / svg puzzle game
C
2
star
34

Super-City-Mayor

C++
2
star
35

SlapstickNES

Global Game Jam NES project template
C
2
star
36

ImageConvert

Extremely simple image conversion CLI tool for OS X.
Objective-C
1
star
37

MultiTouchObjectiveChipmunk

A simple Cocos2D 2.1 project demonstrating multi-touch physics with Objective-Chipmunk.
Objective-C
1
star
38

vscode-m68k

Gnu as m68k syntax highlighting for VSCode.
1
star
39

Blockade

Board game for the NES made during the 2021 Global Game Jam
C++
1
star
40

ggj22

Global Game Jam '22
Lua
1
star
41

AdventOfCode2020

Lua
1
star
42

iPhoneSnap2D

A simple ChipmunkPro/UIKit example of a physics board game.
Objective-C
1
star
43

tree-perf

Comparing performance of various AABB tree algorithms
C
1
star
44

over-crispd

Gene editing game for the NES inspired by Overcooked. Made for the Global Game Jam 2019.
C
1
star
45

ConcaveSprite

A simple example showing how to use Chipmunk Pro autogeometry to generate concave polygon shapes from Cocos2D sprites automatically.
Objective-C
1
star