Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add explicit pause trigger flags to debugger Resume command #1704

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
94 changes: 83 additions & 11 deletions doc/debugger.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1580,21 +1580,66 @@ Resume request (0x13)

Format::

REQ <int: 0x13> EOM
REQ <int: 0x13> [<int: flags>] EOM
REP EOM

Example::

REQ 19 EOM
REP EOM

If Duktape is already running, a no-op. If Duktape is paused, it will exit
the debug message loop associated with the paused state (where control is
fully in the hands of the debug client), resume execution, and send a Status
notification indicating it is running.
Flags describe what pause triggers are enabled (matches internal
DUK_PAUSE_FLAG_xxx constants):

StepInto request (0x14)
-----------------------
FIXME: these defines should be exposed in duktape.h; they would be useful at least
for some debug clients (and others might scrape them).

+--------+----------------------------------------------------------------------+
| Flag | Description |
+========+======================================================================+
| 0x0001 | Pause after a single opcode has been executed; ignored in a native |
| | function. |
+--------+----------------------------------------------------------------------+
| 0x0002 | Pause when current line number changes; ignored if current function |
| | has no line information (typically a native function). |
+--------+----------------------------------------------------------------------+
| 0x0004 | Pause when entering an inner function. |
+--------+----------------------------------------------------------------------+
| 0x0008 | Pause when exiting current function, and when an error is propagated |
| | past the current function. |
+--------+----------------------------------------------------------------------+
| 0x0010 | Pause when an uncaught error (see below) is about to be thrown. |
+--------+----------------------------------------------------------------------+
| 0x0020 | Pause when a caught error (see below) is about to be thrown. |
+--------+----------------------------------------------------------------------+

In addition to these pause triggers, active breakpoints always trigger a pause.

If flags are not explicitly defined (which is allowed for compatibility), the
implied flags are:

* If DUK_USE_DEBUGGER_PAUSE_UNCAUGHT is defined: pause on uncaught (0x0010),
pause on breakpoints.

* If DUK_USE_DEBUGGER_PAUSE_UNCAUGHT is not defined: pause on breakpoints only.

If Duktape is already running, the pause triggers are updated as if Duktape was
first paused and then resumed immediately.

If Duktape is paused, it will exit the debug message loop associated with the
paused state (where control is fully in the hands of the debug client), resume
execution, and send a Status notification indicating it is running.

An error about to be thrown is considered "uncaught" if:

* There is an Ecmascript try-catch, try-finally, or try-catch-finally in the
current callstack, or in any callstack of the active thread resume chain.

* Protected API calls (duk_safe_call(), duk_pcall(), etc) are not considered
catchers for purposes of the pause trigger.

StepInto request (DEPRECATED) (0x14)
------------------------------------

Format::

Expand All @@ -1612,8 +1657,19 @@ the current function (in which case execution pauses in the error catcher,
if any). If the current function doesn't have line information (e.g. it is
native), pauses on function entry/exit or error throw.

StepOver request (0x15)
-----------------------
DEPRECATED: equivalent to Resume with the following flags:

* Pause on line change

* Pause on function entry

* Pause on function exit

* Pause on uncaught error, if DUK_USE_DEBUGGER_PAUSE_UNCAUGHT config option
is defined.

StepOver request (DEPRECATED) (0x15)
------------------------------------

Format::

Expand All @@ -1631,8 +1687,17 @@ case execution pauses in the error catcher, if any). If the current function
doesn't have line information (e.g. it is native), pauses on function exit or
error throw.

StepOut request (0x16)
----------------------
DEPRECATED: equivalent to Resume with the following flags:

* Pause on line change

* Pause on function exit

* Pause on uncaught error, if DUK_USE_DEBUGGER_PAUSE_UNCAUGHT config option
is defined.

StepOut request (DEPRECATED) (0x16)
-----------------------------------

Format::

Expand All @@ -1648,6 +1713,13 @@ Resume execution and pause when execution exits the current function or an
error is thrown past the current function (in which case execution pauses
in the error catcher, if any).

DEPRECATED: equivalent to Resume with the following flags:

* Pause on function exit

* Pause on uncaught error, if DUK_USE_DEBUGGER_PAUSE_UNCAUGHT config option
is defined.

ListBreak request (0x17)
------------------------

Expand Down
6 changes: 6 additions & 0 deletions src-input/duk_debugger.c
Original file line number Diff line number Diff line change
Expand Up @@ -1296,6 +1296,8 @@ DUK_LOCAL void duk__debug_handle_resume(duk_hthread *thr, duk_heap *heap) {

duk_debug_clear_paused(heap);

/* FIXME: explicit flags */

pause_flags = 0;
#if 0 /* manual testing */
pause_flags |= DUK_PAUSE_FLAG_ONE_OPCODE;
Expand All @@ -1315,6 +1317,10 @@ DUK_LOCAL void duk__debug_handle_resume(duk_hthread *thr, duk_heap *heap) {
DUK_LOCAL void duk__debug_handle_step(duk_hthread *thr, duk_heap *heap, duk_int32_t cmd) {
duk_small_uint_t pause_flags;

/* Deprecated command: replaced by Resume with explicit flags.
* To be removed in a future release.
*/

DUK_D(DUK_DPRINT("debug command StepInto/StepOver/StepOut: %d", (int) cmd));

if (cmd == DUK_DBG_CMD_STEPINTO) {
Expand Down
16 changes: 9 additions & 7 deletions src-input/duk_heap.h
Original file line number Diff line number Diff line change
Expand Up @@ -271,14 +271,16 @@ typedef void *(*duk_mem_getptr)(duk_heap *heap, void *ud);
/* Milliseconds between status notify and transport peeks. */
#define DUK_HEAP_DBG_RATELIMIT_MILLISECS 200

/* Debugger pause flags. */
/* Debugger pause flags. These must match the debugger protocol where they
* are used 1:1.
*/
#define DUK_PAUSE_FLAG_ONE_OPCODE (1U << 0) /* pause when a single opcode has been executed */
#define DUK_PAUSE_FLAG_ONE_OPCODE_ACTIVE (1U << 1) /* one opcode pause actually active; artifact of current implementation */
#define DUK_PAUSE_FLAG_LINE_CHANGE (1U << 2) /* pause when current line number changes */
#define DUK_PAUSE_FLAG_FUNC_ENTRY (1U << 3) /* pause when entering a function */
#define DUK_PAUSE_FLAG_FUNC_EXIT (1U << 4) /* pause when exiting current function */
#define DUK_PAUSE_FLAG_CAUGHT_ERROR (1U << 5) /* pause when about to throw an error that is caught */
#define DUK_PAUSE_FLAG_UNCAUGHT_ERROR (1U << 6) /* pause when about to throw an error that won't be caught */
#define DUK_PAUSE_FLAG_LINE_CHANGE (1U << 1) /* pause when current line number changes */
#define DUK_PAUSE_FLAG_FUNC_ENTRY (1U << 2) /* pause when entering a function */
#define DUK_PAUSE_FLAG_FUNC_EXIT (1U << 3) /* pause when exiting current function */
#define DUK_PAUSE_FLAG_CAUGHT_ERROR (1U << 4) /* pause when about to throw an error that is caught */
#define DUK_PAUSE_FLAG_UNCAUGHT_ERROR (1U << 5) /* pause when about to throw an error that won't be caught */
#define DUK_PAUSE_FLAG_ONE_OPCODE_ACTIVE (1U << 15) /* one opcode pause actually active; artifact of current implementation */

struct duk_breakpoint {
duk_hstring *filename;
Expand Down