+++ /dev/null
-=========================================
-Duktape debug client and JSON debug proxy
-=========================================
-
-Overview
-========
-
-Debugger web UI which connects to the Duktape command line tool or any other
-target supporting the example TCP transport (``examples/debug-trans-socket``)
-on Unix and Windows.
-
-Also provides a JSON debug proxy with a JSON mapping for the Duktape debug
-protocol.
-
-For detailed documentation of the debugger internals, see `debugger.rst`__.
-
-__ https://github.com/svaarala/duktape/blob/master/doc/debugger.rst
-
-Using the debugger web UI
-=========================
-
-Some prerequisites:
-
-* You'll need Node.js v0.10.x or newer. Older Node.js versions don't support
- the required packages.
-
-Compile Duktape command line tool with debugger support (for further options
-see http://wiki.duktape.org/FeatureOptions.html):
-
-* ``DUK_OPT_DEBUGGER_SUPPORT``
-
-* ``DUK_OPT_INTERRUPT_COUNTER``
-
-* ``DUK_CMDLINE_DEBUGGER_SUPPORT``
-
-The source distributable contains a Makefile to build a "duk" command with
-debugger support::
-
- $ cd <duktape dist directory>
- $ make -f Makefile.dukdebug
-
-The Duktape Git repo "duk" target has debugger support enabled by default::
-
- $ make clean duk
-
-Start Duktape command line tool so that it waits for a debugger connection::
-
- # For now we need to be in the directory containing the source files
- # executed so that the 'fileName' properties of functions will match
- # that on the debug client.
-
- # Using source distributable
- $ cd <duktape dist directory>
- $ ./duk --debugger mandel.js
-
- # Using Duktape Git repo
- $ cd <duktape checkout>/tests/ecmascript/
- $ ../../duk --debugger test-dev-mandel2-func.js
-
-Start the web UI::
-
- # Must be in 'debugger' directory.
-
- $ cd debugger/
- $ make # runs 'node duk_debug.js'
-
-Once the required packages are installed, the NodeJS debug client will be
-up and running. Open the following in your browser and start debugging:
-
-* http://localhost:9092/
-
-The debug client automatically attaches to the debug target on startup.
-If you start the debug target later, you'll need to click "Attach" in the
-web UI.
-
-Using the JSON debug proxy
-==========================
-
-There are two JSON debug proxy implementations: one implemented in DukLuv
-and another in Node.js.
-
-DukLuv JSON proxy
------------------
-
-DukLuv (https://github.com/creationix/dukluv) is a small and portable event
-loop based on LibUV and Duktape with MIT license (like Duktape). As such it's
-easy to embed in a custom debug client: you just include the DukLuv executable
-and the JSON proxy source file in your debug client.
-
-Install DukLuv:
-
-* Ensure ``cmake`` is installed
-
-* ``git clone https://github.com/creationix/dukluv.git``
-
-* ``git submodule init; git submodule update``
-
-* ``make``
-
-* Binary should appear in:
-
- - ``./build/dukluv`` on Linux
-
- - ``.\build\Debug\dukluv.exe`` on Windows
-
-Run the proxy::
-
- # Using Makefile; autogenerates duk_debug_meta.json
- # (You may need to edit DUKLUV in Makefile to point to your DukLuv)
- $ make runproxydukluv
-
- # Manually: see "dukluv duk_debug_proxy.js --help" for help
- $ .../path/to/dukluv duk_debug_proxy.js
-
-Start Duktape command line (or whatever your target is)::
-
- $ cd <duktape checkout>/tests/ecmascript/
- $ ../../duk --debugger test-dev-mandel2-func.js
-
-Now connect to the proxy using e.g. telnet::
-
- $ telnet localhost 9093
-
-The proxy will then connect to the target and you can start issuing commands::
-
- $ telnet localhost 9093
- Trying 127.0.0.1...
- Connected to localhost.
- Escape character is '^]'.
- {"notify":"_TargetConnecting","args":["127.0.0.1",9091]}
- {"notify":"_TargetConnected","args":["1 10499 v1.4.0-140-gc9a6c7c duk command built from Duktape repo"]}
- {"notify":"Status","command":1,"args":[1,"test-dev-mandel2-func.js","global",58,0]}
- {"request":"BasicInfo"}
- {"reply":true,"args":[10499,"v1.4.0-140-gc9a6c7c","duk command built from Duktape repo",1]}
- {"request":"Eval","args":["print('Hello world!'); 123;"]}
- {"notify":"Print","command":2,"args":["Hello world!\n"]}
- {"reply":true,"args":[0,{"type":"number","data":"405ec00000000000"}]}
- [...]
-
-The proxy log provides dumps both JSON and dvalue binary traffic which is
-quite useful in development::
-
- $ make runproxydukluv
- Running Dukluv based debug proxy
- "dukluv" duk_debug_proxy.js --log-level 2 --metadata duk_debug_meta.json
- 2016-02-17T13:59:42.308Z INF Proxy: Read proxy metadata from duk_debug_meta.json
- 2016-02-17T13:59:42.325Z INF Proxy: Listening for incoming JSON debug connection on 0.0.0.0:9093, target is 127.0.0.1:9091
- 2016-02-17T13:59:47.994Z INF Proxy: JSON proxy client connected
- 2016-02-17T13:59:47.994Z INF Proxy: Connecting to debug target at 127.0.0.1:9091
- 2016-02-17T13:59:47.994Z INF Proxy: PROXY --> CLIENT: {"notify":"_TargetConnecting","args":["127.0.0.1",9091]}
- 2016-02-17T13:59:47.994Z INF Proxy: Connected to debug target at 127.0.0.1:9091
- 2016-02-17T13:59:48.003Z INF Proxy: PROXY --> CLIENT: {"notify":"_TargetConnected","args":["1 10499 v1.4.0-140-gc9a6c7c duk command built from Duktape repo"]}
- 2016-02-17T13:59:48.003Z INF Proxy: Target handshake: {"line":"1 10499 v1.4.0-140-gc9a6c7c duk command built from Duktape repo","protocolVersion":1,"text":"10499 v1.4.0-140-gc9a6c7c duk command built from Duktape repo","dukVersion":"1","dukGitDescribe":"10499","targetString":"v1.4.0-140-gc9a6c7c"}
- 2016-02-17T13:59:48.151Z INF Proxy: PROXY <-- TARGET: |04|
- 2016-02-17T13:59:48.152Z INF Proxy: PROXY <-- TARGET: |81|
- 2016-02-17T13:59:48.152Z INF Proxy: PROXY <-- TARGET: |81|
- 2016-02-17T13:59:48.160Z INF Proxy: PROXY <-- TARGET: |78746573742d6465762d6d616e64656c322d66756e632e6a73|
- 2016-02-17T13:59:48.161Z INF Proxy: PROXY <-- TARGET: |66676c6f62616c|
- 2016-02-17T13:59:48.165Z INF Proxy: PROXY <-- TARGET: |ba|
- 2016-02-17T13:59:48.165Z INF Proxy: PROXY <-- TARGET: |80|
- 2016-02-17T13:59:48.165Z INF Proxy: PROXY <-- TARGET: |00|
- 2016-02-17T13:59:48.165Z INF Proxy: PROXY --> CLIENT: {"notify":"Status","command":1,"args":[1,"test-dev-mandel2-func.js","global",58,0]}
- 2016-02-17T13:59:51.289Z INF Proxy: PROXY <-- CLIENT: {"request":"BasicInfo"}
- 2016-02-17T13:59:51.289Z INF Proxy: PROXY --> TARGET: |01|
- 2016-02-17T13:59:51.289Z INF Proxy: PROXY --> TARGET: |90|
- 2016-02-17T13:59:51.289Z INF Proxy: PROXY --> TARGET: |00|
- 2016-02-17T13:59:51.291Z INF Proxy: PROXY <-- TARGET: |02|
- 2016-02-17T13:59:51.291Z INF Proxy: PROXY <-- TARGET: |e903|
- 2016-02-17T13:59:51.292Z INF Proxy: PROXY <-- TARGET: |7376312e342e302d3134302d6763396136633763|
- 2016-02-17T13:59:51.293Z INF Proxy: PROXY <-- TARGET: |12002364756b20636f6d6d616e64206275696c742066726f6d2044756b74617065207265706f|
- 2016-02-17T13:59:51.293Z INF Proxy: PROXY <-- TARGET: |81|
- 2016-02-17T13:59:51.293Z INF Proxy: PROXY <-- TARGET: |00|
- 2016-02-17T13:59:51.293Z INF Proxy: PROXY --> CLIENT: {"reply":true,"args":[10499,"v1.4.0-140-gc9a6c7c","duk command built from Duktape repo",1]}
- 2016-02-17T14:00:06.105Z INF Proxy: PROXY <-- CLIENT: {"request":"Eval","args":["print('Hello world!'); 123;"]}
- 2016-02-17T14:00:06.105Z INF Proxy: PROXY --> TARGET: |01|
- 2016-02-17T14:00:06.105Z INF Proxy: PROXY --> TARGET: |9e|
- 2016-02-17T14:00:06.105Z INF Proxy: PROXY --> TARGET: |7b7072696e74282748656c6c6f20776f726c642127293b203132333b|
- 2016-02-17T14:00:06.105Z INF Proxy: PROXY --> TARGET: |00|
- 2016-02-17T14:00:06.167Z INF Proxy: PROXY <-- TARGET: |04|
- 2016-02-17T14:00:06.167Z INF Proxy: PROXY <-- TARGET: |82|
- 2016-02-17T14:00:06.167Z INF Proxy: PROXY <-- TARGET: |6d48656c6c6f20776f726c64210a|
- 2016-02-17T14:00:06.168Z INF Proxy: PROXY <-- TARGET: |00|
- 2016-02-17T14:00:06.168Z INF Proxy: PROXY --> CLIENT: {"notify":"Print","command":2,"args":["Hello world!\n"]}
- 2016-02-17T14:00:06.171Z INF Proxy: PROXY <-- TARGET: |02|
- 2016-02-17T14:00:06.171Z INF Proxy: PROXY <-- TARGET: |80|
- 2016-02-17T14:00:06.173Z INF Proxy: PROXY <-- TARGET: |1a405ec00000000000|
- 2016-02-17T14:00:06.173Z INF Proxy: PROXY <-- TARGET: |00|
- 2016-02-17T14:00:06.174Z INF Proxy: PROXY --> CLIENT: {"reply":true,"args":[0,{"type":"number","data":"405ec00000000000"}]}
- [...]
-
-Node.js JSON proxy
-------------------
-
-A Node.js-based JSON debug proxy is also provided by ``duk_debug.js``::
-
- # Same prerequisites as for running the debug client
- $ make runproxynodejs
-
-Start Duktape command line (or whatever your target is)::
-
- $ cd <duktape checkout>/tests/ecmascript/
- $ ../../duk --debugger test-dev-mandel2-func.js
-
-You can then connect to localhost:9093 and interact with the proxy.
-Here's an example session using telnet and manually typed in commands
-The ``-->`` (send) and ``<--`` (receiver) markers have been added for
-readability and are not part of the stream::
-
- $ telnet localhost 9093
- Trying 127.0.0.1...
- Connected to localhost.
- Escape character is '^]'.
- <-- {"notify":"_TargetConnected","args":["1 10199 v1.1.0-275-gbd4d610-dirty duk command built from Duktape repo"]}
- <-- {"notify":"Status","command":1,"args":[1,"test-dev-mandel2-func.js","global",58,0]}
- --> {"request":"BasicInfo"}
- <-- {"reply":true,"args":[10199,"v1.1.0-275-gbd4d610-dirty","duk command built from Duktape repo",1]}
- --> {"request":"Eval", "args":[ "print(Math.PI)" ]}
- <-- {"notify":"Print","command":2,"args":["3.141592653589793\n"]}
- <-- {"reply":true,"args":[0,{"type":"undefined"}]}
- --> {"request":"Resume"}
- <-- {"reply":true,"args":[]}
- <-- {"notify":"Status","command":1,"args":[0,"test-dev-mandel2-func.js","global",58,0]}
- <-- {"notify":"Status","command":1,"args":[0,"test-dev-mandel2-func.js","global",58,0]}
- <-- {"notify":"Print","command":2,"args":["................................................................................\n"]}
- <-- {"notify":"Print","command":2,"args":["................................................................................\n"]}
- <-- {"notify":"Print","command":2,"args":["................................................................................\n"]}
- [...]
- <-- {"notify":"_Disconnecting"}
-
-A telnet connection allows you to experiment with debug commands by simply
-copy-pasting debug commands to the telnet session. This is useful even if
-you decide to implement the binary protocol directly.
-
-The debug target used by the proxy can be configured with ``duk_debug.js``
-command line options.
-
-Source search path
-==================
-
-The NodeJS debug client needs to be able to find source code files matching
-code running on the target ("duk" command line). **The filenames used on the
-target and on the debug client must match exactly**, because e.g. breakpoints
-are targeted based on the 'fileName' property of Function objects.
-
-The search path can be set using the ``--source-dirs`` option given to
-``duk_debug.js``, with the default search paths including only
-``../tests/ecmascript/``.
-
-The default search path means that if a function on the target has fileName
-``foo/bar.js`` it would be loaded from (relative to the duk_debug.js working
-directory, ``debugger/``)::
-
- ../tests/ecmascript/foo/bar.js
-
-Similarly, if the filesystem contained::
-
- ../tests/ecmascript/baz/quux.js
-
-the web UI dropdown would show ``baz/quux.js``. If you selected that file
-and added a breakpoint, the breakpoint fileName sent to the debug target
-would be ``baz/quux.js``.
-
-.. note:: There's much to improve in the search path. For instance, it'd
- be nice to add a certain path to search but exclude files based
- on paths and patterns, etc.
-
-Architecture
-============
-
-::
-
- +-------------------+
- | Web browser | [debug UI]
- +-------------------+
- |
- | http (port 9092)
- | socket.io
- v
- +-------------------+
- | duk_debug.js | [debug client]
- +-------------------+
- | /\
- | ||
- +----------||---- [example tcp transport] (port 9091)
- | || (application provides concrete transport)
- | ||
- | ||---- [debug protocol stream]
- | || (between debug client and Duktape)
- | ||
- + - - | - - - - -|| - - +
- : v || :
- : +-------------||-+ : [target]
- : | application || | :
- : +-------------||-+ :
- : ^ || :
- : | || : [debug API]
- : +----------||-------- debug transport callbacks
- : | || : (read, write, peek, read/write flush)
- : | || : implemented by application
- : | \/ :
- : +----------------+ :
- : | Duktape | :
- : +----------------+ :
- + - - - - - - - - - - - +
-
-The debug transport is application specific:
-
-* Duktape command line ("duk") and this debug client use an **example** TCP
- transport as a concrete example.
-
-* It is entirely up to the application to come up with the most suitable
- transport for its environment. Different mechanisms will be needed for
- Wi-Fi, serial, etc.
-
-The debug protocol running inside the transport is transport independent:
-
-* The debug protocol is documented in ``doc/debugger.rst``.
-
-* This debug client provides further concrete examples and clarifications
- on how the protocol can be used.
-
-Using a custom transport
-========================
-
-Quite possibly your target device cannot use the example TCP transport and
-you need to implement your own transport. You'll need to implement your
-custom transport both for the target device and for the debug client.
-
-Target device
--------------
-
-Implement the debug transport callbacks needed by ``duk_debugger_attach()``.
-
-See ``doc/debugger.rst`` for details and ``examples/debug-trans-socket``
-for example running code for a TCP transport.
-
-Debug client alternative 1: duk_debug.js + custom TCP proxy
------------------------------------------------------------
-
-If you don't want to change ``duk_debug.js`` you can implement a TCP proxy
-which accepts a TCP connection from ``duk_debug.js`` and then uses your
-custom transport to talk to the target::
-
- +--------------+ TCP +-------+ custom +--------+
- | duk_debug.js | ------> | proxy | ---------> | target |
- +--------------+ +-------+ +--------+
-
-This is a straightforward option and a proxy can be used with other debug
-clients too (perhaps custom scripts talking to the target etc).
-
-You could also use netcat and implement your proxy so that it talks to
-``duk_debug.js`` using stdin/stdout.
-
-Debug client alternative 2: duk_debug.js + custom NodeJS stream
----------------------------------------------------------------
-
-To make ``duk_debug.js`` use a custom transport you need to:
-
-* Implement your own transport as NodeJS stream. You can add it directly to
- ``duk_debug.js`` but it's probably easiest to use a separate module so that
- the diff to ``duk_debug.js`` stays minimal.
-
-* Change ``duk_debug.js`` to use the custom transport instead of a TCP
- stream. Search for "CUSTOMTRANSPORT" in ``duk_debug.js``.
-
-See:
-
-* http://nodejs.org/api/stream.html
-
-* https://github.com/substack/stream-handbook
-
-Debug client alternative 3: custom debug client
------------------------------------------------
-
-You can also implement your own debug client and debug UI with support for
-your custom transport.
-
-You'll also need to implement the client part of the Duktape debugger
-protocol. See ``doc/debugger.rst`` for the specification and ``duk_debug.js``
-for example running code which should illustrate the protocol in more detail.
-
-The JSON debug proxy allows you to implement a debug client without needing
-to implement the Duktape binary debug protocol. The JSON protocol provides
-a roughly 1:1 mapping to the binary protocol but with an easier syntax.