-
Notifications
You must be signed in to change notification settings - Fork 253
Otemplate debugging
Otemplate templates can have the original line numbers attached. This allows easy debugging of original templates.
This is the behavior by default, but it can be reverted with the "--no-orig-lines" or "-n" otemplate command line arguments.
First of all it will break compilation in the proper place if there is a error on the generated C file. Normally an error should not arrive there, but it helps.
But most important it allows to use gdb 'straight' on the original template.
For this example we will use fileserver_otemplate. First of all, must be compiled with debugging; for sake of simplicity we will compile all onion with debugging:
$ mkdir build; cd build; cmake .. -DCMAKE_BUILD_TYPE=Debug; make
$ cd examples/fileserver_otemplate
And now we start the debugger:
$ gdb ./fileserver_otemplate
We can set breakpoints:
(gdb) b fileserver.html:30
Breakpoint 1 at 0x80496cf: file [...]/onion/examples/fileserver_otemplate/fileserver.html, line 30. (5 locations)
(gdb) source [...]/onion/examples/fileserver_otemplate/fileserver.html
List the source:
(gdb) l fileserver.html:29,36
29 {% for file in files %}
30 <tr>
31 <td><a href="{{file.name}}{% if file.type == "dir" %}/{% endif %}">{{file.name}}</a></td>
32 <td>{{file.size}}</td>
33 <td>{{file.owner}}</td>
34 </tr>
35 {% endfor %}
36 </tbody>
Run and it will stop at breakpoint. As normal it stops on next eligible line:
(gdb) r
Breakpoint 1, fileserver_html (context=0xb7401048, res=0xb74009b8) at [...]'/onion/examples/fileserver_otemplate/fileserver.html:31
31
<a href="{{file.name}}{% if file.type == "dir" %}/{% endif %}">{{file.name}}And show some variable status. This needs some knowledge of the library:
(gdb) p onion_dict_get(context, "dirname")
$1 = 0xb7400619 ""
(gdb) print onion_dict_rget(context, "files", ".", "name", 0)
$2 = 0xb740a650 "."
(gdb) print onion_dict_rget(context, "files", ".", "type", 0)
$3 = 0x804a247 "dir"
(gdb) print onion_dict_rget(context, "files", ".", "size", 0)
$4 = 0xb740a680 "4096"
(gdb) print onion_block_data(onion_dict_to_json(onion_dict_get_dict(context, "files")))
$5 = 0xb7402468 "{\".\":{\"name\":\".\", \"owner\":\"500\", \"size\":\"4096\", \"type\":\"dir\"},
\"..\":{\"name\":\"..\", \"owner\":\"500\", \"size\":\"4096\", \"type\":\"dir\"},
\"CMakeFiles\":{\"name\":\"CMakeFiles\", \"owner\":\"500\", \"size\":\"4096\",
\"type\":\""...
As we are in a loop, we also have the "file" variable:
(gdb) print onion_dict_rget(context, "file", "name", 0)
$6 = 0xb7402c18 "."
(gdb) p onion_dict_rget(context, "file", "size", 0)
$7 = 0xb7402c98 "4096"
(gdb) c
[...]
(gdb) print onion_dict_rget(context, "file", "name", 0)
$15 = 0xb7402df0 "fileserver_otemplate"
(gdb) p onion_dict_rget(context, "file", "size", 0)
$16 = 0xb7402f60 "22973"
Just now its not very intuitive, but we hope to make it better in the future.