ruby-debug-base19 0.11.18 → 0.11.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,6 @@
1
1
  #include <ruby.h>
2
2
  #include <stdio.h>
3
+ #include <ctype.h>
3
4
  #include <vm_core.h>
4
5
  #include <iseq.h>
5
6
  #include <version.h>
@@ -43,6 +44,7 @@ static debug_context_t *last_debug_context = NULL;
43
44
  VALUE rdebug_threads_tbl = Qnil; /* Context for each of the threads */
44
45
  VALUE mDebugger; /* Ruby Debugger Module object */
45
46
 
47
+ static VALUE opt_call_c_function;
46
48
  static VALUE cThreadsTable;
47
49
  static VALUE cContext;
48
50
  static VALUE cDebugThread;
@@ -71,7 +73,6 @@ static VALUE context_copy_locals(debug_context_t *,debug_frame_t *, VALUE);
71
73
  static void context_suspend_0(debug_context_t *);
72
74
  static void context_resume_0(debug_context_t *);
73
75
  static void copy_scalar_args(debug_frame_t *);
74
- static void debug_event_hook(rb_event_flag_t event, VALUE data, VALUE self, ID mid, VALUE klass);
75
76
 
76
77
  typedef struct locked_thread_t {
77
78
  VALUE thread_id;
@@ -383,6 +384,8 @@ debug_context_create(VALUE thread)
383
384
  debug_context->stack_size = 0;
384
385
  debug_context->thread_id = ref2id(thread);
385
386
  debug_context->breakpoint = Qnil;
387
+ debug_context->jump_pc = NULL;
388
+ debug_context->jump_cfp = NULL;
386
389
  if(rb_obj_class(thread) == cDebugThread)
387
390
  CTX_FL_SET(debug_context, CTX_FL_IGNORE);
388
391
  return Data_Wrap_Struct(cContext, debug_context_mark, debug_context_free, debug_context);
@@ -418,7 +421,7 @@ debug_context_dup(debug_context_t *debug_context, VALUE self)
418
421
  }
419
422
 
420
423
  static void
