ruby-debug-base19 0.11.18 → 0.11.19

Sign up to get free protection for your applications and to get access to all the features.
@@ -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