Module: Debugger
- Defined in:
- ext/ruby_debug/ruby_debug.c
Constant Summary collapse
- VERSION =
rb_str_new2(DEBUG_VERSION)
Class Method Summary collapse
-
.add_breakpoint(source, pos, condition = nil) ⇒ Object
Adds a new breakpoint.
-
.catchpoint(string) ⇒ String
Sets catchpoint.
-
.breakpoints ⇒ Array
Returns an array of breakpoints.
-
.catchpoints ⇒ Hash
Returns a current catchpoints, which is a hash exception names that will trigger a debugger when raised.
-
.contexts ⇒ Array
Returns an array of all contexts.
-
.current_context ⇒ Object
Returns current context.
-
.debug ⇒ Object
:nodoc:.
-
.debug=(value) ⇒ Object
:nodoc:.
-
.debug_at_exit { ... } ⇒ Proc
Register
at_exit
hook which is escaped from the debugger. -
.debug_load(file, stop = false, increment_start = false) ⇒ nil
Same as Kernel#load but resets current context’s frames.
-
.keep_frame_binding=(bool) ⇒ Object
Setting to
true
will make the debugger create frame bindings. -
.keep_frame_binding? ⇒ Boolean
Returns
true
if the debugger will collect frame bindings. -
.last_interrupted ⇒ Object
Returns last debugged context.
-
.post_mortem=(bool) ⇒ Object
Sets post-moterm flag.
-
.post_mortem? ⇒ Boolean
Returns
true
if post-moterm debugging is enabled. -
.remove_breakpoint(id) ⇒ Object
Removes breakpoint by its id.
-
.resolve_symlinks=(bool) ⇒ Object
Setting to
true
will make the debugger resolve symlinks when checking breakpoint. -
.resolve_symlinks? ⇒ Boolean
Returns
true
if the debugger will resolve symlinks when checking breakpoint. -
.resume ⇒ Debugger
Resumes all contexts.
-
.skip { ... } ⇒ Object?
The code inside of the block is escaped from the debugger.
-
.start_ ⇒ Object
This method is internal and activates the debugger.
-
.started? ⇒ Boolean
Returns
true
the debugger is started. -
.stop ⇒ Boolean
This method disables the debugger.
-
.suspend ⇒ Debugger
Suspends all contexts.
-
.thread_context(thread) ⇒ Object
Returns context of the thread passed as an argument.
-
.tracing ⇒ Boolean
Returns
true
if the global tracing is activated. -
.tracing=(bool) ⇒ Object
Sets the global tracing flag.
-
.track_frame_args=(bool) ⇒ Object
Setting to
true
will make the debugger save argument info on calls. -
.track_fame_args? ⇒ Boolean
Returns
true
if the debugger track frame argument values on calls.
Class Method Details
.add_breakpoint(source, pos, condition = nil) ⇒ Object
Adds a new breakpoint. source is a name of a file or a class. pos is a line number or a method name if source is a class name. condition is a string which is evaluated to true
when this breakpoint is activated.
2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 |
# File 'ext/ruby_debug/ruby_debug.c', line 2640
static VALUE
debug_add_breakpoint(int argc, VALUE *argv, VALUE self)
{
VALUE result;
debug_check_started();
result = create_breakpoint_from_args(argc, argv, ++bkp_count);
rb_ary_push(rdebug_breakpoints, result);
return result;
}
|
.catchpoint(string) ⇒ String
Sets catchpoint. Returns the string passed.
249 250 251 252 253 254 255 256 257 258 259 |
# File 'ext/ruby_debug/breakpoint.c', line 249
VALUE
rdebug_add_catchpoint(VALUE self, VALUE value)
{
debug_check_started();
if (TYPE(value) != T_STRING) {
rb_raise(rb_eTypeError, "value of a catchpoint must be String");
}
rb_hash_aset(rdebug_catchpoints, rb_str_dup(value), INT2FIX(0));
return value;
}
|
.breakpoints ⇒ Array
Returns an array of breakpoints.
2622 2623 2624 2625 2626 2627 2628 |
# File 'ext/ruby_debug/ruby_debug.c', line 2622
static VALUE
debug_breakpoints(VALUE self)
{
debug_check_started();
return rdebug_breakpoints;
}
|
.catchpoints ⇒ Hash
Returns a current catchpoints, which is a hash exception names that will trigger a debugger when raised. The values are the number of times taht catchpoint was hit, initially 0.
235 236 237 238 239 240 241 |
# File 'ext/ruby_debug/breakpoint.c', line 235
VALUE
debug_catchpoints(VALUE self)
{
debug_check_started();
return rdebug_catchpoints;
}
|
.contexts ⇒ Array
Returns an array of all contexts.
1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 |
# File 'ext/ruby_debug/ruby_debug.c', line 1310
static VALUE
debug_contexts(VALUE self)
{
volatile VALUE list;
volatile VALUE new_list;
VALUE thread, context;
threads_table_t *threads_table;
debug_context_t *debug_context;
int i;
debug_check_started();
new_list = rb_ary_new();
list = rb_funcall(rb_cThread, idList, 0);
for(i = 0; i < RARRAY_LEN(list); i++)
{
thread = rb_ary_entry(list, i);
thread_context_lookup(thread, &context, NULL, 1);
rb_ary_push(new_list, context);
}
threads_table_clear(rdebug_threads_tbl);
Data_Get_Struct(rdebug_threads_tbl, threads_table_t, threads_table);
for(i = 0; i < RARRAY_LEN(new_list); i++)
{
context = rb_ary_entry(new_list, i);
Data_Get_Struct(context, debug_context_t, debug_context);
st_insert(threads_table->tbl, debug_context->thread_id, context);
}
return new_list;
}
|
.current_context ⇒ Object
Returns current context. Note: Debugger.current_context.thread == Thread.current
1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 |
# File 'ext/ruby_debug/ruby_debug.c', line 1275
static VALUE
debug_current_context(VALUE self)
{
VALUE thread, context;
debug_check_started();
thread = rb_thread_current();
thread_context_lookup(thread, &context, NULL, 1);
return context;
}
|
.debug ⇒ Object
:nodoc:
1535 1536 1537 1538 1539 |
# File 'ext/ruby_debug/ruby_debug.c', line 1535
static VALUE
debug_debug(VALUE self)
{
return debug;
}
|
.debug=(value) ⇒ Object
:nodoc:
1542 1543 1544 1545 1546 1547 |
# File 'ext/ruby_debug/ruby_debug.c', line 1542
static VALUE
debug_set_debug(VALUE self, VALUE value)
{
debug = RTEST(value) ? Qtrue : Qfalse;
return value;
}
|
.debug_at_exit { ... } ⇒ Proc
Register at_exit
hook which is escaped from the debugger. FOR INTERNAL USE ONLY.
1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 |
# File 'ext/ruby_debug/ruby_debug.c', line 1672
static VALUE
debug_at_exit(VALUE self)
{
VALUE proc;
if (!rb_block_given_p())
rb_raise(rb_eArgError, "called without a block");
proc = rb_block_proc();
rb_set_end_proc(debug_at_exit_i, proc);
return proc;
}
|
.debug_load(file, stop = false, increment_start = false) ⇒ nil
Same as Kernel#load but resets current context’s frames. stop
parameter forces the debugger to stop at the first line of code in the file
increment_start
determines if start_count should be incremented. When
control threads are used, they have to be set up before loading the
debugger; so here +increment_start+ will be false.
FOR INTERNAL USE ONLY.
1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 |
# File 'ext/ruby_debug/ruby_debug.c', line 1567
static VALUE
debug_debug_load(int argc, VALUE *argv, VALUE self)
{
VALUE file, stop, context, increment_start;
debug_context_t *debug_context;
int state = 0;
if(rb_scan_args(argc, argv, "12", &file, &stop, &increment_start) == 1)
{
stop = Qfalse;
increment_start = Qtrue;
}
debug_start(self);
if (Qfalse == increment_start) start_count--;
context = debug_current_context(self);
Data_Get_Struct(context, debug_context_t, debug_context);
debug_context->stack_size = 0;
if(RTEST(stop))
debug_context->stop_next = 1;
/* Initializing $0 to the script's path */
ruby_script(RSTRING_PTR(file));
rb_load_protect(file, 0, &state);
if (0 != state)
{
VALUE errinfo = rb_errinfo();
debug_suspend(self);
reset_stepping_stop_points(debug_context);
rb_set_errinfo(Qnil);
return errinfo;
}
/* We should run all at_exit handler's in order to provide,
* for instance, a chance to run all defined test cases */
rb_exec_end_proc();
/* We could have issued a Debugger.stop inside the debug
session. */
if (start_count > 0)
debug_stop(self);
return Qnil;
}
|
.keep_frame_binding=(bool) ⇒ Object
Setting to true
will make the debugger create frame bindings.
1502 1503 1504 1505 1506 1507 |
# File 'ext/ruby_debug/ruby_debug.c', line 1502
static VALUE
debug_set_keep_frame_binding(VALUE self, VALUE value)
{
keep_frame_binding = RTEST(value) ? Qtrue : Qfalse;
return value;
}
|
.keep_frame_binding? ⇒ Boolean
Returns true
if the debugger will collect frame bindings.
1490 1491 1492 1493 1494 |
# File 'ext/ruby_debug/ruby_debug.c', line 1490
static VALUE
debug_keep_frame_binding(VALUE self)
{
return keep_frame_binding;
}
|
.last_interrupted ⇒ Object
Returns last debugged context.
1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 |
# File 'ext/ruby_debug/ruby_debug.c', line 1254
static VALUE
debug_last_interrupted(VALUE self)
{
VALUE result = Qnil;
threads_table_t *threads_table;
debug_check_started();
Data_Get_Struct(rdebug_threads_tbl, threads_table_t, threads_table);
st_foreach(threads_table->tbl, find_last_context_func, (st_data_t)&result);
return result;
}
|
.post_mortem=(bool) ⇒ Object
Sets post-moterm flag. FOR INTERNAL USE ONLY.
1450 1451 1452 1453 1454 1455 1456 1457 |
# File 'ext/ruby_debug/ruby_debug.c', line 1450
static VALUE
debug_set_post_mortem(VALUE self, VALUE value)
{
debug_check_started();
post_mortem = RTEST(value) ? Qtrue : Qfalse;
return value;
}
|
.post_mortem? ⇒ Boolean
Returns true
if post-moterm debugging is enabled.
1437 1438 1439 1440 1441 |
# File 'ext/ruby_debug/ruby_debug.c', line 1437
static VALUE
debug_post_mortem(VALUE self)
{
return post_mortem;
}
|
.remove_breakpoint(id) ⇒ Object
Removes breakpoint by its id. id is an identificator of a breakpoint.
204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 |
# File 'ext/ruby_debug/breakpoint.c', line 204
VALUE
rdebug_remove_breakpoint(VALUE self, VALUE id_value)
{
int i;
int id;
VALUE breakpoint;
debug_breakpoint_t *debug_breakpoint;
id = FIX2INT(id_value);
for( i = 0; i < RARRAY_LEN(rdebug_breakpoints); i += 1 )
{
breakpoint = rb_ary_entry(rdebug_breakpoints, i);
Data_Get_Struct(breakpoint, debug_breakpoint_t, debug_breakpoint);
if(debug_breakpoint->id == id)
{
rb_ary_delete_at(rdebug_breakpoints, i);
return breakpoint;
}
}
return Qnil;
}
|
.resolve_symlinks=(bool) ⇒ Object
Setting to true
will make the debugger resolve symlinks when checking breakpoint.
1527 1528 1529 1530 1531 1532 |
# File 'ext/ruby_debug/ruby_debug.c', line 1527
static VALUE
debug_set_resolve_symlinks(VALUE self, VALUE value)
{
resolve_symlinks = RTEST(value) ? Qtrue : Qfalse;
return value;
}
|
.resolve_symlinks? ⇒ Boolean
Returns true
if the debugger will resolve symlinks when checking breakpoint.
1515 1516 1517 1518 1519 |
# File 'ext/ruby_debug/ruby_debug.c', line 1515
static VALUE
debug_resolve_symlinks(VALUE self)
{
return resolve_symlinks;
}
|
.resume ⇒ Debugger
Resumes all contexts.
1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 |
# File 'ext/ruby_debug/ruby_debug.c', line 1379
static VALUE
debug_resume(VALUE self)
{
VALUE current, context;
VALUE context_list;
debug_context_t *debug_context;
int i;
debug_check_started();
context_list = debug_contexts(self);
thread_context_lookup(rb_thread_current(), ¤t, NULL, 1);
for(i = 0; i < RARRAY_LEN(context_list); i++)
{
context = rb_ary_entry(context_list, i);
if(current == context)
continue;
Data_Get_Struct(context, debug_context_t, debug_context);
context_resume_0(debug_context);
}
rb_thread_schedule();
return self;
}
|
.skip { ... } ⇒ Object?
The code inside of the block is escaped from the debugger.
1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 |
# File 'ext/ruby_debug/ruby_debug.c', line 1633
static VALUE
debug_skip(VALUE self)
{
if (!rb_block_given_p()) {
rb_raise(rb_eArgError, "called without a block");
}
if(!IS_STARTED)
return rb_yield(Qnil);
set_current_skipped_status(Qtrue);
return rb_ensure(rb_yield, Qnil, set_current_skipped_status, Qfalse);
}
|
.start_ ⇒ Boolean .start_ { ... } ⇒ Boolean
This method is internal and activates the debugger. Use Debugger.start (from lib/ruby-debug-base.rb
) instead.
The return value is the value of !Debugger.started? before issuing the start
; That is, true
is returned, unless debugger was previously started.
If a block is given, it starts debugger and yields to block. When the block is finished executing it stops the debugger with Debugger.stop method. Inside the block you will probably want to have a call to Debugger.debugger. For example:
Debugger.start{debugger; foo} # Stop inside of foo
Also, ruby-debug only allows one invocation of debugger at a time; nested Debugger.start’s have no effect and you can’t use this inside the debugger itself.
Note that if you want to completely remove the debugger hook, you must call Debugger.stop as many times as you called Debugger.start method.
1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 |
# File 'ext/ruby_debug/ruby_debug.c', line 1177
static VALUE
debug_start(VALUE self)
{
VALUE result;
start_count++;
if(IS_STARTED)
result = Qfalse;
else
{
locker = Qnil;
rdebug_breakpoints = rb_ary_new();
rdebug_catchpoints = rb_hash_new();
rdebug_threads_tbl = threads_table_create();
rb_add_event_hook(debug_event_hook, RUBY_EVENT_ALL, Qnil);
result = Qtrue;
}
if(rb_block_given_p())
rb_ensure(rb_yield, self, debug_stop_i, self);
return result;
}
|
.started? ⇒ Boolean
Returns true
the debugger is started.
323 324 325 326 327 |
# File 'ext/ruby_debug/ruby_debug.c', line 323
static VALUE
debug_is_started(VALUE self)
{
return IS_STARTED ? Qtrue : Qfalse;
}
|
.stop ⇒ Boolean
This method disables the debugger. It returns true
if the debugger is disabled, otherwise it returns false
.
Note that if you want to complete remove the debugger hook, you must call Debugger.stop as many times as you called Debugger.start method.
1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 |
# File 'ext/ruby_debug/ruby_debug.c', line 1213
static VALUE
debug_stop(VALUE self)
{
debug_check_started();
start_count--;
if(start_count)
return Qfalse;
rb_remove_event_hook(debug_event_hook);
locker = Qnil;
rdebug_breakpoints = Qnil;
rdebug_threads_tbl = Qnil;
return Qtrue;
}
|
.suspend ⇒ Debugger
Suspends all contexts.
1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 |
# File 'ext/ruby_debug/ruby_debug.c', line 1348
static VALUE
debug_suspend(VALUE self)
{
VALUE current, context;
VALUE context_list;
debug_context_t *debug_context;
int i;
debug_check_started();
context_list = debug_contexts(self);
thread_context_lookup(rb_thread_current(), ¤t, NULL, 1);
for(i = 0; i < RARRAY_LEN(context_list); i++)
{
context = rb_ary_entry(context_list, i);
if(current == context)
continue;
Data_Get_Struct(context, debug_context_t, debug_context);
context_suspend_0(debug_context);
}
return self;
}
|
.thread_context(thread) ⇒ Object
Returns context of the thread passed as an argument.
1294 1295 1296 1297 1298 1299 1300 1301 1302 |
# File 'ext/ruby_debug/ruby_debug.c', line 1294
static VALUE
debug_thread_context(VALUE self, VALUE thread)
{
VALUE context;
debug_check_started();
thread_context_lookup(thread, &context, NULL, 1);
return context;
}
|
.tracing ⇒ Boolean
Returns true
if the global tracing is activated.
1412 1413 1414 1415 1416 |
# File 'ext/ruby_debug/ruby_debug.c', line 1412
static VALUE
debug_tracing(VALUE self)
{
return tracing;
}
|
.tracing=(bool) ⇒ Object
Sets the global tracing flag.
1424 1425 1426 1427 1428 1429 |
# File 'ext/ruby_debug/ruby_debug.c', line 1424
static VALUE
debug_set_tracing(VALUE self, VALUE value)
{
tracing = RTEST(value) ? Qtrue : Qfalse;
return value;
}
|
.track_frame_args=(bool) ⇒ Object
Setting to true
will make the debugger save argument info on calls.
1477 1478 1479 1480 1481 1482 |
# File 'ext/ruby_debug/ruby_debug.c', line 1477
static VALUE
debug_set_track_frame_args(VALUE self, VALUE value)
{
track_frame_args = RTEST(value) ? Qtrue : Qfalse;
return value;
}
|
.track_fame_args? ⇒ Boolean
Returns true
if the debugger track frame argument values on calls.
1465 1466 1467 1468 1469 |
# File 'ext/ruby_debug/ruby_debug.c', line 1465
static VALUE
debug_track_frame_args(VALUE self)
{
return track_frame_args;
}
|