A screenshot of ZeroBrane Studio in black (Ubuntu 12.04, MATE Desktop with BlackMATE theme, TomorrowNightBright ZBS theme), courtesy of naturally as shown in Moai forums. You may click on the image to see it full screen.

You can choose one from several color themes that are included with ZeroBrane Studio.

Moonscript is an interesting dynamic scripting language that compiles to Lua. Moonscript can be dynamically compiled and run using a component called moonloader and because moonloader keeps a mapping between the moonscript code and the produced Lua code, I thought it could be possible to extend the debugging in ZeroBrane Studio to take that mapping into account in some way.

The version of the debugging bundled with ZeroBrane Studio v0.70+ provides a way to specify a line mapper that can be used to map the current line in the Lua code to the line number in the "original" moonscript code. This code is "injected" in the debugger when the debugging session is started, so any line number used by the debugger (whether to show the current line, set a breakpoint, or display a stack trace) goes through that mapping.

Let's see how you can now debug moonscript files.

ZeroBrane Studio configuration.

1. Get ZeroBrane Studio (0.70+). These instructions are for Windows, but the debugging should work on Linux and OSX as well.

2. Get Moonscript plugin and save it to ZBS/packages/ or HOME/.zbstudio/packages folder (where ZBS is the path to ZeroBrane Studio location and HOME is the path specified by the HOME environment variable); the second option may also be preferable for Mac OS X users as the packages/ folder may be overwritten during an application upgrade.

3. (Optional) If moon executable is in a folder listed in the PATH environment variable, you don't need to do anything as the plugin will find it; if the executable is in some other location, you may need to add path.moonscript = [[/full/path/moon.exe]] to the ZBS configuration file (Edit | Preferences | Settings: User).

4. Start ZBS (zbstudio.exe or zbstudio.sh).

Script debugging.

Let's now debug a simple three line script:

sum = (x, y) ->
  x + y
print "The sum is ", sum 10, 20

Save it as sum.moon and set the project directory to the folder where you saved the script (Project | Project Directory | Set From Current File) and select Moonscript as the current interpreter by going to Project | Lua Interpreter | Moonscript (this option is only available when the Moonscript plugin is installed).

Now if you Run the script, you should see "The sum is 30" in the output. If you select Debug, you should see the debugging started at line 1 and should be able to step through the script, set breakpoints, look at the stack trace, and use all other debugging functionality available in ZeroBrane Studio. Note that all the line numbers are from the moonscript source and not from the (dynamically) generated Lua code, as can be seen on the screenshot:

Moonscript debugging

You may notice that stepping in the debugger through the moonscript code spends more time on the same line than you'd expect. One of the most prominent examples is class definitions or table comprehensions that map few lines of Moonscript code to a (potentially) large number of lines in the corresponding Lua code, which causes the debugger to stay on the same line for each "step" through the Lua code. This may be improved in the future, but for now it's something to keep in mind; if you want to get to your destination faster, you can use breakpoints.

That's not all you can use the debugger for. You can also use moonscript expressions in the Watch panel; for example, if you enter sum 10, 20, you'll see 30 as the result after sum function is defined.

