Debugging Plugins

Sometimes things do not go right. Even experienced developers are not protected from logical errors and typos. It can be tricky to grasp the problem with proper debugging tooling. In this chapter I will explain a few ways of debugging Marta plugins.

Runtime Errors

Let’s start with a trivial example:

plugin { ... }

local function hello()
    martax.alert("Hello!")
end

action {
    id = "my.action",
    name = "My action",
    apply = function(context)
        hallo()
    end
}

As you probably noticed, this action will not show the “Hello” alert. We tried to call hello(), but accidentally called hallo() which we didn’t define. However, Marta shows no error messages when an action is executed. So where we can find one?

In fact, macOS ships with a Console application, which is basically a log viewer. Marta puts messages to the system log, so you can find them in the Console. E.g., for the action above, Marta will post a log message like this:

'apply()' failed for action marta.example.error.my.action: [string "my.lua"]:15: attempt to call a nil value (global 'hallo')
stack traceback:
    [C]: in global 'hallo'
    [string "my.lua"]:15: in function <[string "my.lua"]:14>

Here you can find the appeared on the 15th line of the “my.lua” file. In essense, Lua resolved the global hallo to nil – this means there is no such a global. Also, Lua does not allow calling nil values, so we got an error.

The alternative way of viewing error messages is to run Marta binary from the terminal:

/Applications/Marta.app/Contents/MacOS/Marta

All diagnostic messages will appear directly in the terminal session.

Debug Prints

Printing out intermediate values is the easiest way of finding the problem. Marta redirects output of the built-in print() and error() functions to the Console:

action {
    id = "my.action",
    name = "My action",
    apply = function(context)
        print("Hello, world!")
    end
}

The action above will print the “Hello, world!” message to the log.

MobDebug

Marta embeds MobDebug, a fully-functional remote debugger for Lua. ZeroBrane Studio IDE supports MobDebug out-of-the-box. Here is how to debug the plugin:

  1. Add marta.mobdebug() (or just mobdebug() for a single-file plugin) to the very beginning of your plugin code.
  2. Start ZeroBrane Studio, open ~/Library/Application Support/org.yanex.marta/Plugins as a project directory. Open your plugin file there.
  3. Choose “Project” → “Start Debugger Server” in the application menu. The “Debugger server started at <…>” message should appear in the Output toolbar.
  4. Start Marta. You will notice that the application does not start immediately, as the debugger intercepted its loading. Go back to ZeroBrane, put some breakpoints and press “Start or continue debugging (F5)”.

The default MobDebug port number is 8172. You can specify any other port explicitly:

marta.mobdebug(4321)

See the Remote debugging article on the ZeroBrane Studio website for more information.