1## JerryScript debugger interface 2 3JerryScript provides a remote debugger which allows debugging 4JavaScript programs. The debugger has two main components: 5a server which is part of the JerryScript binary and a 6separate client application. Currently a Python-based debugger 7client is available in the /jerry-debugger subdirectory. 8This simple application demonstrates the communication protocol 9between the client and server, and can be reused by integrated 10development environments. 11 12## Setting up the debugger server 13 14The following arguments must be passed to `tools/build.py`: 15 16`--jerry-debugger=on` 17 18The transport layer of the communication protocol is pluggable. 19At the moment, a WebSocket-based implementation is provided as a 20JerryScript extension, which transmits messages over TCP/IP networks. 21If necessary/implemented, any reliable stream or datagram based 22protocol can be used for transmitting debugger messages. 23 24## Debugging JavaScript applications 25 26The debugger client must be connected to the server before the 27JavaScript application runs. On-the-fly attachment is supported 28for more than one file, right after the engine initialization 29(this feature is available with the python client). The debugging 30information (e.g. line index of each possible breakpoint location) 31is not preserved by JerryScript. The client is expected to be run 32on a system with much more resources and it should be capable of 33storing this information. JerryScript frees all debug information 34after it is transmitted to the client to save memory. 35 36The following argument makes JerryScript wait for a client 37connection: 38 39`--start-debug-server` 40 41The following argument makes JerryScript wait for a client 42source code: 43 44`--debugger-wait-source` 45 46It is also recommended to increase the log level to see 47the *Waiting for client connection* message: 48 49`--log-level 2` 50 51The Python client can connect to the server by specifying its 52IP address on the command line. The address can be localhost 53if the server and the client are running on the same machine. 54 55After the connection is established the execution can be 56controlled by the debugger. The debugger always stops at 57the first possible breakpoint location. The effect is the 58same as using the `stop` command. This allows inserting 59breakpoints right before the meaningful part of the execution 60starts. 61 62All available commands of the client can be queried by the 63`help` command. 64 65## Integrating debugger support into applications using JerryScript 66 67When using the extension-provided WebSocket transport layer, the 68debugger can be enabled by calling `jerryx_debugger_after_connect 69(jerryx_debugger_tcp_create (debug_port) && jerryx_debugger_ws_create ())` 70after the `jerry_init ()` function. It initializes the debugger and 71blocks until a client connects. 72(Custom transport layers may be implemented and initialized similarly. 73Currently, `jerryx_debugger_rp_create ()` for raw packet transport layer and 74`jerryx_debugger_serial_create (const char* config)` for serial protocol 75are also available.) 76 77The resource name provided to `jerry_parse ()` is used by the client 78to identify the resource name of the source code. This resource name 79is usually a file name. 80 81## JerryScript debugger C-API interface 82 83The following section describes the debugger functions 84available to the host application. 85 86## JerryScript debugger types 87 88## jerry_debugger_wait_for_source_callback_t 89 90**Summary** 91 92This callback function is called by 93[jerry_debugger_wait_for_client_source](#jerry_debugger_wait_for_client_source) 94when a source code is received successfully. 95 96**Prototype** 97 98```c 99typedef jerry_value_t 100(*jerry_debugger_wait_for_source_callback_t) (const jerry_char_t *resource_name_p, 101 size_t resource_name_size, 102 const jerry_char_t *source_p, 103 size_t source_size, void *user_p); 104``` 105 106- `resource_name_p` - resource (usually a file) name of the source code 107- `resource_name_size` - size of resource name 108- `source_p` - source code character data 109- `source_size` - size of source code 110- `user_p` - custom pointer passed to [jerry_debugger_wait_for_client_source](#jerry_debugger_wait_for_client_source) 111 112 113## JerryScript debugger functions 114 115### jerry_debugger_is_connected 116 117**Summary** 118 119Returns true if a remote debugger client is connected. 120 121**Prototype** 122 123```c 124bool 125jerry_debugger_is_connected (void); 126``` 127 128**Example** 129 130[doctest]: # (test="link") 131 132```c 133#include "jerryscript.h" 134#include "jerryscript-ext/debugger.h" 135 136int 137main (void) 138{ 139 jerry_init (JERRY_INIT_EMPTY); 140 jerryx_debugger_after_connect (jerryx_debugger_tcp_create (5001) 141 && jerryx_debugger_ws_create ()); 142 143 if (jerry_debugger_is_connected ()) 144 { 145 printf ("A remote debugger client is connected."); 146 } 147 148 jerry_cleanup (); 149} 150``` 151 152### jerry_debugger_stop 153 154**Summary** 155 156Stops execution at the next available breakpoint if a remote 157debugger client is connected and the engine is not waiting at 158a breakpoint. The engine will stop regardless the breakpoint 159is enabled or not. 160 161**Prototype** 162 163```c 164void 165jerry_debugger_stop (void) 166``` 167 168**Example** 169 170[doctest]: # (test="link") 171 172```c 173#include "jerryscript.h" 174#include "jerryscript-ext/debugger.h" 175 176int 177main (void) 178{ 179 jerry_init (JERRY_INIT_EMPTY); 180 jerryx_debugger_after_connect (jerryx_debugger_tcp_create (5001) 181 && jerryx_debugger_ws_create ()); 182 183 jerry_debugger_stop (); 184 185 jerry_cleanup (); 186} 187``` 188 189**See also** 190 191- [jerry_debugger_continue](#jerry_debugger_continue) 192 193### jerry_debugger_continue 194 195**Summary** 196 197If the engine would stop at the next available breakpoint it 198cancels this effect. The engine will still stop at enabled 199breakpoints. This function effectively negates the effect of 200[jerry_debugger_stop ()](#jerry_debugger_stop) calls or stop 201requests issued by the debugger client. 202 203**Prototype** 204 205```c 206void 207jerry_debugger_continue (void) 208``` 209 210**Example** 211 212[doctest]: # (test="link") 213 214```c 215#include "jerryscript.h" 216#include "jerryscript-ext/debugger.h" 217 218int 219main (void) 220{ 221 jerry_init (JERRY_INIT_EMPTY); 222 jerryx_debugger_after_connect (jerryx_debugger_tcp_create (5001) 223 && jerryx_debugger_ws_create ()); 224 225 jerry_debugger_continue (); 226 227 jerry_cleanup (); 228} 229``` 230 231**See also** 232 233- [jerry_debugger_stop](#jerry_debugger_stop) 234 235### jerry_debugger_stop_at_breakpoint 236 237**Summary** 238 239Enables or disables stopping at breakpoints. When stopping is 240disabled all breakpoints are ignored including user enabled 241breakpoints. This allows hidden execution of ECMAScript code. 242 243**Prototype** 244 245```c 246void 247jerry_debugger_stop_at_breakpoint (bool enable_stop_at_breakpoint) 248``` 249 250- `enable_stop_at_breakpoint` - enable (=`true`) or disable (=`false`) stopping at breakpoints 251 252**Example** 253 254[doctest]: # (test="link") 255 256```c 257#include "jerryscript.h" 258#include "jerryscript-ext/debugger.h" 259 260int 261main (void) 262{ 263 jerry_init (JERRY_INIT_EMPTY); 264 jerryx_debugger_after_connect (jerryx_debugger_tcp_create (5001) 265 && jerryx_debugger_ws_create ()); 266 267 jerry_debugger_stop_at_breakpoint (true); 268 269 // Protected execution of JavaScript code. 270 const jerry_char_t script[] = "42"; 271 jerry_eval (script, sizeof (script) - 1, JERRY_PARSE_NO_OPTS); 272 273 jerry_debugger_stop_at_breakpoint (false); 274 275 jerry_cleanup (); 276} 277``` 278 279### jerry_debugger_wait_for_client_source 280 281**Summary** 282 283Asks the client to provide the next source code. The function 284waits until the whole source code is received. As a reply the 285the client may request a context reset or notify that no more 286source is available. These notifications are passed back as the 287return value of the function. 288 289**Prototype** 290 291```c 292jerry_debugger_wait_for_source_status_t 293jerry_debugger_wait_for_client_source (jerry_debugger_wait_for_source_callback_t callback_p, 294 void *user_p, jerry_value_t *return_value) 295``` 296 297**Example** 298 299[doctest]: # (test="link") 300 301```c 302#include "jerryscript.h" 303#include "jerryscript-ext/debugger.h" 304 305/** 306 * Runs the source code received by jerry_debugger_wait_for_client_source. 307 */ 308static jerry_value_t 309wait_for_source_callback (const jerry_char_t *resource_name_p, /**< resource name */ 310 size_t resource_name_size, /**< size of resource name */ 311 const jerry_char_t *source_p, /**< source code */ 312 size_t source_size, /**< source code size */ 313 void *user_p /**< user pointer */) 314{ 315 (void) user_p; 316 317 jerry_value_t ret_val = jerry_parse (resource_name_p, 318 resource_name_size, 319 source_p, 320 source_size, 321 JERRY_PARSE_NO_OPTS); 322 323 if (!jerry_value_is_error (ret_val)) 324 { 325 jerry_value_t func_val = ret_val; 326 ret_val = jerry_run (func_val); 327 jerry_release_value (func_val); 328 } 329 330 return ret_val; 331} /* wait_for_source_callback */ 332 333int 334main (void) 335{ 336 jerry_debugger_wait_for_source_status_t receive_status; 337 338 do 339 { 340 /* Create a new JerryScript instance when a context reset is 341 * received. Applications usually registers their core bindings 342 * here as well (e.g. print, setTimeout). */ 343 jerry_init (JERRY_INIT_EMPTY); 344 jerryx_debugger_after_connect (jerryx_debugger_tcp_create (5001) 345 && jerryx_debugger_ws_create ()); 346 347 do 348 { 349 jerry_value_t run_result; 350 351 receive_status = jerry_debugger_wait_for_client_source (wait_for_source_callback, 352 NULL, 353 &run_result); 354 355 jerry_release_value (run_result); 356 } 357 while (receive_status == JERRY_DEBUGGER_SOURCE_RECEIVED); 358 359 jerry_cleanup (); 360 } 361 while (receive_status == JERRY_DEBUGGER_CONTEXT_RESET_RECEIVED); 362 363 if (receive_status == JERRY_DEBUGGER_SOURCE_RECEIVE_FAILED) 364 { 365 // Handle the failure (e.g. display an error). 366 } 367 return 0; 368} 369``` 370 371### jerry_debugger_send_output 372 373**Summary** 374 375Sends the program's output to the debugger client. 376 377**Prototype** 378 379```c 380void 381jerry_debugger_send_output (const jerry_char_t *buffer, jerry_size_t string_size) 382``` 383 384**Example** 385 386[doctest]: # (test="link") 387 388```c 389#include "jerryscript.h" 390#include "jerryscript-ext/debugger.h" 391 392int 393main (void) 394{ 395 jerry_init (JERRY_INIT_EMPTY); 396 jerryx_debugger_after_connect (jerryx_debugger_tcp_create (5001) 397 && jerryx_debugger_ws_create ()); 398 399 jerry_char_t my_output[] = "Hey, this should be sent too!"; 400 jerry_size_t my_output_size = sizeof (my_output); 401 402 jerry_debugger_send_output (my_output, my_output_size); 403 404 jerry_cleanup (); 405} 406``` 407 408### jerry_debugger_send_log 409 410**Summary** 411 412Sends the program's log to the debugger client. 413 414**Prototype** 415 416```c 417void 418jerry_debugger_send_log (jerry_log_level_t level, const jerry_char_t *buffer, jerry_size_t string_size) 419``` 420 421**Example** 422 423[doctest]: # (test="link") 424 425```c 426#include "jerryscript.h" 427#include "jerryscript-ext/debugger.h" 428 429int 430main (void) 431{ 432 jerry_init (JERRY_INIT_EMPTY); 433 jerryx_debugger_after_connect (jerryx_debugger_tcp_create (5001) 434 && jerryx_debugger_ws_create ()); 435 436 jerry_char_t my_log[] = "Custom diagnostics"; 437 jerry_size_t my_log_size = sizeof (my_log); 438 439 jerry_debugger_send_log (JERRY_LOG_LEVEL_DEBUG, my_log, my_log_size); 440 441 jerry_cleanup (); 442} 443``` 444