421
- thread_context_lookup(VALUE thread, VALUE *context, debug_context_t **debug_context)
424
+ thread_context_lookup(VALUE thread, VALUE *context, debug_context_t **debug_context, int create)
422
425
  {
423
426
  threads_table_t *threads_table;
424
427
  VALUE thread_id;
@@ -437,8 +440,18 @@ thread_context_lookup(VALUE thread, VALUE *context, debug_context_t **debug_cont
437
440
  Data_Get_Struct(rdebug_threads_tbl, threads_table_t, threads_table);
438
441
  if(!st_lookup(threads_table->tbl, thread_id, context))
439
442
  {
440
- *context = debug_context_create(thread);
441
- st_insert(threads_table->tbl, thread_id, *context);
443
+ if (create)
444
+ {
445
+ *context = debug_context_create(thread);
446
+ st_insert(threads_table->tbl, thread_id, *context);
447
+ }
448
+ else
449
+ {
450
+ *context = 0;
451
+ if (debug_context)
452
+ *debug_context = NULL;
453
+ return;
454
+ }
442
455
  }
443
456
 
444
457
  Data_Get_Struct(*context, debug_context_t, l_debug_context);
@@ -709,7 +722,7 @@ debug_event_hook(rb_event_flag_t event, VALUE data, VALUE self, ID mid, VALUE kl
709
722
 
710
723
  if ((iseq == NULL) && (event != RUBY_EVENT_RAISE))
711
724
  return;
712
- thread_context_lookup(thread->self, &context, &debug_context);
725
+ thread_context_lookup(thread->self, &context, &debug_context, 1);
713
726
 
714
727
  if ((event == RUBY_EVENT_LINE) || (event == RUBY_EVENT_CALL))
715
728
  {
@@ -803,12 +816,7 @@ debug_event_hook(rb_event_flag_t event, VALUE data, VALUE self, ID mid, VALUE kl
803
816
  else
804
817
  set_frame_source(event, debug_context, self, file, line, mid);
805
818
 
806
- if (CTX_FL_TEST(debug_context, CTX_FL_JUMPING))
807
- {
808
- CTX_FL_UNSET(debug_context, CTX_FL_JUMPING);
809
- break;
810
- }
811
- else if (CTX_FL_TEST(debug_context, CTX_FL_CATCHING))
819
+ if (CTX_FL_TEST(debug_context, CTX_FL_CATCHING))
812
820
  {
813
821
  debug_frame_t *top_frame = get_top_frame(debug_context);
814
822
 
@@ -1195,7 +1203,7 @@ debug_current_context(VALUE self)
1195
1203
  debug_check_started();
1196
1204
 
1197
1205
  thread = rb_thread_current();
1198
- thread_context_lookup(thread, &context, NULL);
1206
+ thread_context_lookup(thread, &context, NULL, 1);
1199
1207
 
1200
1208
  return context;
1201
1209
  }
@@ -1212,7 +1220,7 @@ debug_thread_context(VALUE self, VALUE thread)
1212
1220
  VALUE context;
1213
1221
 
1214
1222
  debug_check_started();
1215
- thread_context_lookup(thread, &context, NULL);
1223
+ thread_context_lookup(thread, &context, NULL, 1);
1216
1224
  return context;
1217
1225
  }
1218
1226
 
@@ -1239,7 +1247,7 @@ debug_contexts(VALUE self)
1239
1247
  for(i = 0; i < RARRAY_LEN(list); i++)
1240
1248
  {
1241
1249
  thread = rb_ary_entry(list, i);
1242
- thread_context_lookup(thread, &context, NULL);
1250
+ thread_context_lookup(thread, &context, NULL, 1);
1243
1251
  rb_ary_push(new_list, context);
1244
1252
  }
1245
1253
  threads_table_clear(rdebug_threads_tbl);
@@ -1271,7 +1279,7 @@ debug_suspend(VALUE self)
1271
1279
  debug_check_started();
1272
1280
 
1273
1281
  context_list = debug_contexts(self);
1274
- thread_context_lookup(rb_thread_current(), &current, NULL);
1282
+ thread_context_lookup(rb_thread_current(), &current, NULL, 1);
1275
1283
 
1276
1284
  for(i = 0; i < RARRAY_LEN(context_list); i++)
1277
1285
  {
@@ -1303,7 +1311,7 @@ debug_resume(VALUE self)
1303
1311
 
1304
1312
  context_list = debug_contexts(self);
1305
1313
 
1306
- thread_context_lookup(rb_thread_current(), &current, NULL);
1314
+ thread_context_lookup(rb_thread_current(), &current, NULL, 1);
1307
1315
  for(i = 0; i < RARRAY_LEN(context_list); i++)
1308
1316
  {
1309
1317
  context = rb_ary_entry(context_list, i);
@@ -1440,7 +1448,7 @@ debug_set_debug(VALUE self, VALUE value)
1440
1448
  static VALUE
1441
1449
  debug_thread_inherited(VALUE klass)
1442
1450
  {
1443
- rb_raise(rb_eRuntimeError, "Can't inherit Debugger::DebugThread class");
1451
+ rb_raise(rb_eRuntimeError, "Can't inherit Debugger::DebugThread class");
1444
1452
  }
1445
1453
 
1446
1454
  /*
@@ -1755,12 +1763,32 @@ context_frame_line(int argc, VALUE *argv, VALUE self)
1755
1763
  {
1756
1764
  VALUE frame;
1757
1765
  debug_context_t *debug_context;
1766
+ debug_frame_t *debug_frame;
1767
+ rb_control_frame_t *cfp;
1768
+ rb_control_frame_t *cfp_end;
1769
+ rb_thread_t *th;
1770
+ VALUE *pc;
1758
1771
 
1759
1772
  debug_check_started();
1760
1773
  frame = optional_frame_position(argc, argv);
1761
1774
  Data_Get_Struct(self, debug_context_t, debug_context);
1775
+ GetThreadPtr(context_thread_0(debug_context), th);
1776
+
1777
+ debug_frame = get_top_frame(debug_context);
1778
+ if (debug_frame == NULL)
1779
+ return(INT2FIX(0));
1762
1780
 
1763
- return(INT2FIX(rb_vm_get_sourceline(GET_FRAME->info.runtime.cfp)));
1781
+ pc = GET_FRAME->info.runtime.last_pc;
1782
+ cfp_end = RUBY_VM_END_CONTROL_FRAME(th);
1783
+ cfp = GET_FRAME->info.runtime.cfp;
1784
+ while (cfp > (rb_control_frame_t*)th->stack)
1785
+ {
1786
+ if ((cfp->iseq != NULL) && (pc >= cfp->iseq->iseq_encoded) && (pc < cfp->iseq->iseq_encoded + cfp->iseq->iseq_size))
1787
+ return(INT2FIX(rb_vm_get_sourceline(cfp)));
1788
+ cfp = RUBY_VM_NEXT_CONTROL_FRAME(cfp);
1789
+ }
1790
+
1791
+ return(INT2FIX(0));
1764
1792
  }
1765
1793
 
1766
1794
  /*
@@ -1883,7 +1911,7 @@ context_copy_locals(debug_context_t *debug_context, debug_frame_t *debug_frame,
1883
1911
  {
1884
1912
  rb_thread_t *th;
1885
1913
  rb_control_frame_t *block_frame = RUBY_VM_NEXT_CONTROL_FRAME(cfp);
1886
- Data_Get_Struct(context_thread_0(debug_context), rb_thread_t, th);
1914
+ GetThreadPtr(context_thread_0(debug_context), th);
1887
1915
  while (block_frame > (rb_control_frame_t*)th->stack)
1888
1916
  {
1889
1917
  if (block_frame->iseq == cfp->block_iseq)
@@ -2243,6 +2271,32 @@ context_stop_reason(VALUE self)
2243
2271
  return ID2SYM(rb_intern(sym_name));
2244
2272
  }
2245
2273
 
2274
+ static rb_control_frame_t *
2275
+ FUNC_FASTCALL(do_jump)(rb_thread_t *th, rb_control_frame_t *cfp)
2276
+ {
2277
+ VALUE context;
2278
+ debug_context_t *debug_context;
2279
+
2280
+ thread_context_lookup(th->self, &context, &debug_context, 0);
2281
+ if (debug_context == NULL)
2282
+ rb_raise(rb_eRuntimeError, "Lost context in jump");
2283
+ cfp->pc[-2] = debug_context->saved_jump_ins[0];
2284
+ cfp->pc[-1] = debug_context->saved_jump_ins[1];
2285
+
2286
+ cfp = debug_context->jump_cfp;
2287
+ if ((debug_context->jump_pc < cfp->iseq->iseq_encoded) || (debug_context->jump_pc >= cfp->iseq->iseq_encoded + cfp->iseq->iseq_size))
2288
+ rb_raise(rb_eRuntimeError, "Invalid jump PC target");
2289
+ cfp->pc = debug_context->jump_pc;
2290
+
2291
+ debug_context->jump_pc = NULL;
2292
+ debug_context->jump_cfp = NULL;
2293
+ debug_context->last_line = 0;
2294
+ debug_context->last_file = NULL;
2295
+ debug_context->stop_next = 1;
2296
+ th->cfp = cfp;
2297
+ return(cfp);
2298
+ }
2299
+
2246
2300
  /*
2247
2301
  * call-seq:
2248
2302
  * context.jump(line, file) -> bool
@@ -2255,39 +2309,74 @@ context_jump(int argc, VALUE *argv, VALUE self)
2255
2309
  debug_context_t *debug_context;
2256
2310
  debug_frame_t *debug_frame;
2257
2311
  VALUE line, file;
2258
- const char *file_str;
2259
2312
  int i;
2260
- struct rb_iseq_struct *iseq;
2313
+ rb_thread_t *th;
2314
+ rb_control_frame_t *cfp;
2315
+ rb_control_frame_t *cfp_end;
2316
+ rb_control_frame_t *cfp_start = NULL;
2317
+
2318
+ debug_check_started();
2261
2319
 
2262
2320
  Data_Get_Struct(self, debug_context_t, debug_context);
2321
+ GetThreadPtr(context_thread_0(debug_context), th);
2263
2322
  debug_frame = get_top_frame(debug_context);
2323
+ if (debug_frame == NULL)
2324
+ rb_raise(rb_eRuntimeError, "No frames collected.");
2264
2325
 
2265
- if ((argc <= 0) || (argc > 2))
2266
- rb_raise(rb_eArgError, "wrong number of arguments (%d for 1 or 2)", argc);
2267
- rb_scan_args(argc, argv, "11", &line, &file);
2326
+ if (argc != 2)
2327
+ rb_raise(rb_eArgError, "wrong number of arguments (%d for 2)", argc);
2328
+ rb_scan_args(argc, argv, "2", &line, &file);
2268
2329
 
2269
2330
  line = FIX2INT(line);
2270
- if (file == Qnil)
2271
- file_str = debug_frame->file;
2272
- else
2273
- file_str = RSTRING_PTR(file);
2274
2331
 
2275
- iseq = debug_frame->info.runtime.cfp->iseq;
2276
- for (i = 0; i < iseq->insn_info_size; i++)
2332
+ /* find topmost frame of the debugged code */
2333
+ cfp = th->cfp;
2334
+ cfp_end = RUBY_VM_END_CONTROL_FRAME(th);
2335
+ while (RUBY_VM_VALID_CONTROL_FRAME_P(cfp, cfp_end))
2277
2336
  {
2278
- if (iseq->insn_info_table[i].line_no == line)
2337
+ if (cfp->pc == debug_frame->info.runtime.last_pc)
2279
2338
  {
2280
- if (*debug_frame->info.runtime.cfp->pc == BIN(pop))
2281
- debug_frame->info.runtime.cfp->sp--;
2282
- debug_frame->info.runtime.cfp->pc =
2283
- iseq->iseq_encoded + iseq->insn_info_table[i].position;
2284
- CTX_FL_SET(debug_context, CTX_FL_JUMPING);
2285
- return Qtrue;
2339
+ cfp_start = cfp;
2340
+ if ((cfp->pc - cfp->iseq->iseq_encoded) >= (cfp->iseq->iseq_size - 1))
2341
+ return(INT2FIX(1)); /* no space for opt_call_c_function hijack */
2342
+ break;
2286
2343
  }
2344
+ cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
2287
2345
  }
2288
- return Qfalse;
2346
+ if (cfp_start == NULL)
2347
+ return(INT2FIX(2)); /* couldn't find frame; should never happen */
2348
+
2349
+ /* find target frame to jump to */
2350
+ while (RUBY_VM_VALID_CONTROL_FRAME_P(cfp, cfp_end))
2351
+ {
2352
+ if ((cfp->iseq != NULL) && (rb_str_cmp(file, cfp->iseq->filename) == 0))
2353
+ {
2354
+ for (i = 0; i < cfp->iseq->insn_info_size; i++)
2355
+ {
2356
+ if (cfp->iseq->insn_info_table[i].line_no != line)
2357
+ continue;
2358
+
2359
+ /* hijack the currently running code so that we can change the frame PC(s) */
2360
+ debug_context->saved_jump_ins[0] = cfp_start->pc[0];
2361
+ debug_context->saved_jump_ins[1] = cfp_start->pc[1];
2362
+ cfp_start->pc[0] = opt_call_c_function;
2363
+ cfp_start->pc[1] = (VALUE)do_jump;
2364
+
2365
+ debug_context->jump_cfp = cfp;
2366
+ debug_context->jump_pc =
2367
+ cfp->iseq->iseq_encoded + cfp->iseq->insn_info_table[i].position;
2368
+
2369
+ return(INT2FIX(0)); /* success */
2370
+ }
2371
+ }
2372
+
2373
+ cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
2374
+ }
2375
+
2376
+ return(INT2FIX(3)); /* couldn't find a line and file frame match */
2289
2377
  }
2290
2378
 
2379
+
2291
2380
  /*
2292
2381
  * Document-class: Context
2293
2382
  *
@@ -2378,6 +2467,19 @@ debug_add_breakpoint(int argc, VALUE *argv, VALUE self)
2378
2467
  void
2379
2468
  Init_ruby_debug()
2380
2469
  {
2470
+ rb_iseq_t iseq;
2471
+ iseq.iseq = &opt_call_c_function;
2472
+ iseq.iseq_size = 1;
2473
+ iseq.iseq_encoded = NULL;
2474
+
2475
+ opt_call_c_function = (VALUE)BIN(opt_call_c_function);
2476
+ rb_iseq_translate_threaded_code(&iseq);
2477
+ if (iseq.iseq_encoded != iseq.iseq)
2478
+ {
2479
+ opt_call_c_function = iseq.iseq_encoded[0];
2480
+ xfree(iseq.iseq_encoded);
2481
+ }
2482
+
2381
2483
  mDebugger = rb_define_module("Debugger");
2382
2484
  rb_define_const(mDebugger, "VERSION", rb_str_new2(DEBUG_VERSION));
2383
2485
  rb_define_module_function(mDebugger, "start_", debug_start, 0);
@@ -13,7 +13,6 @@ enum ctx_stop_reason {CTX_STOP_NONE, CTX_STOP_STEP, CTX_STOP_BREAKPOINT,
13
13
  #define CTX_FL_STEPPED (1<<8)
14
14
  #define CTX_FL_FORCE_MOVE (1<<9)
15
15
  #define CTX_FL_CATCHING (1<<10)
16
- #define CTX_FL_JUMPING (1<<11)
17
16
 
18
17
  #define CTX_FL_TEST(c,f) ((c)->flags & (f))
19
18
  #define CTX_FL_SET(c,f) do { (c)->flags |= (f); } while (0)
@@ -69,6 +68,9 @@ typedef struct {
69
68
  int last_line;
70
69
  VALUE breakpoint;
71
70
  debug_catch_t catch_table;
71
+ VALUE saved_jump_ins[2];
72
+ rb_control_frame_t *jump_cfp;
73
+ VALUE *jump_pc;
72
74
  } debug_context_t;
73
75
 
74
76
  /* variables in ruby_debug.c */
@@ -90,7 +90,7 @@ module Debugger
90
90
  end
91
91
 
92
92
  def source_reload
93
- LineCache::clear_file_cache(true)
93
+ LineCache::clear_file_cache
94
94
  end
95
95
 
96
96
  # Get line +line_number+ from file named +filename+. Return "\n"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-debug-base19
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.11.18
4
+ version: 0.11.19
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kent Sibilev
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2009-08-30 00:00:00 -07:00
13
+ date: 2009-09-01 00:00:00 -07:00
14
14
  default_executable:
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency