Debugging OpenResty and Nginx Lua scripts with Zer

ZeroBrane

By seeking, you will discover...

 

Subscribe

Debugging OpenResty and Nginx Lua scripts with ZeroBrane Studio

12 MAY 2014

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

You should get a copy of my slick ZeroBrane Studio IDE and follow me on twitter here.

Posted by Paul Kulchenko on Monday, May 12, 2014 at 9:22 PM

Filed in zerobrane | Tagged ideluanginxopenrestyzerobrane

Related Entries

10 Comments

Hi Paul, I've tried debugging in linux as your guide, but could not make it work. After I made a request to http://localhost/hellolua, I got an error log in nginx's error.log, "[error] 23503#0: *22 lua entry thread aborted: runtime error: attempt to yield across C-call boundary" and nginx ended the request with a "500 Internal Server Error" response. It seemed that the luasocket which mobdebug is using produced the error. I was using openresty-1.5.8(with the bunlded LuaJIT-2.1-20140109) and zbstudio-0.60 in SuSE Linux, I also tried in Ubuntu 12.10 using openresty-1.5.12 and zbstudio-0.60 and got the same error. Did I miss somthing? Any suggestion? Any help would be greatly appreciated!

LiuJun | June 10, 2014 7:28 PM | Reply

Hi LiuJun, I initially got the same error -- "attempt to yield across C-call boundary" -- and this is why I switched to using "blocking" luasocket, as this is needed for the debugger. Is it possible that in your case you use a nonblocking luasocket that comes with OpenResty?

Try removing references to "luapackagecpath" and replacing the content of content.lua with something like: "print(1) require 'socket' print(2)". This should fail if luasocket is indeed unavailable. If it does correctly reference the version from ZeroBrane Studio, I don't see why it would fail, but I haven't tested it on Linux. I'll try to set it up on my VM to see if I can reproduce this issue.

Paul Kulchenko replied to comment from LiuJun | June 10, 2014 9:36 PM | Reply

I removed the zbstudio's clibs path from lua_package_cpath as you suggested, and got the following error when require "socket":

"[error] 10473#0: *29 lua entry thread aborted: runtime error: /opt/zbstudio/lualibs/socket.lua:12: module 'socket.core' not found:"

So I think the lua script was using luasocket from zbstudio, not from openresty.

LiuJun | June 11, 2014 3:11 AM | Reply

LiuJun, you seem to be doing everything correctly and the results are as expected. I'll have to try it myself on Linux to see what may be going on (in a day or two).

Paul Kulchenko replied to comment from LiuJun | June 11, 2014 10:44 PM | Reply

LiuJun, I can confirm the same issue. I tried on Ubuntu 12.04 using the latest OpenResty (1.7.0.1) and got the same error. I don't have a good explanation for you and am working on a test case. Drop me an email (my address is at the bottom of the page) and I'll send you an update when I figure out what may be going on. Paul.

Paul Kulchenko replied to comment from LiuJun | June 14, 2014 4:06 PM | Reply

LiuJun, you need to add "coroutine = require('coroutine')" before "start()" call. It seems like openresty on Linux is using "lightweight threads" instead of "default" coroutines and those interfere with debugging as they are managed by ngx_lua. Paul.

Paul Kulchenko replied to comment from LiuJun | June 15, 2014 10:10 AM | Reply

It works smoothly now. Thank you very much.

LiuJun replied to comment from Paul Kulchenko | June 16, 2014 9:26 PM | Reply

LiuJun, glad it's working for you. The workaround I suggested earlier is likely not to work in the coming version of OpenResty. This issue should be fixed in the current master branch of ZeroBrane Studio; please check that version as it uses updated debugger, which doesn't require any workarounds.

Paul Kulchenko replied to comment from LiuJun | June 17, 2014 9:18 PM | Reply

Hi Paul, I'm trying to get the remote debugging going and seem to have trouble getting the two boxes to communicate. The actual server is an AWS Ubuntu box and the studio is running locally on my windows machine. Essentially, it looks like the script simply gives up a few minutes after I refresh the page (displays the following without ever reaching the studio running on my machine): "Hello, Anonymous! Done debugging." Is there any specific port or range of ports I need to open up to get this going, do you know? Thank you very much!!

Ilya | August 9, 2014 12:16 PM | Reply

Hi Ilya, per our email exchange, you should make sure the (default) port 8172 is open on your computer running the IDE as this is the port that is used for debugging. Also make sure that "require('mobdebug').start('IP-address-of-ZBS')" call includes the IP address of the machine that runs ZeroBrane Studio. This should resolve the issue.

Paul Kulchenko replied to comment from Ilya | August 30, 2014 11:36 AM | Reply


转载于:https://my.oschina.net/epiclight/blog/424472

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值