Github User Fetcher 1.0.0
C Application with Server and GUI
Loading...
Searching...
No Matches
duktape-1.5.2/src-separate/duk_api_debug.c
Go to the documentation of this file.
1/*
2 * Debugging related API calls
3 */
4
5#include "duk_internal.h"
6
8 duk_idx_t idx;
9 duk_idx_t top;
10
12
13 /* We don't duk_require_stack() here now, but rely on the caller having
14 * enough space.
15 */
16
17 top = duk_get_top(ctx);
18 duk_push_array(ctx);
19 for (idx = 0; idx < top; idx++) {
20 duk_dup(ctx, idx);
21 duk_put_prop_index(ctx, -2, idx);
22 }
23
24 /* XXX: conversion errors should not propagate outwards.
25 * Perhaps values need to be coerced individually?
26 */
28 duk_get_top_index(ctx), /*idx_value*/
29 DUK_INVALID_INDEX, /*idx_replacer*/
30 DUK_INVALID_INDEX, /*idx_space*/
34
35 duk_push_sprintf(ctx, "ctx: top=%ld, stack=%s", (long) top, (const char *) duk_safe_to_string(ctx, -1));
36 duk_replace(ctx, -3); /* [ ... arr jsonx(arr) res ] -> [ ... res jsonx(arr) ] */
37 duk_pop(ctx);
38 DUK_ASSERT(duk_is_string(ctx, -1));
39}
40
41#if defined(DUK_USE_DEBUGGER_SUPPORT)
42
48 duk_debug_write_flush_function write_flush_cb,
51 void *udata) {
52 duk_hthread *thr = (duk_hthread *) ctx;
53 duk_heap *heap;
54 const char *str;
55 duk_size_t len;
56
57 /* XXX: should there be an error or an automatic detach if
58 * already attached?
59 */
60
61 DUK_D(DUK_DPRINT("application called duk_debugger_attach()"));
62
64 DUK_ASSERT(read_cb != NULL);
65 DUK_ASSERT(write_cb != NULL);
66 /* Other callbacks are optional. */
67
68 heap = thr->heap;
69 heap->dbg_read_cb = read_cb;
70 heap->dbg_write_cb = write_cb;
71 heap->dbg_peek_cb = peek_cb;
72 heap->dbg_read_flush_cb = read_flush_cb;
73 heap->dbg_write_flush_cb = write_flush_cb;
74 heap->dbg_request_cb = request_cb;
75 heap->dbg_detached_cb = detached_cb;
76 heap->dbg_udata = udata;
77 heap->dbg_have_next_byte = 0;
78
79 /* Start in paused state. */
80 heap->dbg_processing = 0;
81 heap->dbg_paused = 1;
82 heap->dbg_state_dirty = 1;
83 heap->dbg_force_restart = 0;
84 heap->dbg_step_type = 0;
85 heap->dbg_step_thread = NULL;
86 heap->dbg_step_csindex = 0;
87 heap->dbg_step_startline = 0;
88 heap->dbg_exec_counter = 0;
89 heap->dbg_last_counter = 0;
90 heap->dbg_last_time = 0.0;
91
92 /* Send version identification and flush right afterwards. Note that
93 * we must write raw, unframed bytes here.
94 */
95 duk_push_sprintf(ctx, "%ld %ld %s %s\n",
97 (long) DUK_VERSION,
98 (const char *) DUK_GIT_DESCRIBE,
99 (const char *) DUK_USE_TARGET_INFO);
100 str = duk_get_lstring(ctx, -1, &len);
101 DUK_ASSERT(str != NULL);
102 duk_debug_write_bytes(thr, (const duk_uint8_t *) str, len);
103 duk_debug_write_flush(thr);
104 duk_pop(ctx);
105}
106
108 duk_hthread *thr;
109
110 DUK_D(DUK_DPRINT("application called duk_debugger_detach()"));
111
113 thr = (duk_hthread *) ctx;
114 DUK_ASSERT(thr != NULL);
115 DUK_ASSERT(thr->heap != NULL);
116
117 /* Can be called multiple times with no harm. */
118 duk_debug_do_detach(thr->heap);
119}
120
122 duk_hthread *thr;
123 duk_bool_t processed_messages;
124
126 thr = (duk_hthread *) ctx;
127 DUK_ASSERT(thr != NULL);
128 DUK_ASSERT(thr->heap != NULL);
129
130 if (!DUK_HEAP_IS_DEBUGGER_ATTACHED(thr->heap)) {
131 return;
132 }
133 if (thr->callstack_top > 0 || thr->heap->dbg_processing) {
134 /* Calling duk_debugger_cooperate() while Duktape is being
135 * called into is not supported. This is not a 100% check
136 * but prevents any damage in most cases.
137 */
138 return;
139 }
140
141 processed_messages = duk_debug_process_messages(thr, 1 /*no_block*/);
142 DUK_UNREF(processed_messages);
143}
144
146 duk_hthread *thr;
147 duk_idx_t top;
148 duk_idx_t idx;
149 duk_bool_t ret = 0;
150
152 thr = (duk_hthread *) ctx;
153 DUK_ASSERT(thr != NULL);
154 DUK_ASSERT(thr->heap != NULL);
155
156 DUK_D(DUK_DPRINT("application called duk_debugger_notify() with nvalues=%ld", (long) nvalues));
157
158 top = duk_get_top(ctx);
159 if (top < nvalues) {
160 DUK_ERROR_API(thr, "not enough stack values for notify");
161 return ret; /* unreachable */
162 }
163 if (DUK_HEAP_IS_DEBUGGER_ATTACHED(thr->heap)) {
164 duk_debug_write_notify(thr, DUK_DBG_CMD_APPNOTIFY);
165 for (idx = top - nvalues; idx < top; idx++) {
166 duk_tval *tv = DUK_GET_TVAL_POSIDX(ctx, idx);
167 duk_debug_write_tval(thr, tv);
168 }
169 duk_debug_write_eom(thr);
170
171 /* Return non-zero (true) if we have a good reason to believe
172 * the notify was delivered; if we're still attached at least
173 * a transport error was not indicated by the transport write
174 * callback. This is not a 100% guarantee of course.
175 */
176 if (DUK_HEAP_IS_DEBUGGER_ATTACHED(thr->heap)) {
177 ret = 1;
178 }
179 }
180 duk_pop_n(ctx, nvalues);
181 return ret;
182}
183
185 duk_hthread *thr;
186
188 thr = (duk_hthread *) ctx;
189 DUK_ASSERT(thr != NULL);
190 DUK_ASSERT(thr->heap != NULL);
191
192 DUK_D(DUK_DPRINT("application called duk_debugger_pause()"));
193
194 /* Treat like a debugger statement: ignore when not attached. */
195 if (DUK_HEAP_IS_DEBUGGER_ATTACHED(thr->heap)) {
196 DUK_HEAP_SET_PAUSED(thr->heap);
197
198 /* Pause on the next opcode executed. This is always safe to do even
199 * inside the debugger message loop: the interrupt counter will be reset
200 * to its proper value when the message loop exits.
201 */
202 thr->interrupt_init = 1;
203 thr->interrupt_counter = 0;
204 }
205}
206
207#else /* DUK_USE_DEBUGGER_SUPPORT */
208
213 duk_debug_read_flush_function read_flush_cb,
214 duk_debug_write_flush_function write_flush_cb,
216 duk_debug_detached_function detached_cb,
217 void *udata) {
219 DUK_UNREF(read_cb);
220 DUK_UNREF(write_cb);
221 DUK_UNREF(peek_cb);
222 DUK_UNREF(read_flush_cb);
223 DUK_UNREF(write_flush_cb);
224 DUK_UNREF(request_cb);
225 DUK_UNREF(detached_cb);
226 DUK_UNREF(udata);
227 DUK_ERROR_API((duk_hthread *) ctx, "no debugger support");
228}
229
232 DUK_ERROR_API((duk_hthread *) ctx, "no debugger support");
233}
234
236 /* nop */
238 DUK_UNREF(ctx);
239}
240
242 duk_idx_t top;
243
245
246 top = duk_get_top(ctx);
247 if (top < nvalues) {
248 DUK_ERROR_API((duk_hthread *) ctx, "not enough stack values for notify");
249 return 0; /* unreachable */
250 }
251
252 /* No debugger support, just pop values. */
253 duk_pop_n(ctx, nvalues);
254 return 0;
255}
256
258 /* Treat like debugger statement: nop */
260 DUK_UNREF(ctx);
261}
262
263#endif /* DUK_USE_DEBUGGER_SUPPORT */
duk_small_int_t duk_bool_t
#define DUK_ASSERT_CTX_VALID(ctx)
DUK_EXTERNAL const char * duk_get_lstring(duk_context *ctx, duk_idx_t index, duk_size_t *out_len)
DUK_EXTERNAL duk_bool_t duk_put_prop_index(duk_context *ctx, duk_idx_t obj_idx, duk_uarridx_t arr_idx)
#define DUK_JSON_FLAG_AVOID_KEY_QUOTES
#define DUK_ERROR_API(thr, msg)
DUK_INTERNAL_DECL void duk_bi_json_stringify_helper(duk_context *ctx, duk_idx_t idx_value, duk_idx_t idx_replacer, duk_idx_t idx_space, duk_small_uint_t flags)
DUK_EXTERNAL void duk_replace(duk_context *ctx, duk_idx_t to_index)
#define DUK_DBG_CMD_APPNOTIFY
DUK_EXTERNAL duk_idx_t duk_get_top_index(duk_context *ctx)
DUK_EXTERNAL void duk_dup(duk_context *ctx, duk_idx_t from_index)
#define DUK_JSON_FLAG_EXT_CUSTOM
DUK_EXTERNAL duk_idx_t duk_get_top(duk_context *ctx)
DUK_EXTERNAL const char * duk_push_sprintf(duk_context *ctx, const char *fmt,...)
DUK_EXTERNAL void duk_pop_n(duk_context *ctx, duk_idx_t count)
#define DUK_GET_TVAL_POSIDX(ctx, idx)
DUK_EXTERNAL void duk_pop(duk_context *ctx)
DUK_EXTERNAL duk_idx_t duk_push_array(duk_context *ctx)
DUK_EXTERNAL duk_bool_t duk_is_string(duk_context *ctx, duk_idx_t index)
#define DUK_JSON_FLAG_ASCII_ONLY
duk_size_t(* duk_debug_read_function)(void *udata, char *buffer, duk_size_t length)
void(* duk_debug_write_flush_function)(void *udata)
#define DUK_DEBUG_PROTOCOL_VERSION
#define duk_safe_to_string(ctx, index)
void(* duk_debug_detached_function)(void *udata)
void(* duk_debug_read_flush_function)(void *udata)
duk_idx_t(* duk_debug_request_function)(duk_context *ctx, void *udata, duk_idx_t nvalues)
duk_size_t(* duk_debug_peek_function)(void *udata)
duk_size_t(* duk_debug_write_function)(void *udata, const char *buffer, duk_size_t length)
DUK_EXTERNAL void duk_debugger_cooperate(duk_context *ctx)
DUK_EXTERNAL void duk_push_context_dump(duk_context *ctx)
DUK_EXTERNAL void duk_debugger_detach(duk_context *ctx)
DUK_EXTERNAL duk_bool_t duk_debugger_notify(duk_context *ctx, duk_idx_t nvalues)
DUK_EXTERNAL void duk_debugger_attach_custom(duk_context *ctx, duk_debug_read_function read_cb, duk_debug_write_function write_cb, duk_debug_peek_function peek_cb, duk_debug_read_flush_function read_flush_cb, duk_debug_write_flush_function write_flush_cb, duk_debug_request_function request_cb, duk_debug_detached_function detached_cb, void *udata)
DUK_EXTERNAL void duk_debugger_pause(duk_context *ctx)
#define NULL
Definition gmacros.h:924