(Some gdb-compatible aliases have been added.)
Suppose you want to debug the following short program:
# ./y2base test2.ycp qt { list cpu = SCR(`Read(.probe.cpu)); list hosts = SCR(`Read(.etc.hosts)); UI(``{ OpenDialog(`PushButton("Hello World!")); UserInput(); CloseDialog(); }); float pi = 3.141; }
So first we have to set Y2DEBUGGER and start y2base:
-> export Y2DEBUGGER 2 -> y2base test2.ycp qt waiting for debugger frontend to connect
As you can see, the interpreter is waiting for the frontend to connect. We will use telnet as a frontend:
-> telnet localhost 19473 Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. Welcome to the YCP debugger. interpreter: #0 wfm 0 position: /suse/arvin/yast2/debugger/test2.ycp 0
We are connected to the ycp debugger. The last line shows us the position in the source code: filename and linenumber. Don't wonder about the linenumber of 0, it hasn't been initialized yet. The line above tells us which interpreter is currently active: It is the wfm interpreter with the unique number 0.
First we want to get a listing of the source code:
list source BEGIN SOURCE # ./y2base test2.ycp qt { list cpu = SCR(`Read(.probe.cpu)); list hosts = SCR(`Read(.etc.hosts)); UI(``{ OpenDialog(`PushButton("Hello World!")); UserInput(); CloseDialog(); }); float pi = 3.141; } END SOURCEThe source code is surrounded by BEGIN SOURCE / END SOURCE lines. This is mainly to simplify parsing for (intelligent?) frontends. Now we can step a bit through the code:
step interpreter: #0 wfm 1 position: /suse/arvin/yast2/debugger/test2.ycp 5 step interpreter: #0 wfm 1 position: /suse/arvin/yast2/debugger/test2.ycp 6
In the qt frontend a green arrow points to the current line. Well, it's time to see some variables:
scope BEGIN SCOPE 1 list cpu = [$["architecture":"i386", "baseclass":"Internally Used Clas END SCOPE
The interpreter only knows about the variable cpu. The first number tells us the level in which the variable is located. You can also see that the output is truncated. This is done since those list can get very long. If you want to see the complete variable, use the print command:
print cpu BEGIN VARIABLE [$["architecture":"i386", "baseclass":"Internally Used Class", "bus":"None", "family":6, "model":3, "subclass":"CPU", "unique_key":"9zuE.j8NaKXDZtZ6"]] END VARIABLE
In the qt frontend, the variable is displayed in a separate window in a more human readable style and with syntax highlighting.
Let's go on:
step interpreter: #0 wfm 1 position: /suse/arvin/yast2/debugger/test2.ycp 12 step interpreter: #4 ui 0 position: /suse/arvin/yast2/debugger/test2.ycp 0
Now the ui interpreter is active. It has the unique number 4. You can get a list of all interpreters:
list interpreters BEGIN INTERPRETERS #0 wfm #1 scr #2 scr #3 scr #4 ui END INTERPRETERS
Well, quite a lot of scr interpreters. But it's correct: Every scr path has one interpreter (after it has been used) plus one interpreter for the main ScriptingAgent.
Now let's set a breakpoint at line 16 and continue until it is reached:
break /suse/arvin/yast2/debugger/test2.ycp 16 BEGIN BREAKPOINTS /suse/arvin/yast2/debugger/test2.ycp 16 END BREAKPOINTS continue breakpoint reached interpreter: #0 wfm 1 position: /suse/arvin/yast2/debugger/test2.ycp 16
Setting breakpoints is much easier in the qt frontend: Just click with the left mousebutton onto a line. Breakpoints are also marked with a red sign. Note: If you set a breakpoint at a empty line, it will never be reached.
continue All interpreters finished, bye. Connection closed by foreign host. ->
That's all folks.