Jump to: navigation, search

Difference between revisions of "Koneki/LDT/User Guide/Concepts/Debugger"

< Koneki‎ | LDT‎ | User Guide‎ | Concepts
m (spelling)
(DBGp Client)
(4 intermediate revisions by 2 users not shown)
Line 3: Line 3:
 
== Remote Debug  ==
 
== Remote Debug  ==
  
The Debugger of Lua Development Tools is based on the DBGP protocol.<br> The IDE contains a DBGP server. To connect to this server, and begin remote/attach debugging, you need to get our [[Media:Debugger_lua.zip|DBGP Lua client]].  
+
The Debugger of Lua Development Tools is based on the DBGp protocol.<br> The IDE contains a DBGp server. To connect to this server, and begin remote/attach debugging, you need to get our [[Media:Debugger_lua.zip|DBGp Lua client]].  
  
=== DBGP Client  ===
+
=== DBGp Client  ===
  
The DBGP Lua client is composed of two Lua files ([http://git.eclipse.org/c/koneki/org.eclipse.koneki.ldt.git/plain/plugins/org.eclipse.koneki.ldt.debug.core/script/debugger.lua debugger.lua] and [http://git.eclipse.org/c/koneki/org.eclipse.koneki.ldt.git/plain/plugins/org.eclipse.koneki.ldt.debug.core/script/debugintrospection.lua debugintrospection.lua]).<br> It runs on Unix-like OS and Windows (XP and later). It is written in '''Lua 5.1''' and '''depends on lua-socket'''.<br> ''You can get Lua on http://www.lua.org/download.html and install lua-socket thanks to [http://luarocks.org/en/Download luarocks], or via your official OS repositories.''<br>  
+
The DBGp Lua client is composed of two Lua files ([http://git.eclipse.org/c/koneki/org.eclipse.koneki.ldt.git/plain/libraries/luadbgpclient/debugger.lua debugger.lua] and [http://git.eclipse.org/c/koneki/org.eclipse.koneki.ldt.git/plain/libraries/luadbgpclient/debugintrospection.lua debugintrospection.lua]).<br> It runs on Unix-like OS and Windows (XP and later). It is written in '''Lua 5.1''' and '''depends on lua-socket'''.<br> ''You can get Lua on http://www.lua.org/download.html and install lua-socket thanks to [http://luarocks.org/en/Download luarocks], or via your official OS repositories.''<br>  
  
 
To use it, you must have these two files in your lua path.<br> To begin the connection, you must execute this Lua code&nbsp;:  
 
To use it, you must have these two files in your lua path.<br> To begin the connection, you must execute this Lua code&nbsp;:  
Line 18: Line 18:
 
  &gt; require("debugger")(host, port, idekey)
 
  &gt; require("debugger")(host, port, idekey)
  
*'''host''': the host name or the IP address of the DBGP server (thus, of your IDE).  
+
*'''host''': the host name or the IP address of the DBGp server (thus, of your IDE).  
 
**if host is nil, the DBGP_IDEHOST environment variable is used.  
 
**if host is nil, the DBGP_IDEHOST environment variable is used.  
 
**if the environment variable is nil, the default value '127.0.0.1' is used.  
 
**if the environment variable is nil, the default value '127.0.0.1' is used.  
*'''port''': the port of the DBGP server (must be configured in the IDE).  
+
*'''port''': the port of the DBGp server (must be configured in the IDE).  
 
**if port is nil, the DBGP_IDEPORT environment variable is used.  
 
**if port is nil, the DBGP_IDEPORT environment variable is used.  
 
**if the environment variable is nil, the default value '10000' is used.  
 
**if the environment variable is nil, the default value '10000' is used.  
Line 30: Line 30:
 
So, To debug your application you could do&nbsp;:  
 
So, To debug your application you could do&nbsp;:  
  
  lua -e "require('debugger')("idehost","ideport");" MyApp.lua  
+
  lua -e "require('debugger')("idehost","ideport");" MyApp.lua
  
=== DBGP Server  ===
+
=== DBGp Server  ===
  
The DBGP Server is integrated in LDT.<br> In order to accept incoming debug sessions, you must create a new '''Remote Lua Application''' launch configuration, then launch it.  
+
The DBGp Server is integrated in LDT.<br> In order to accept incoming debug sessions, you must create a new '''Remote Lua Application''' launch configuration, then launch it.  
  
 
Go in '''Run/Debug Configurations...'''. [[Image:LaunchConfiguration.png|center]]<br>  
 
Go in '''Run/Debug Configurations...'''. [[Image:LaunchConfiguration.png|center]]<br>  
Line 40: Line 40:
 
*'''Project'''&nbsp;: Set the LDT project in your workspace which includes the Lua source file(s) of the application you want to debug. <br>  
 
*'''Project'''&nbsp;: Set the LDT project in your workspace which includes the Lua source file(s) of the application you want to debug. <br>  
 
*'''IdeKey'''&nbsp;: Default value is luaidekey, if you need to debug more than one application at the same time, you should change it to associate a launch configuration with only one application to debug.<br>  
 
*'''IdeKey'''&nbsp;: Default value is luaidekey, if you need to debug more than one application at the same time, you should change it to associate a launch configuration with only one application to debug.<br>  
*'''Source Mapping'''&nbsp;: Define a common way for DBGP Server (IDE) and DBGP Client (running application) to identify source file. There are several strategy, each more or less adapted to a specific used case. To better understand it, see the [[#Source Mapping |advanced documentation]] on it.  
+
*'''Source Mapping'''&nbsp;: Define a common way for DBGp Server (IDE) and DBGp Client (running application) to identify source file. There are several strategy, each more or less adapted to a specific used case. To better understand it, see the [[#Source Mapping |advanced documentation]] on it.  
  
 
<br> Now you can start your debug session by clicking '''Debug'''. IDE will wait for an incoming connection from the debugger client, on the port you can see in the debug view.<br> [[Image:DebugView.png|center]]  
 
<br> Now you can start your debug session by clicking '''Debug'''. IDE will wait for an incoming connection from the debugger client, on the port you can see in the debug view.<br> [[Image:DebugView.png|center]]  
Line 88: Line 88:
 
[[Image:Dbg-repl.png|frame|center|The interactive console allows you to type statements under the local scope]]  
 
[[Image:Dbg-repl.png|frame|center|The interactive console allows you to type statements under the local scope]]  
  
{{Warning|Always on top level|Due to a limitation from DBGP protocol, the interactive console and expressions are always mapped to the top stack frame !}}  
+
{{Warning|Always on top level|Due to a limitation from DBGp protocol, the interactive console and expressions are always mapped to the top stack frame !}}  
  
 
==== Source Mapping  ====
 
==== Source Mapping  ====
The DBGP Server (IDE) and the DBGP client (running application) need to communicate about source files.<br/>
+
The DBGp Server (IDE) and the DBGp client (running application) need to communicate about source files.<br/>
 
''E.g. When you set a breakpoint, the IDE need to say to the running application on which file the breakpoint must be added.''<br/>
 
''E.g. When you set a breakpoint, the IDE need to say to the running application on which file the breakpoint must be added.''<br/>
 
''E.g. When the running application stops on a breakpoint of a file, the IDE must retrieve the file and open it.''<br/>
 
''E.g. When the running application stops on a breakpoint of a file, the IDE must retrieve the file and open it.''<br/>
Line 101: Line 101:
 
   
 
   
 
* '''Local Resolution'''
 
* '''Local Resolution'''
This way to resolve the source mapping is the more simple and the more reliable. Both client and server works with absolute path. The IDE will search only in its buildpath a file which have the given absolute path. This means that executed file should be in your workspace (in your buildpath more exactly). So you can not use it to debug code on a remote host.
+
This way to resolve the source mapping is the more simple and the more reliable. Both client and server works with absolute path. The IDE will search first in its buildpath, then in the whole workspace, a file that has the given absolute path. This means that executed file should be in your workspace. So you can not use it to debug code on a remote host.
  
 
* '''Module Resolution'''
 
* '''Module Resolution'''
Line 124: Line 124:
 
On windows, you should prefix your path with "/" (e.g. /C:/foo/bar/)
 
On windows, you should prefix your path with "/" (e.g. /C:/foo/bar/)
  
'''In all case, if file is not found in the workspace, the source code is sent via the DBGP protocol'''
+
'''In all case, if file is not found in the workspace, the source code is sent via the DBGp protocol'''
  
 
=== Unsupported features  ===
 
=== Unsupported features  ===

Revision as of 04:03, 16 October 2012

Lua Development Tools Debugger

Remote Debug

The Debugger of Lua Development Tools is based on the DBGp protocol.
The IDE contains a DBGp server. To connect to this server, and begin remote/attach debugging, you need to get our DBGp Lua client.

DBGp Client

The DBGp Lua client is composed of two Lua files (debugger.lua and debugintrospection.lua).
It runs on Unix-like OS and Windows (XP and later). It is written in Lua 5.1 and depends on lua-socket.
You can get Lua on http://www.lua.org/download.html and install lua-socket thanks to luarocks, or via your official OS repositories.

To use it, you must have these two files in your lua path.
To begin the connection, you must execute this Lua code :

> local initconnection = require("debugger")
> initconnection(host, port, idekey)

or shortly

> require("debugger")(host, port, idekey)
  • host: the host name or the IP address of the DBGp server (thus, of your IDE).
    • if host is nil, the DBGP_IDEHOST environment variable is used.
    • if the environment variable is nil, the default value '127.0.0.1' is used.
  • port: the port of the DBGp server (must be configured in the IDE).
    • if port is nil, the DBGP_IDEPORT environment variable is used.
    • if the environment variable is nil, the default value '10000' is used.
  • idekey: a string which is used as session key (must be configured in the IDE).
    • if IDEKEY is nil, the DBGP_IDEKEY environment variable is used.
    • if the environment variable is nil, the default value 'luaidekey' is used.

So, To debug your application you could do :

lua -e "require('debugger')("idehost","ideport");" MyApp.lua

DBGp Server

The DBGp Server is integrated in LDT.
In order to accept incoming debug sessions, you must create a new Remote Lua Application launch configuration, then launch it.

Go in Run/Debug Configurations....
LaunchConfiguration.png

  • Project : Set the LDT project in your workspace which includes the Lua source file(s) of the application you want to debug.
  • IdeKey : Default value is luaidekey, if you need to debug more than one application at the same time, you should change it to associate a launch configuration with only one application to debug.
  • Source Mapping : Define a common way for DBGp Server (IDE) and DBGp Client (running application) to identify source file. There are several strategy, each more or less adapted to a specific used case. To better understand it, see the advanced documentation on it.

Now you can start your debug session by clicking Debug. IDE will wait for an incoming connection from the debugger client, on the port you can see in the debug view.
DebugView.png
If needed, you can change the server port, in Window > Preferences > Dynamic Languages > Debug.
DebugUI.png

Debug features

Supported features

Breakpoints, code navigation

You can set breakpoints at a particular file/line, you can do it with the regular double-click on margin:

Dbg-setbreakpoint.png

You can then specify some conditions to stop execution only under certain circumstances:

Dbg-openproperties.png
Dbg-properties.png
  1. Enable or disable breakpoint globally
  2. Condition on hit count (stop only after 3rd hit, each 4 reaches, ...)
  3. Conditional breakpoint: you can put any expression, it will be evaluated in the local scope each time breakpoint is reached and break only when expression is evaluated to true.

Once a breakpoint has been reached and breaks, you can use usual step into, step over and step out commands.

Idea.png
Coroutine handling
When the current instruction is a coroutine.yield or a coroutine.resume step over will jump over the coroutine until the next resume or yield whereas step into will go into the coroutine and re-break as soon as possible.


Environment inspection

When a breakpoint is reached, you can see any variable visible from any stack frame (local, upvalue and global variables). You can also change values to another.

Dbg-variables.png
Idea.png
New values are expressions
When you set a new value, it is evaluated as expression, so math.sqrt will be evaluated to a function, if you want to put a literal string, use Lua syntax: "math.sqrt". In particular you can change an entire table by another table expression. This is sometimes powerful and sometimes dangerous, be careful with that.


Some special values can also be displayed such as metatables or function environments (if it is different from global environment). You can also change these values.

Interactive console and expressions

In addition to variable view, you have two other useful tools to evaluate some code snippets: expressions view and interactive console.

The expressions view allows you to re-evaluate complex expressions at each step
The interactive console allows you to type statements under the local scope
Warning2.png
Always on top level
Due to a limitation from DBGp protocol, the interactive console and expressions are always mapped to the top stack frame !


Source Mapping

The DBGp Server (IDE) and the DBGp client (running application) need to communicate about source files.
E.g. When you set a breakpoint, the IDE need to say to the running application on which file the breakpoint must be added.
E.g. When the running application stops on a breakpoint of a file, the IDE must retrieve the file and open it.

The problem is that the file executed in your Lua VM could be physically different than the source file in your IDE (in your workspace). For example, in the case where your code is executed on a different host or just if your executed code is duplicated in another folder.

To resolve this problem, LDT proposes to you different strategies, each with advantages and drawbacks :

  • Local Resolution

This way to resolve the source mapping is the more simple and the more reliable. Both client and server works with absolute path. The IDE will search first in its buildpath, then in the whole workspace, a file that has the given absolute path. This means that executed file should be in your workspace. So you can not use it to debug code on a remote host.

  • Module Resolution

Both IDE and application have their own way to retrieve a module from its name. So we could use the module name has file ID instead of path. With this mode, you could do remote debugging without settin a list of path mapping. The limitation is that you should use the standard lua_path way to load module. Another problem is that we could not really retrieve the module name at client side, because the Lua debug api uses source path. The module name is retrieved from the path (from debug.getinfo) and the lua_path (package.path). so with ambiguous lua_path you could have insolvable conflict.
E.g: with package.path = "/foo/bar/?.lua, /foo/?.lua" and debug.getinfo="@/foo/bar/baz.lua" the possible module name is bar.baz or baz
There are no way to know the real module name, in this case the debugger will use the shorter one, but the ideal is to avoid ambiguous lua_path with this mode.

  • Replace path Resolution

This mode is a fallback. If the two previous one don't fit your needs, you could try it. In this mode, client talks with absolute path and server (IDE) uses relative path (relative to the buildpath). A path must be set in launchconfiguration to move from one world to another.

e.g: You set path with "/foo/bar/".
when file path is sent from client (/foo/bar/baz/qux.lua), path will be removed (baz/qux.lua) and a file with this relative path will be searched in your buildpath.
when file path is sent from server (baz/qux.lua), path will be add (/foo/bar/baz/qux.lua) and the absolute path will be sent to the client

The problem is that you could set only one path.
The path comparison is case sensitive (even on windows).
On windows, you should prefix your path with "/" (e.g. /C:/foo/bar/)

In all case, if file is not found in the workspace, the source code is sent via the DBGp protocol

Unsupported features

The dynamic code is not supported, it means that any code that is loaded with load, loadstring will not be supported. The debugger will step over it just like a C function.

The only well tested virtual machine is Lua 5.1. Any other implementation (Lua 5.2, LuaJIT[1], ...) is not guaranteed to work at this time.

References:
  1. http://lua-users.org/lists/lua-l/2011-11/msg00583.html