Didn't manage to trigger the CSPROPI issue - before that happens, some other
shuffling issue easily crops up. But the root cause seems clear and this
test will trigger the root cause.
Add minimal debugger support to Duktape:
* Binary debug protocol which runs directly between Duktape internals and
an external debug client. Application code implements a blind transport
for debug packets only and is unaware of debug capabilities otherwise.
* Feature option DUK_OPT_DEBUGGER_SUPPORT to enable debugger support. This
adds about 10kB for code footprint. DUK_OPT_INTERRUPT_COUNTER is also
required. Other DUK_OPT_DEBUGGER_xxx feature options to control individual
features, see doc/feature-options.rst and doc/debugger.rst.
* Duktape API additions to allow an application to attach/detach a debugger
and to provide the debug packet transport mechanism.
* Simple debug capabilities include:
- List breakpoints
- Add breakpoint targeted at a fileName/lineNumber pair
- Delete breakpoint
- "debugger;" statement, interpreted as a breakpoint
- Step over
- Step into
- Step out
- Get callstack
- Get locals
- Eval
- Get variable
- Put variable
- Forwarding of print(), alert(), and logger writes
- Full heap dump (debug client / debugger UI converts to JSON)
* Example TCP debug transport (examples/debug-trans-socket).
* Duktape command line tool "--debugger" option which causes the command
line tool to wait for an incoming debug connection (using the example
TCP transport) before starting the program.
* A Node.js-based debug client with a web UI (debugger/duk_debug.js), which
can communicate with the Duktape command line tool to provide a full
example that can be tried "out of the box". The current version is very
barebones.
Various internal changes:
* Track function min/max line number when debugging enabled, so that
breakpoints can be accurately targeted
* Compiler line number handling fixes to make pc/line mapping more accurate
(previous inaccuracies don't matter for tracebacks but they do when using
breakpoints and stepping)
* Keep _Varmap for functions when debugger support is enabled. It is needed
to support eval() for all functions. Without debugger support Duktape can
sometimes deduce that _Varmap will never be needed and will omit it.
The debugger functionality has a number of limitations:
* Duktape doesn't maintain source code for functions, so the debug client
must have access to matching source code.
* Dynamic code (eval etc) cannot be easily debugged because breakpoints
cannot be targeted in them, and no source is available. The "debugger;"
statement still works, but is mostly useful to allow variables to be
evaluated at the debugger; statement breakpoint.
* Reading local variables and eval can invoke getters/setters which can
have unexpected consequences.
* Many primitives are missing, such as: inspect arbitrary callstack frames
(not just the topmost), enumerate heap objects, traverse the object graph,
execution and memory statistics, data dependent breakpoints, etc.
The breakpoint trigger condition included a check that if prev_line was zero,
no line transition would ever be detected. This means that if a breakpoint
is set on the first line of a function, it would never get triggered - not
even after execution had proceeded beyond it.
Change the condition so that prev_line can be zero, and a transition 0->1 is
generated. This allows breakpoints at line 1 to match.
Line range was updated only whenever bytecode opcodes were emitted. This
caused the line range to emit e.g. the opening brace of a function. Add
specific line number updates for e.g. function delimiting braces to ensure
the line range covers the function entirely.
- Add error constant to debug client
- Rework duk_debug.js to use bluebird promises
- Use proper path delimiter (e.g. ';' on Windows)
- Tolerate broken source search dirs
- Accept both node and nodejs in debugger Makefile
- Automatic --source-dirs for both Duktape repo and dist dir
- README update
- Debugger cleanups
The duk_to_uint() coercion caps negative values to zero, so that e.g.
"buf[3] = -1;" yields 0x00 as the buffer value instead of the more natural
0xFF. Change to duk_to_int() to get natural behavior at least for the
whole duk_int_t range. Outside this range the duk_to_int() coercion will
again cap to DUK_INT_MIN and DUK_INT_MAX and behave a bit oddly.
Also testcase and RELEASES.rst update.
- Endianness for pointers and IEEE doubles
- Add DUK_OPT_DEBUGGER_DUMPHEAP feature option
- Add DUK_OPT_DEBUGGER_DUMPHEAP to Makefile
- Refactor executor and executor interrupt debugger handling to separate
functions to make them easier to read
- Explicit peek, read flush, and write flush callbacks
- Remove brkpt_dirty, easier and perhaps more robust to recheck breakpoints
whenever any debug commands have been executed
- Bug fixes, FIXME resolutions, trivia
- DUK_BSWAP32() and DUK_BSWAP16() in duk_features.h so that platform specific
macros, intrinsics, or inline assembly can be used if necessary
- DUK_DBLUNION_BSWAP() for byte swapping doubles (needed by debugger)
- duk_byteswap_bytes() helper for byte swapping arbitrary data (needed by
debugger for pointers)
- API call documentation
- DUK_DEBUG_PROTOCOL_VERSION define
- Update LoC in website index page
- Debugger changes to Guide
Quite minimal at this point. There should be an architecture figure.
To be text browser compatible it'd have to be ASCII art or have an
ASCII art fallback.
Fix compiler register limit which was incorrectly set to DUK_BC_BC_MAX.
That value is correct from a bytecode perspective but duk_hcompiledfunction
nargs/nregs fields are 16-bit so 0xffff is the effective limit.
Before this change functions with [65536,262143] registers would compile
without error but would allocate a register frame too small (due to nregs
overflow) which could then result in segfaults etc.