But there is more. You can also execute moonscript expressions in the Remote console. As can be seen on the screenshot, you can execute sum 1, 2 and get 3 as the result. You can also execute export mult = (x, y) -> x * y and then execute mult 10, 20 to get 200 as the result. Essentially, you can use the Remote console as Moonscript REPL with access to your application state. The only current limitation with the console commands is that they need to be single commands; this is a feature of command execution in the console that "flattens" multi-line scripts into one-liners (which doesn't work well with Moonscript, because of its whitespace sensitivity).

And one more thing. Not only syntax highlighting and folding is supported to some degree (as it's based on the Coffeescript lexer), but auto-complete for Lua functions also works with both . and \ notations, so using str = "" and str\ will offer "string" methods in the auto-complete list.

This functionality is highly experimental and has been tested with Moonscript 0.2.5 and 0.2.6 using the current ZeroBrane Studio (0.70). Give it a try with your moonscript application and share your experience in the comments or using any other method that works for you.

Fresh on the heels of getting OpenResty debugging to work with ZeroBrane Studio, I thought I would take a look at Lapis debugging. Lapis is a web framework for Lua or Moonscript, which runs inside OpenResty. Leaf Corcoran just released v1.0, which got better Lua support and more extensive documentation.

Since Lapis runs inside OpenResty, I'll be using a very similar setup to what was used for OpenResty debugging while following instructions on Creating a Lapis Application with Lua page.

ZeroBrane Studio configuration.

1. Get ZeroBrane Studio (0.70+). These instructions are for Windows, but the debugging should work on Linux and OSX as well.

2. Start ZBS (zbstudio.exe or zbstudio.sh) and start the debugger Project | Start Debugger Server.

Lapis configuration.

The easiest way to get Lapis and its dependencies is to use luarocks package manager and run luarocks install lapis command. You then need to make Lapis and its dependencies available to Nginx/OpenResty. If you don't have luarocks installed or prefer to do things manually, try the following:

1. Download Lapis and copy lapis folder inside of it to <NGINX>/lua folder.

2. Download ansicolor.lua and copy it into <NGINX>/lua folder.

3. Download and compile lpeg and cjson libraries and copy the resulting dynamic libraries to the same folder where you have lua51 dynamic library (.dll, .so, or .dylib). If you are using Windows and get those libraries from LuaForWindows, LuaDist, or similar binary distribution, you may need to copy <ZBS>/bin/lua5.1.dll (not lua51.dll!) to the same folder where you copied the libraries (where lua51.dll file is located). This is necessary because those dll files are likely to be linked to lua5.1.dll, but OpenResty comes with lua51.dll and this lua5.1.dll acts as a proxy.

OpenResty configuration.

1. I'm using a very basic config (<NGINX>/conf/nginx.conf):

worker_processes  1;
events {
    worker_connections  1024;
http {
    lua_package_path '<ZBS>/lualibs/?/?.lua;<ZBS>/lualibs/?.lua;;';
    lua_package_cpath '<ZBS>/bin/clibs/?.dll;;';
    server {
        location / {
            default_type 'text/html';
            content_by_lua_file 'lua/web.lua';

Make sure you replace <ZBS> with the actual path to ZeroBrane Studio location. If you are running on OSX, replace ?.dll with ?.dylib and if you are running on Linux, replace bin/clibs/?.dll with either bin/linux/x86/clibs/?.so or bin/linux/x64/clibs/?.so depending on your platform.

2. Create the file we are going to debug (<NGINX>/lua/web.lua), which may look like this:

local lapis = require("lapis")

Note that start() call takes the IP of the computer running the IDE. It uses "localhost" by default, but since your nginx instance is running there, you will need to specify the IP address of the computer running the IDE (in my case it is

3. Create the application file as described in Creating a Lapis Application with Lua (<NGINX>/lua/my_app.lua):

local lapis = require "lapis"
local app = lapis.Application()
app:get("/", function(self)
  return "Hello world"
return app

4. Open both files (web.lua and my_app.lua) in the IDE and set the project directory to lua folder by going to Project | Project Directory | Set From Current File.

If you already have a Lapis application you want to debug, you only need to update the Nginx config to include references to ZeroBrane Studio libraries and add require('mobdebug').start(....) and require('mobdebug').done() calls to web.lua file.

Script debugging.

Now start nginx and go to http://localhost/. If everything is done correctly, you should see ZeroBrane Studio activated with the green arrow pointing to the third line in the web.lua files. You can now set breakpoints, step through the code, look at the stack and so on.

Using step into command (Project | Step Into) will allow you to step into my_app.lua file. If you want the application to stop in the handler that returns "Hello world", you can set a breakpoint on line 4 and then use "Run" command (Project | Run).

Note that the browser window will be showing "waiting for..." message until the execution of web.lua file is completed, at which point you should see "Hello world" text there.

Debugging of Lapis files.

In addition to debugging your own application, you may also step through Lapis files if you are interested. If you open one of Lapis files in the IDE, you will be able to set breakpoints and step through it. You may also configure the IDE to auto-open any Lua file the control gets into by setting editor.autoactivate = true in the configuration file.

ZeroBrane Studio has already been used to debug various Lua engines -- game frameworks (like Corona, Gideros, Moai, Love2d), home automation devices, wireshark scripts, Adobe Lightroom plugins, and more -- but there have been several Lua environments that I haven't tried it on. One of them is OpenResty/Nginx Lua scripts. OpenResty is a web application server built around nginx, a very fast web server, that provides non-blocking IO with various backends (Redis, Memcached, MySQL, HTTP servers, and others) and supports Lua as its scripting language.

I first tried to use the non-blocking socket API that OpenResty provides, but couldn't get the debugging to work because socket calls that were supposed to be blocking were returning too early, which was breaking the interaction between the debugger in the application and the IDE. Based on advice from Yichun Zhang (agentzh), the maintainer of the OpenResty bundle, I then tried to use the same luasocket library that ZeroBrane Studio is using and got it all working. These are the steps you can follow to try it yourself:

ZeroBrane Studio configuration.

1. Get ZeroBrane Studio. These instructions are for Windows, but the debugging should work on Linux and OSX as well.

2. Start ZBS (zbstudio.exe or zbstudio.sh) and start the debugger Project | Start Debugger Server.

OpenResty configuration.

1. I'm using a very basic config (<NGINX>/conf/nginx.conf):

worker_processes  1;
events {
    worker_connections  1024;
http {
    lua_package_path '<ZBS>/lualibs/?/?.lua;<ZBS>/lualibs/?.lua;;';
    lua_package_cpath '<ZBS>/bin/clibs/?.dll;;';
    server {
        location /hellolua {
           default_type 'text/plain';
           content_by_lua_file 'lua/content.lua';

Make sure you replace <ZBS> with the actual path to ZeroBrane Studio location. If you are running on OSX, replace ?.dll with ?.dylib and if you are running on Linux, replace bin/clibs/?.dll with either bin/linux/x86/clibs/?.so or bin/linux/x64/clibs/?.so depending on your platform.

2. Create the file we are going to debug (<NGINX>/lua/content.lua), which may look like this:

local name = ngx.var.arg_name or "Anonymous"
ngx.say("Hello, ", name, "!")
ngx.say("Done debugging.")

Note that start() call takes the IP of the computer running the IDE. It uses "localhost" by default, but since your nginx instance is running there, you will need to specify the IP address of the computer running the IDE (in my case it is

3. Open this file (<NGINX>/lua/content.lua) file in the IDE and set the project directory to lua folder by going to Project | Project Directory | Set From Current File.

Script debugging.

Now start nginx and go to http://localhost/hellolua. If everything is right, you should see ZeroBrane Studio activated with the green arrow pointing to the second line (similar to what can be seen in the screenshot above). You can now set breakpoints, step through the code, look at the stack and so on.

You can also go to the remote console and run any ngx command there. For example, if you run ngx.say("Message from console") (as shown in the screenshot), you will see this text in the output after the script is done.

If you get "attempt to yield across C-call boundary" error in Nginx logs when you start debugging, try with a more recent ZeroBrane Studio (0.70+) as it includes several improvements that make debugging to work with recent versions of OpenResty.

Continue reading Debugging OpenResty and Nginx Lua scripts with ZeroBrane Studio

(This post is by Christopher Reimold, who tested and documented the details of Adobe Lightroom plugin debugging.)

Adobe Photoshop Lightroom is a photo management and editing program that offers the ability to extend its functionality through plugins written in Lua. Debugging Lightroom plugin scripts has often been a somewhat cumbersome process, in which one had to resort to printing of variables to the console in order to understand what's going on in your plugin. However, there is now the possibility to use full in-editor interactive debugging which we will briefly demonstrate in this article.

Minimally useful demo Lightroom plugin script

We use the following short script to demonstrate developing and debugging of a Lightroom (LR) plugin in ZeroBrane Studio Lua IDE. The plugin shows the exposure value to the user. To create a plugin for LR, you have to create at least two files and one directory:

(1) The Info.lua file, which is a manifest that provides information about your plugin to LR. Its name is always Info.lua.

(2) Your actual plugin, which is called ShowExposureValue.lua in this example. It is referenced from your Info.lua file, as shown in the highlighted fragment above.

Put these two files into a directory called ExposureValue.lrplugin; the directory can reside anywhere on your hard disk. The .lrplugin extension will make LR recognize this directory as a plugin. On OSX, .lrplugin directories are recognized and treated as a package (single file). This can sometimes be problematic during development, and you can thus use .lrdevplugin as an extension on OSX if you want to avoid this.

If you want to learn more about developing an LR plugin, please have a look at the Lightroom SDK, in particular the programmer's guide and the API reference.

Continue reading Debugging Adobe Lightroom plugins with ZeroBrane Studio

ZeroBrane Studio has supported Corona SDK debugging for over a year, but one of the less known features of the integration is that it supports on-device debugging in addition to debugging in the simulator.

Since you can't initiate this process from the IDE, it requires slightly different steps:

1. You need to include the debugger component (mobdebug.lua) with your application code (to allow require 'mobdebug' command to execute successfully). You can find it under lualibs/mobdebug in ZeroBrane Studio folder.

2. You need to include require('mobdebug').start("IP-address-of-computer-running-ZBS") in your code. Note that with "regular" debugging you simply include require("mobdebug").start(), but in this case you need to provide a domain name or an IP address of the computer with the IDE as this is where the debugger in the application will connect to.

3. You need to start debugger server in the IDE by going to Project | Start Debugger Server.

4. If you do debugging on Android devices, you may need to add android.permission.INTERNET permissions to the build settings, as documented here.

If you open your Lua files in the IDE and you run your application on the device, you should see the message in the IDE that debugging has started. Most of debugging functions should work (stepping, breakpoints and the stack view), but any function that requires loadstring (remote console, watches, or value tooltips) won't work and will cause a run-time error in your application.

If you want to protect yourself from those run-time errors, you may run the following command in the local console ide.debugger.options = {noshell = true, noeval = true}; this will disable remote console and watches/tooltip evaluations to avoid using loadstring in the debugger. This configuration will be in effect for any debugging started remotely and will reset when you start any debugging from the IDE itself.

A better fix would be to allow Corona SDK to support loadstring during debugging; you may upvote this feature request that asks Corona to implement this.

Keszegh Balazs, one of Gideros forum users put together a detailed overview of using ZeroBrane Studio for debugging of Gideros applications, including on-device debugging. Take a look at the tutorial if you have any questions about Gideros debugging with ZeroBrane Studio.

ZeroBrane Studio is often used for remote debugging, when the application being debugged is running on a different computer or a device, and it is very convenient to be able to "redirect" its printed output to the IDE. The IDE supports this functionality and not only allows "redirecting" of the printed output, but also pretty prints the results such that local t = {a = 1, b = 2} print(t) will print {a = 1, b = 2}. This option is turned on by default for some interpreters and can be explicitly enabled using debugger.redirect configuration option.

This is all good, but what if you have a long running process and want to be able to use this "remote" printing as a log file. The plugin below allows you to do just that: it will dump all the "remote" output to a file (output.log by default) in the current project folder. It also limits the number of records in the Output window (100 by default) to allow you to generate a large number of records without taking more memory.

Continue reading Saving debugging output to a file

Lua ecosystem has two package managers: LuaDist and LuaRocks. Both managers allow users to install Lua and C modules and work on Windows, Mac OS X and Linux, but have some important differences in how they operate, which I'll briefly go over.


  • Unified build system for all modules based on CMake.
  • Mixed binary/source distribution that allows to use whatever dependency is available in the repository.
  • Everything is stored in git (using github as host) including the repository manifest. Tags are used for versions and branches for binary distributions.
  • Provides "batteries included" binary distributions (as a successor to Lua for Windows).
  • Relies on few Lua modules (luasocket, lfs, lua-git) for its implementation.
  • Allows for building the modules manually without using LuaDist.
  • Can be used from a command line or as a library (local ld = require "dist"; ld.install("luaexpat"))
  • Uses dist.info files for package specification information (mostly for dependency tracking, no build information).
  • Provides support for packaging modules for distribution.
  • Includes about 260 projects (as of November 2013; based on the number of sub-modules in the repository).
  • Includes a good number of pre-compiled binaries for Windows, but many for outdated module versions.


  • Supports local and remote repositories.
  • Distributed as a Lua scripts without dependencies, but relies on Unix tools for module deployment and installation.
  • Uses .rockspec files as a package specification file.
  • Uses "native" build instructions for each rock.
  • Includes rocks for 330 projects (as of November 2013).
  • Have several repositories: main one with manual curation and rocks.moonscript repository that supports (non-curated) rock submission and download statistics.

As we are talking about Lua module distribution, I'll also mention a nice project of Pierre Chapuis: lua toolbox. It provides a list of modules with short descriptions and their endorsement by various users (along with a simple tagging mechanism).

Both systems are easy to use as command-line tools. When you have one of the package managers installed, it's a matter of running luarocks install module or luadist install module commands to get the modules you need (assuming you have the tools available and don't run into compilation issues). It is certainly possible to setup LuaDist and LuaRocks to deploy modules to the directories you need and make those directories available to your project (see for example this nice write up by Thijs Schreijer on Setting up Lua installation on Windows using Lua Rocks and ZeroBrane Studio), but I'd prefer to have something simpler for users who may be new to programming and Lua.

I teach a semester long computer science class at a local high school during summer (using Lua and ZeroBrane Studio) and sometimes want to install Lua modules like penlight to my students' computers and use them from ZeroBrane Studio. I have 18 students using their own laptops running different systems and want to be able to say "install penlight" and then make "require 'pl.strict'" to work in their Lua scripts. The coming version (v0.40) of ZeroBrane Studio (and the current master branch) integrates with LuaDist and allows you to do just that.

Continue reading Lua package managers and integration with ZeroBrane Studio

After ZeroBrane Studio for Vera was released, I received several questions whether it is possible to load files from the device and edit them. The product already allows to upload files to Vera devices and to download log files, but it doesn't support editing of remote files and I thought it would be useful and interesting to implement this.

What you see below is the plugin that does just that. It adds a new menu item (File | Open Remotely...) that asks for a file name and then loads that file in a new editor tab. You can edit and save that file as you'd do with any other file. The main difference is that it only works when a debugging session is in progress as it uses the debugging mechanism to retrieve and save the files.

Continue reading Remote file editing while debugging

ZeroBrane Studio has already been used to debug Lua in various applications, from game engines to medical systems. Several months ago one of the ZeroBrane Studio users asked if it would be possible to debug Lua application running on Vera home automation devices. It turned out to be possible, but not trivial and I decided to release this integration as a separate product that allows Vera users to debug their Lua applications while they are running on Vera devices.

These devices look like network routers with additional functionality to control various devices and access sensors using z-wave protocol. This integration allows you to write a Lua script that may start a sprinkler system at a specific time, but only if it wasn't raining that day. Or to turn lights on when a motion detector is triggered. Or to turn the heating system on before you come home. You can probably come up with many other interesting uses that are only limited by the devices you may have (and your budget).

As you can see in the demo (you may want to switch to 720p for better quality), ZeroBrane Studio for Vera allows Vera users to not only debug their Lua scripts, but also provides auto-complete for luup (Lua Universal PnP API) calls, ability to upload files and download logs, restart the Lua engine and some other device-specific functions.

The documentation page for the project provides links to Vera resources and detailed descriptions for debugging of Lua scripts started the IDE and scripts in plugins and scenes that are triggered from the device itself.

ZeroBrane LLC, the company behind ZeroBrane Studio, has applied for a small business grant from Chase. We now need 250 votes to get to the second round where applications are being considered by a panel of judges and would appreciate your help.

Please cast your vote and spread the word to help us be considered for the grant! The grant will allow us to provide more educational content, enable collaborative editing, add version control integration, and more.

The voting is only available through Facebook Connect; if you don't see your vote accepted, try enabling popups and disabling Facebook filters you may have. Thank you!

It's expected to be able to watch an expression in the debugger and ZeroBrane Studio provides that functionality. You can specify an expression and it will be evaluated when the application is stopped in the debugger.

This is all good, but the application needs to be stopped to refresh the values and there are situations when you want to see the values while your application is running. ZeroBrane Studio supports redirecting of program output to the Output window in the IDE (when debugging) and (with a bit of magic) this can be leveraged to send the values you want to appear in the Watch window.

What does it give you? You can then include in your code print statements of the form print("foo=", someValue) and print("bar=", someOtherValue) and those values will be shown in the Watch window as foo and bar. The values can be complex values that will be pretty-printed for you (this is the same functionality that "prints" complex values to the Output window during debugging). For example, the script below will show values for a, b, c, and d as defined in the print expressions:

for i = 1, 1000 do
  print("a=", {i, i*2})
  if 0 == i % 10 then print("b=", {i, i*3}, collectgarbage("count")) end
  if 0 == i % 100 then print("c=", {i, i*4}, os.clock()) end
  print("d=", math.random())

Since the "printed" output is sent over sockets, this also works when you debug your application remotely, for example, when you debug something running on a mobile device from ZeroBrane Studio running on a desktop.

For simple values (like d in the example above) the plugin will also calculate min, max, avg, and count values. The result may look similar to this (if you run it you will see that the numbers are updated while your app is running):

Here is the plugin code; you can save it into packages/ folder in the ZeroBrane Studio folder as realtimewatch.lua and restart the IDE.

The latest version of ZeroBrane Studio includes several recent updates: LuaJIT is now a default interpreter instead of Lua 5.1, Lua 5.2 is included for all supported platforms (just select "Lua 5.2" from the list of interpreters), and luasocket has been upgraded to v3.0.

Note that "normal" Lua5.1 interpreter is no longer included, but as before you can continue using the IDE to debug your Lua 5.1 applications (you can also use your own Lua 5.1 interpreter if you want).

LuaJIT is compiled with LUAJIT_ENABLE_LUA52COMPAT, which enables some of Lua5.2 features (see this link for details) and allows to do syntax checks for "goto" and other features. The local console is using LuaJIT as well.

All these changes are going to be included in the coming release (0.39), so please report any issues or incompatibilities you notice.

Note that while Lua 5.2 (and luasocket compiled against Lua 5.2) are included, you may still run into issues if you debug your own Lua 5.2 applications that statically link the interpreter (at least on Windows). The reason for that is that when you load luasocket, it loads lua52.dll and you end up with multiple VMs (and may get "PANIC: unprotected error in call to Lua API (multiple Lua VMs detected)" message). There are (at least) two ways to resolve this: (1) compile luasocket into your app the same way you include lua interpreter itself; you won't need anything else except one mobdebug.lua file to debug your app, or (2) use proxy dll; it will look like lua52.dll, but will actually proxy your calls to your statically compiled lua library, avoiding problems with multiple VMs. The proxy dll is for Lua 5.1, but you can tweak the script to make it work for Lua 5.2. See this SO answer for related discussion.

I received several questions about whether it's possible to add ability to see the same file in different editor tabs in ZeroBrane Studio and thought it would be a good test for the current plugin interface.

The Scintilla editor component that is used in ZeroBrane Studio includes a nice feature that allows two editors to share the same document, with changes made in one editor being immediately seen in the other one. The code is very simple ('e1' is the editor you are cloning and 'e2' is the new editor):

 local docpointer = e1:GetDocPointer()

I wrapped this code in a plugin that allows users to clone an editor tab vertically or horizontally. Save this plugin as cloneview.lua to packages/ folder, restart ZeroBrane Studio, and right click on one of editor tabs to select 'Clone Vertically' and 'Clone Horizontally'.

return {
  name = "Clone view plugin",
  description = "Clones the current editor tab.",
  author = "Paul Kulchenko",
  version = 0.11,

  onMenuEditorTab = function(self, menu, notebook, event, index)
    local idvert = ID(self.fname..".clone.vert")
    local idhorz = ID(self.fname..".clone.horz")

    local cloner = function(event)
      local e1 = ide:GetEditor(index)
      local e2 = NewFile("clone: "..ide:GetDocument(e1):GetFileName())
      local docpointer = e1:GetDocPointer()
        event:GetId() == idhorz and wx.wxRIGHT or wx.wxBOTTOM)

    menu:Append(idhorz, "Clone Horizontally")
    menu:Append(idvert, "Clone Vertically")
    notebook:Connect(idvert, wx.wxEVT_COMMAND_MENU_SELECTED, cloner)
    notebook:Connect(idhorz, wx.wxEVT_COMMAND_MENU_SELECTED, cloner)

[Updated on 09/21/2013] The plugin code has been updated to use index parameter that refers to a correct index in split notebook situations. This functionality requires using v0.39 of ZeroBrane Studio (when released) or the current master.

There has been recent interest in getting ZeroBrane Studio to work with Cocos2d-x, so I decided to put my notes together on how this can be accomplished.

Debugging with ZeroBrane Studio requires using luasocket and because it can be integrated with a Cocos2d-x project in different ways, you may have several options to consider.

Continue reading Cocos2d-x simulator and on-device debugging with ZeroBrane Studio

[Update 10/18/2013] The bounty was for a specific issue with ZeroBrane Studio IDE (as documented below) and not for any problem related to this website.

[Update 10/04/2013] The bounty has been withdrawn as the issue appears to be fixed. If you can still reproduce it with the current master, please leave a comment.

Bug bounty programs are nothing new; Google, Mozilla, Microsoft and many others use them to find security vulnerabilities and bugs (and these program are reported to be cost effective). There has been an issue in ZeroBrane Studio that have been bugging me for almost two months, so I decided to offer a bounty for it.

I offer $250 dollars to the first person who can figure out what's causing the bug and I'll add $150 if you can provide a fix for it (so $400 USD total for a fix), payable via PayPal or as an Amazon giftcard. All the source code for ZeroBrane Studio is available on github and the code for wxwidgets and wxlua is available as well.

The details of the crash as well as associated stack traces are available in this ticket. Please use the ticket for discussion.

The bug only happens under Windows 7 64bit. I have received several reports of the same crash happening on different computers, all running Windows 7 64bit. I also have several users who use the same system, but have never experienced this crash. The crash most likely happens when typing text and is likely to be related to auto-complete, but I have so far been unable to reproduce it.

There are some strange things showing up on the stack trace that I've discussed with John Labenski (the author of wxlua). I can provide wx.dll built with debug information (it's rather large, 186M) or you can build one yourself using this build script (run it as bash build-win32.sh wxwidgets lua wxlua debug). Note that you don't need to build anything else and can run ZeroBrane Studio from a cloned repository.

The fix has to include code that can be applied to ZeroBrane Studio or upstream (wxlua or wxwidgets) to eliminate the issue. The bounty will not be awarded if it is illegal to do so.

ZeroBrane Studio is now available in seven languages! Thanks to all who contributed translations:

Starting from v0.38 ZeroBrane Studio includes experimental support for scope aware variable indicators. These indicators are added to mark local, global, masked, and masking variables and are calculated in real-time as the code is being written. Having this ability changes the way you write code, and does catch a lot of errors and 'wrong thinking' cases.

ZeroBrane Studio provides default indicators that can be updated; both the colors and the appearance can be changed as described in the documentation. For example, styles.indicator.varmasked = nil will disable masked indicator.

In addition to providing real-time indicators, the IDE uses the same mechanism to provide "Go To Definition" and "Rename All Instances" options available from the popup menu in the editor. The items in the popup menu also show the number of instances detected and the line where the definition is found. "Go To Definition" item is enabled for local variables/functions, function parameters, and loop variables.

You can quickly select instances of a variable by doing Ctrl/Cmd-DblClick on it. All instances get selected with the main one having slightly darker background and can be edited to update the name. In addition to that you can navigate selected instances using Find Next/F3 and Find Previous/Shift-F3; it will move the selection to the next/previous instance (and scroll the editor to make it visible).

From its very first version ZeroBrane Studio supported debugging of embedded Lua code; it was only a matter of adding require('mobdebug').start() (when running on the same computer) and it would start a debugging session in the IDE.

There was one case though when it didn't work: if the environment that loads some Lua code doesn't provide a file name, the IDE doesn't have information about what resource to load for debugging. The simplest example to see this to try to try to do something like loadstring("print(1); print(2)"). When this code is executed under the debugger, the source of this code is shown as print(1); print(2). One workaround for this was to specify the second parameter to loadstring: chunkname, which is then used by the Lua debug interface where it reports the source.

This workaround only works when you can modify the fragment that loads Lua code and in those cases where this is not an option (for example, when you need to use luaL_loadstring, which provides no way to label the chunk with its file path) you were out of luck.

This situation has changed now. Starting from v0.38, ZeroBrane Studio provides a way to debug these code chunks without any additional configuration. When it gets a request that has a code fragment instead of a file name as its source, it will try to find an open editor with the content that matches that source and if there is no match will open a new editor and load the fragment in it.

This allows to use the debugger to "step into" calls to functions returned by loadstring and also debug Lua scripts executed in environments like LuaJava. You can also look at the stack trace, set breakpoints, and use local console as you can normally do in the debugger.

Recent Comments


I am Paul Kulchenko.
I live in Kirkland, WA with my wife and three kids.
I do consulting as a software developer.
I study robotics and artificial intelligence.
I write books and open-source software.
I teach introductory computer science.
I develop a slick Lua IDE and debugger.