Debugging OpenResty and Nginx Lua scripts with ZeroBrane Studio

from  http://notebook.kulchenko.com/zerobrane/debugging-openresty-nginx-lua-scripts-with-zerobrane-studio

ZeroBrane Studio has already been used to debug various Lua engines -- game frameworks (like CoronaGiderosMoaiLove2d), home automation deviceswireshark scriptsAdobe 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:

require('mobdebug').start('192.168.1.22')
local name = ngx.var.arg_name or "Anonymous"
ngx.say("Hello, ", name, "!")
ngx.say("Done debugging.")
require('mobdebug').done()

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 192.168.1.22).

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.

OpenResty configuration for remote debugging.

The following steps are only needed if you configure OpenResty/Nginx for remote debugging when Nginx runs on one machine and ZeroBrane Studio runs on another one. When you run both on the same machine, Nginx is using modules included with ZeroBrane Studio as those are referenced by lua_package_path and lua_package_cpath directives.

1. Copy the debugger (mobdebug.lua) and socket files. Go to <ZBS>/lualibs/mobdebug/ and copy mobdebug.lua to <NGINX>/lua/mobdebug.lua; also copy <ZBS>/lualibs/socket.lua to <NGINX>/lua/. After all this is done, the content of lua folder is going to look like this:

./
content.lua
mobdebug.lua
socket.lua

2. Copy <ZBS>/bin/clibs/socket/core.dll to <NGINX>/socket/core.dll (core.dylib and core.so files are in the bin folder as well).

posted @ 2017-01-10 18:42  princessd8251  阅读(702)  评论(0)    收藏  举报