google-cloud-debugger 0.30.0 → 0.31.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -49,7 +49,7 @@ module Google
49
49
  class Agent
50
50
  ##
51
51
  # Name of the logpoints log file.
52
- DEFAULT_LOG_NAME = "debugger_logpoints"
52
+ DEFAULT_LOG_NAME = "debugger_logpoints".freeze
53
53
 
54
54
  ##
55
55
  # @private Debugger Agent is an asynchronous actor
@@ -182,7 +182,7 @@ module Google
182
182
  breakpoint_manager.sync_active_breakpoints debuggee.id
183
183
  debuggee.revoke_registration unless sync_result
184
184
  end
185
- rescue => e
185
+ rescue StandardError => e
186
186
  warn ["#{e.class}: #{e.message}", e.backtrace].join("\n\t")
187
187
  @last_exception = e
188
188
  end
@@ -242,8 +242,8 @@ module Google
242
242
  project_id = @service.project
243
243
  credentials = @service.credentials
244
244
  logging = Google::Cloud::Logging::Project.new(
245
- Google::Cloud::Logging::Service.new(
246
- project_id, credentials))
245
+ Google::Cloud::Logging::Service.new(project_id, credentials)
246
+ )
247
247
  resource =
248
248
  Google::Cloud::Logging::Middleware.build_monitored_resource
249
249
 
@@ -315,7 +315,7 @@ module Google
315
315
 
316
316
 
317
317
  condition_result ? true : false
318
- rescue => e
318
+ rescue StandardError => e
319
319
  set_error_state "Error: #{e.message}",
320
320
  refers_to: StatusMessage::BREAKPOINT_CONDITION
321
321
  false
@@ -424,7 +424,7 @@ module Google
424
424
  # @private Exports Breakpoint status to
425
425
  # Google::Devtools::Clouddebugger::V2::StatusMessage object
426
426
  def status_to_grpc
427
- status.nil? ? nil: status.to_grpc
427
+ status.nil? ? nil : status.to_grpc
428
428
  end
429
429
 
430
430
  ##
@@ -37,13 +37,13 @@ module Google
37
37
  # Doc](https://cloud.google.com/debugger/api/reference/rpc/google.devtools.clouddebugger.v2#google.devtools.clouddebugger.v2.Breakpoint)
38
38
  # for details.
39
39
  #
40
- module Evaluator
40
+ class Evaluator
41
41
  ##
42
42
  # @private YARV bytecode that the evaluator blocks during expression
43
43
  # evaluation. If the breakpoint contains expressions that uses the
44
44
  # following bytecode, the evaluator will block the expression
45
45
  # evaluation from execusion.
46
- BYTE_CODE_BLACKLIST = %w(
46
+ BYTE_CODE_BLACKLIST = %w[
47
47
  setinstancevariable
48
48
  setclassvariable
49
49
  setconstant
@@ -52,28 +52,28 @@ module Google
52
52
  opt_ltlt
53
53
  opt_aset
54
54
  opt_aset_with
55
- ).freeze
55
+ ].freeze
56
56
 
57
57
  ##
58
58
  # @private YARV bytecode that the evaluator blocks during expression
59
59
  # evaluation on the top level. (not from within by predefined methods)
60
- LOCAL_BYTE_CODE_BLACKLIST = %w(
60
+ LOCAL_BYTE_CODE_BLACKLIST = %w[
61
61
  setlocal
62
- ).freeze
62
+ ].freeze
63
63
 
64
64
  ##
65
65
  # @private YARV bytecode call flags that the evaluator blocks during
66
66
  # expression evaluation
67
- FUNC_CALL_FLAG_BLACKLIST = %w(
67
+ FUNC_CALL_FLAG_BLACKLIST = %w[
68
68
  ARGS_BLOCKARG
69
- ).freeze
69
+ ].freeze
70
70
 
71
71
  ##
72
72
  # @private YARV instructions catch table type that the evaluator
73
73
  # blocks during expression evaluation
74
- CATCH_TABLE_TYPE_BLACKLIST = %w(
75
- rescue
76
- ).freeze
74
+ CATCH_TABLE_TYPE_BLACKLIST = %w[
75
+ rescue StandardError
76
+ ].freeze
77
77
 
78
78
  ##
79
79
  # @private Predefined regex. Saves time during runtime.
@@ -136,638 +136,596 @@ module Google
136
136
  # during expression evaluation
137
137
  C_CLASS_METHOD_WHITELIST = {
138
138
  # Classes
139
- ArgumentError => hashify(%I{
140
- new
141
- }).freeze,
142
- Array => hashify(%I{
143
- new
144
- []
145
- try_convert
146
- }).freeze,
147
- BasicObject => hashify(%I{
148
- new
149
- }).freeze,
150
- Exception => hashify(%I{
151
- exception
152
- new
153
- }).freeze,
154
- Enumerator => hashify(%I{
155
- new
156
- }).freeze,
157
- Fiber => hashify(%I{
158
- current
159
- }).freeze,
160
- FiberError => hashify(%I{
161
- new
162
- }).freeze,
163
- File => hashify(%I{
164
- basename
165
- dirname
166
- extname
167
- join
168
- path
169
- split
170
- }).freeze,
171
- FloatDomainError => hashify(%I{
172
- new
173
- }).freeze,
174
- Hash => hashify(%I{
175
- []
176
- new
177
- try_convert
178
- }).freeze,
179
- IndexError => hashify(%I{
180
- new
181
- }).freeze,
182
- KeyError => hashify(%I{
183
- new
184
- }).freeze,
185
- Module => hashify(%I{
186
- constants
187
- nesting
188
- used_modules
189
- }).freeze,
190
- NameError => hashify(%I{
191
- new
192
- }).freeze,
193
- NoMethodError => hashify(%I{
194
- new
195
- }).freeze,
196
- Object => hashify(%I{
197
- new
198
- }).freeze,
199
- RangeError => hashify(%I{
200
- new
201
- }).freeze,
202
- RegexpError => hashify(%I{
203
- new
204
- }).freeze,
205
- RuntimeError => hashify(%I{
206
- new
207
- }).freeze,
208
- String => hashify(%I{
209
- new
210
- try_convert
211
- }).freeze,
212
- Thread => hashify(%I{
213
- DEBUG
214
- abort_on_exception
215
- current
216
- list
217
- main
218
- pending_interrupt?
219
- report_on_exception
220
- }).freeze,
221
- Time => hashify(%I{
222
- at
223
- gm
224
- local
225
- mktime
226
- new
227
- now
228
- utc
229
- }).freeze,
230
- TypeError => hashify(%I{
231
- new
232
- }).freeze,
233
- Google::Cloud::Debugger::Breakpoint::Evaluator => hashify(%I{
234
- disable_method_trace_for_thread
235
- }).freeze,
236
- ZeroDivisionError => hashify(%I{
237
- new
238
- }).freeze
139
+ ArgumentError => hashify(%I[new]).freeze,
140
+ Array => hashify(%I[new [] try_convert]).freeze,
141
+ BasicObject => hashify(%I[new]).freeze,
142
+ Exception => hashify(%I[exception new]).freeze,
143
+ Enumerator => hashify(%I[new]).freeze,
144
+ Fiber => hashify(%I[current]).freeze,
145
+ FiberError => hashify(%I[new]).freeze,
146
+ File => hashify(
147
+ %I[
148
+ basename
149
+ dirname
150
+ extname
151
+ join
152
+ path
153
+ split
154
+ ]
155
+ ).freeze,
156
+ FloatDomainError => hashify(%I[new]).freeze,
157
+ Hash => hashify(%I[new [] try_convert]).freeze,
158
+ IndexError => hashify(%I[new]).freeze,
159
+ KeyError => hashify(%I[new]).freeze,
160
+ Module => hashify(%I[constants nesting used_modules]).freeze,
161
+ NameError => hashify(%I[new]).freeze,
162
+ NoMethodError => hashify(%I[new]).freeze,
163
+ Object => hashify(%I[new]).freeze,
164
+ RangeError => hashify(%I[new]).freeze,
165
+ RegexpError => hashify(%I[new]).freeze,
166
+ RuntimeError => hashify(%I[new]).freeze,
167
+ String => hashify(%I[new try_convert]).freeze,
168
+ Thread => hashify(
169
+ %I[
170
+ DEBUG
171
+ abort_on_exception
172
+ current
173
+ list
174
+ main
175
+ pending_interrupt?
176
+ report_on_exception
177
+ ]
178
+ ).freeze,
179
+ Time => hashify(
180
+ %I[
181
+ at
182
+ gm
183
+ local
184
+ mktime
185
+ new
186
+ now
187
+ utc
188
+ ]
189
+ ).freeze,
190
+ TypeError => hashify(%I[new]).freeze,
191
+ Google::Cloud::Debugger::Breakpoint::Evaluator => hashify(
192
+ %I[disable_method_trace_for_thread]
193
+ ).freeze,
194
+ ZeroDivisionError => hashify(%I[new]).freeze
239
195
  }.freeze
240
196
 
241
197
  ##
242
198
  # @private List of C level instance methods that the evaluator allows
243
199
  # during expression evaluation
244
200
  C_INSTANCE_METHOD_WHITELIST = {
245
- ArgumentError => hashify(%I{
246
- initialize
247
- }).freeze,
248
- Array => hashify(%I{
249
- initialize
250
- &
251
- *
252
- +
253
- -
254
- <=>
255
- ==
256
- any?
257
- assoc
258
- at
259
- bsearch
260
- bsearch_index
261
- collect
262
- combination
263
- compact
264
- []
265
- count
266
- cycle
267
- dig
268
- drop
269
- drop_while
270
- each
271
- each_index
272
- empty?
273
- eql?
274
- fetch
275
- find_index
276
- first
277
- flatten
278
- frozen?
279
- hash
280
- include?
281
- index
282
- inspect
283
- to_s
284
- join
285
- last
286
- length
287
- map
288
- max
289
- min
290
- pack
291
- permutation
292
- product
293
- rassoc
294
- reject
295
- repeated_combination
296
- repeated_permutation
297
- reverse
298
- reverse_each
299
- rindex
300
- rotate
301
- sample
302
- select
303
- shuffle
304
- size
305
- slice
306
- sort
307
- sum
308
- take
309
- take_while
310
- to_a
311
- to_ary
312
- to_h
313
- transpose
314
- uniq
315
- values_at
316
- zip
317
- |
318
- }).freeze,
319
- BasicObject => hashify(%I{
320
- initialize
321
- !
322
- !=
323
- ==
324
- __id__
325
- method_missing
326
- object_id
327
- send
328
- __send__
329
- equal?
330
- }).freeze,
331
- Binding => hashify(%I{
332
- local_variable_defined?
333
- local_variable_get
334
- local_variables
335
- receiver
336
- }).freeze,
337
- Class => hashify(%I{
338
- superclass
339
- }).freeze,
340
- Dir => hashify(%I{
341
- inspect
342
- path
343
- to_path
344
- }).freeze,
345
- Exception => hashify(%I{
346
- initialize
347
- ==
348
- backtrace
349
- backtrace_locations
350
- cause
351
- exception
352
- inspect
353
- message
354
- to_s
355
- }).freeze,
356
- Enumerator => hashify(%I{
357
- initialize
358
- each
359
- each_with_index
360
- each_with_object
361
- inspect
362
- size
363
- with_index
364
- with_object
365
- }).freeze,
366
- Fiber => hashify(%I{
367
- alive?
368
- }).freeze,
369
- FiberError => hashify(%I{
370
- initialize
371
- }).freeze,
372
- File => hashify(%I{
373
- path
374
- to_path
375
- }).freeze,
376
- FloatDomainError => hashify(%I{
377
- initialize
378
- }).freeze,
379
- Hash => hashify(%I{
380
- initialize
381
- <
382
- <=
383
- ==
384
- >
385
- >=
386
- []
387
- any?
388
- assoc
389
- compact
390
- compare_by_identity?
391
- default_proc
392
- dig
393
- each
394
- each_key
395
- each_pair
396
- each_value
397
- empty?
398
- eql?
399
- fetch
400
- fetch_values
401
- flatten
402
- has_key?
403
- has_value?
404
- hash
405
- include?
406
- to_s
407
- inspect
408
- invert
409
- key
410
- key?
411
- keys
412
- length
413
- member?
414
- merge
415
- rassoc
416
- reject
417
- select
418
- size
419
- to_a
420
- to_h
421
- to_hash
422
- to_proc
423
- transform_values
424
- value?
425
- values
426
- value_at
427
- }).freeze,
428
- IndexError => hashify(%I{
429
- initialize
430
- }).freeze,
431
- IO => hashify(%I{
432
- autoclose?
433
- binmode?
434
- close_on_exec?
435
- closed?
436
- encoding
437
- inspect
438
- internal_encoding
439
- sync
440
- }).freeze,
441
- KeyError => hashify(%I{
442
- initialize
443
- }).freeze,
444
- Method => hashify(%I{
445
- ==
446
- []
447
- arity
448
- call
449
- clone
450
- curry
451
- eql?
452
- hash
453
- inspect
454
- name
455
- original_name
456
- owner
457
- parameters
458
- receiver
459
- source_location
460
- super_method
461
- to_proc
462
- to_s
463
- }).freeze,
464
- Module => hashify(%I{
465
- <
466
- <=
467
- <=>
468
- ==
469
- ===
470
- >
471
- >=
472
- ancestors
473
- autoload?
474
- class_variable_defined?
475
- class_variable_get
476
- class_variables
477
- const_defined?
478
- const_get
479
- constants
480
- include?
481
- included_modules
482
- inspect
483
- instance_method
484
- instance_methods
485
- method_defined?
486
- name
487
- private_instance_methods
488
- private_method_defined?
489
- protected_instance_methods
490
- protected_method_defined?
491
- public_instance_method
492
- public_instance_methods
493
- public_method_defined?
494
- singleton_class?
495
- to_s
496
- }).freeze,
497
- Mutex => hashify(%I{
498
- locked?
499
- owned?
500
- }).freeze,
501
- NameError => hashify(%I{
502
- initialize
503
- }).freeze,
504
- NoMethodError => hashify(%I{
505
- initialize
506
- }).freeze,
507
- RangeError => hashify(%I{
508
- initialize
509
- }).freeze,
510
- RegexpError => hashify(%I{
511
- initialize
512
- }).freeze,
513
- RuntimeError => hashify(%I{
514
- initialize
515
- }).freeze,
516
- String => hashify(%I{
517
- initialize
518
- %
519
- *
520
- +
521
- +@
522
- -@
523
- <=>
524
- ==
525
- ===
526
- =~
527
- []
528
- ascii_only?
529
- b
530
- bytes
531
- bytesize
532
- byteslice
533
- capitalize
534
- casecmp
535
- casecmp?
536
- center
537
- chars
538
- chomp
539
- chop
540
- chr
541
- codepoints
542
- count
543
- crypt
544
- delete
545
- downcase
546
- dump
547
- each_byte
548
- each_char
549
- each_codepoint
550
- each_line
551
- empty?
552
- encoding
553
- end_with?
554
- eql?
555
- getbyte
556
- gsub
557
- hash
558
- hex
559
- include?
560
- index
561
- inspect
562
- intern
563
- length
564
- lines
565
- ljust
566
- lstrip
567
- match
568
- match?
569
- next
570
- oct
571
- ord
572
- partition
573
- reverse
574
- rindex
575
- rjust
576
- rpartition
577
- rstrip
578
- scan
579
- scrub
580
- size
581
- slice
582
- split
583
- squeeze
584
- start_with?
585
- strip
586
- sub
587
- succ
588
- sum
589
- swapcase
590
- to_c
591
- to_f
592
- to_i
593
- to_r
594
- to_s
595
- to_str
596
- to_sym
597
- tr
598
- tr_s
599
- unpack
600
- unpack1
601
- upcase
602
- upto
603
- valid_encoding?
604
- }).freeze,
605
- ThreadGroup => hashify(%I{
606
- enclosed?
607
- list
608
- }).freeze,
609
- Thread => hashify(%I{
610
- []
611
- abort_on_exception
612
- alive?
613
- backtrace
614
- backtrace_locations
615
- group
616
- inspect
617
- key?
618
- keys
619
- name
620
- pending_interrupt?
621
- priority
622
- report_on_exception
623
- safe_level
624
- status
625
- stop?
626
- thread_variable?
627
- thread_variable_get
628
- thread_variables
629
- }).freeze,
630
- Time => hashify(%I{
631
- initialize
632
- +
633
- -
634
- <=>
635
- asctime
636
- ctime
637
- day
638
- dst?
639
- eql?
640
- friday?
641
- getgm
642
- getlocal
643
- getuc
644
- gmt
645
- gmt_offset
646
- gmtoff
647
- hash
648
- hour
649
- inspect
650
- isdst
651
- mday
652
- min
653
- mon
654
- month
655
- monday?
656
- month
657
- nsec
658
- round
659
- saturday?
660
- sec
661
- strftime
662
- subsec
663
- succ
664
- sunday?
665
- thursday?
666
- to_a
667
- to_f
668
- to_i
669
- to_r
670
- to_s
671
- tuesday?
672
- tv_nsec
673
- tv_sec
674
- tv_usec
675
- usec
676
- utc?
677
- utc_offset
678
- wday
679
- wednesday?
680
- yday
681
- year
682
- zone
683
- }).freeze,
684
- TypeError => hashify(%I{
685
- initialize
686
- }).freeze,
687
- UnboundMethod => hashify(%I{
688
- ==
689
- arity
690
- clone
691
- eql?
692
- hash
693
- inspect
694
- name
695
- original_name
696
- owner
697
- parameters
698
- source_location
699
- super_method
700
- to_s
701
- }).freeze,
702
- ZeroDivisionError => hashify(%I{
703
- initialize
704
- }).freeze,
201
+ ArgumentError => hashify(%I[initialize]).freeze,
202
+ Array => hashify(
203
+ %I[
204
+ initialize
205
+ &
206
+ *
207
+ +
208
+ -
209
+ <=>
210
+ ==
211
+ any?
212
+ assoc
213
+ at
214
+ bsearch
215
+ bsearch_index
216
+ collect
217
+ combination
218
+ compact
219
+ []
220
+ count
221
+ cycle
222
+ dig
223
+ drop
224
+ drop_while
225
+ each
226
+ each_index
227
+ empty?
228
+ eql?
229
+ fetch
230
+ find_index
231
+ first
232
+ flatten
233
+ frozen?
234
+ hash
235
+ include?
236
+ index
237
+ inspect
238
+ to_s
239
+ join
240
+ last
241
+ length
242
+ map
243
+ max
244
+ min
245
+ pack
246
+ permutation
247
+ product
248
+ rassoc
249
+ reject
250
+ repeated_combination
251
+ repeated_permutation
252
+ reverse
253
+ reverse_each
254
+ rindex
255
+ rotate
256
+ sample
257
+ select
258
+ shuffle
259
+ size
260
+ slice
261
+ sort
262
+ sum
263
+ take
264
+ take_while
265
+ to_a
266
+ to_ary
267
+ to_h
268
+ transpose
269
+ uniq
270
+ values_at
271
+ zip
272
+ |
273
+ ]
274
+ ).freeze,
275
+ BasicObject => hashify(
276
+ %I[
277
+ initialize
278
+ !
279
+ !=
280
+ ==
281
+ __id__
282
+ method_missing
283
+ object_id
284
+ send
285
+ __send__
286
+ equal?
287
+ ]
288
+ ).freeze,
289
+ Binding => hashify(
290
+ %I[
291
+ local_variable_defined?
292
+ local_variable_get
293
+ local_variables
294
+ receiver
295
+ ]
296
+ ).freeze,
297
+ Class => hashify(%I[superclass]).freeze,
298
+ Dir => hashify(%I[inspect path to_path]).freeze,
299
+ Exception => hashify(
300
+ %I[
301
+ initialize
302
+ ==
303
+ backtrace
304
+ backtrace_locations
305
+ cause
306
+ exception
307
+ inspect
308
+ message
309
+ to_s
310
+ ]
311
+ ).freeze,
312
+ Enumerator => hashify(
313
+ %I[
314
+ initialize
315
+ each
316
+ each_with_index
317
+ each_with_object
318
+ inspect
319
+ size
320
+ with_index
321
+ with_object
322
+ ]
323
+ ).freeze,
324
+ Fiber => hashify(%I[alive?]).freeze,
325
+ FiberError => hashify(%I[initialize]).freeze,
326
+ File => hashify(%I[path to_path]).freeze,
327
+ FloatDomainError => hashify(%I[initialize]).freeze,
328
+ Hash => hashify(
329
+ %I[
330
+ initialize
331
+ <
332
+ <=
333
+ ==
334
+ >
335
+ >=
336
+ []
337
+ any?
338
+ assoc
339
+ compact
340
+ compare_by_identity?
341
+ default_proc
342
+ dig
343
+ each
344
+ each_key
345
+ each_pair
346
+ each_value
347
+ empty?
348
+ eql?
349
+ fetch
350
+ fetch_values
351
+ flatten
352
+ has_key?
353
+ has_value?
354
+ hash
355
+ include?
356
+ to_s
357
+ inspect
358
+ invert
359
+ key
360
+ key?
361
+ keys
362
+ length
363
+ member?
364
+ merge
365
+ rassoc
366
+ reject
367
+ select
368
+ size
369
+ to_a
370
+ to_h
371
+ to_hash
372
+ to_proc
373
+ transform_values
374
+ value?
375
+ values
376
+ value_at
377
+ ]
378
+ ).freeze,
379
+ IndexError => hashify(%I[initialize]).freeze,
380
+ IO => hashify(
381
+ %I[
382
+ autoclose?
383
+ binmode?
384
+ close_on_exec?
385
+ closed?
386
+ encoding
387
+ inspect
388
+ internal_encoding
389
+ sync
390
+ ]
391
+ ).freeze,
392
+ KeyError => hashify(%I[initialize]).freeze,
393
+ Method => hashify(
394
+ %I[
395
+ ==
396
+ []
397
+ arity
398
+ call
399
+ clone
400
+ curry
401
+ eql?
402
+ hash
403
+ inspect
404
+ name
405
+ original_name
406
+ owner
407
+ parameters
408
+ receiver
409
+ source_location
410
+ super_method
411
+ to_proc
412
+ to_s
413
+ ]
414
+ ).freeze,
415
+ Module => hashify(
416
+ %I[
417
+ <
418
+ <=
419
+ <=>
420
+ ==
421
+ ===
422
+ >
423
+ >=
424
+ ancestors
425
+ autoload?
426
+ class_variable_defined?
427
+ class_variable_get
428
+ class_variables
429
+ const_defined?
430
+ const_get
431
+ constants
432
+ include?
433
+ included_modules
434
+ inspect
435
+ instance_method
436
+ instance_methods
437
+ method_defined?
438
+ name
439
+ private_instance_methods
440
+ private_method_defined?
441
+ protected_instance_methods
442
+ protected_method_defined?
443
+ public_instance_method
444
+ public_instance_methods
445
+ public_method_defined?
446
+ singleton_class?
447
+ to_s
448
+ ]
449
+ ).freeze,
450
+ Mutex => hashify(%I[locked? owned?]).freeze,
451
+ NameError => hashify(%I[initialize]).freeze,
452
+ NoMethodError => hashify(%I[initialize]).freeze,
453
+ RangeError => hashify(%I[initialize]).freeze,
454
+ RegexpError => hashify(%I[initialize]).freeze,
455
+ RuntimeError => hashify(%I[initialize]).freeze,
456
+ String => hashify(
457
+ %I[
458
+ initialize
459
+ %
460
+ *
461
+ +
462
+ +@
463
+ -@
464
+ <=>
465
+ ==
466
+ ===
467
+ =~
468
+ []
469
+ ascii_only?
470
+ b
471
+ bytes
472
+ bytesize
473
+ byteslice
474
+ capitalize
475
+ casecmp
476
+ casecmp?
477
+ center
478
+ chars
479
+ chomp
480
+ chop
481
+ chr
482
+ codepoints
483
+ count
484
+ crypt
485
+ delete
486
+ downcase
487
+ dump
488
+ each_byte
489
+ each_char
490
+ each_codepoint
491
+ each_line
492
+ empty?
493
+ encoding
494
+ end_with?
495
+ eql?
496
+ getbyte
497
+ gsub
498
+ hash
499
+ hex
500
+ include?
501
+ index
502
+ inspect
503
+ intern
504
+ length
505
+ lines
506
+ ljust
507
+ lstrip
508
+ match
509
+ match?
510
+ next
511
+ oct
512
+ ord
513
+ partition
514
+ reverse
515
+ rindex
516
+ rjust
517
+ rpartition
518
+ rstrip
519
+ scan
520
+ scrub
521
+ size
522
+ slice
523
+ split
524
+ squeeze
525
+ start_with?
526
+ strip
527
+ sub
528
+ succ
529
+ sum
530
+ swapcase
531
+ to_c
532
+ to_f
533
+ to_i
534
+ to_r
535
+ to_s
536
+ to_str
537
+ to_sym
538
+ tr
539
+ tr_s
540
+ unpack
541
+ unpack1
542
+ upcase
543
+ upto
544
+ valid_encoding?
545
+ ]
546
+ ).freeze,
547
+ ThreadGroup => hashify(%I[enclosed? list]).freeze,
548
+ Thread => hashify(
549
+ %I[
550
+ []
551
+ abort_on_exception
552
+ alive?
553
+ backtrace
554
+ backtrace_locations
555
+ group
556
+ inspect
557
+ key?
558
+ keys
559
+ name
560
+ pending_interrupt?
561
+ priority
562
+ report_on_exception
563
+ safe_level
564
+ status
565
+ stop?
566
+ thread_variable?
567
+ thread_variable_get
568
+ thread_variables
569
+ ]
570
+ ).freeze,
571
+ Time => hashify(
572
+ %I[
573
+ initialize
574
+ +
575
+ -
576
+ <=>
577
+ asctime
578
+ ctime
579
+ day
580
+ dst?
581
+ eql?
582
+ friday?
583
+ getgm
584
+ getlocal
585
+ getuc
586
+ gmt
587
+ gmt_offset
588
+ gmtoff
589
+ hash
590
+ hour
591
+ inspect
592
+ isdst
593
+ mday
594
+ min
595
+ mon
596
+ month
597
+ monday?
598
+ month
599
+ nsec
600
+ round
601
+ saturday?
602
+ sec
603
+ strftime
604
+ subsec
605
+ succ
606
+ sunday?
607
+ thursday?
608
+ to_a
609
+ to_f
610
+ to_i
611
+ to_r
612
+ to_s
613
+ tuesday?
614
+ tv_nsec
615
+ tv_sec
616
+ tv_usec
617
+ usec
618
+ utc?
619
+ utc_offset
620
+ wday
621
+ wednesday?
622
+ yday
623
+ year
624
+ zone
625
+ ]
626
+ ).freeze,
627
+ TypeError => hashify(%I[initialize]).freeze,
628
+ UnboundMethod => hashify(
629
+ %I[
630
+ ==
631
+ arity
632
+ clone
633
+ eql?
634
+ hash
635
+ inspect
636
+ name
637
+ original_name
638
+ owner
639
+ parameters
640
+ source_location
641
+ super_method
642
+ to_s
643
+ ]
644
+ ).freeze,
645
+ ZeroDivisionError => hashify(%I[initialize]).freeze,
705
646
  # Modules
706
- Kernel => hashify(%I{
707
- Array
708
- Complex
709
- Float
710
- Hash
711
- Integer
712
- Rational
713
- String
714
- __callee__
715
- __dir__
716
- __method__
717
- autoload?
718
- block_given?
719
- caller
720
- caller_locations
721
- catch
722
- format
723
- global_variables
724
- iterator?
725
- lambda
726
- local_variables
727
- loop
728
- method
729
- methods
730
- proc
731
- rand
732
- !~
733
- <=>
734
- ===
735
- =~
736
- class
737
- clone
738
- dup
739
- enum_for
740
- eql?
741
- frozen?
742
- hash
743
- inspect
744
- instance_of?
745
- instance_variable_defined?
746
- instance_variable_get
747
- instance_variables
748
- is_a?
749
- itself
750
- kind_of?
751
- nil?
752
- object_id
753
- private_methods
754
- protected_methods
755
- public_method
756
- public_methods
757
- public_send
758
- respond_to?
759
- respond_to_missing?
760
- __send__
761
- send
762
- singleton_class
763
- singleton_method
764
- singleton_methods
765
- tainted?
766
- tap
767
- to_enum
768
- to_s
769
- untrusted?
770
- }).freeze
647
+ Kernel => hashify(
648
+ %I[
649
+ Array
650
+ Complex
651
+ Float
652
+ Hash
653
+ Integer
654
+ Rational
655
+ String
656
+ __callee__
657
+ __dir__
658
+ __method__
659
+ autoload?
660
+ block_given?
661
+ caller
662
+ caller_locations
663
+ catch
664
+ format
665
+ global_variables
666
+ iterator?
667
+ lambda
668
+ local_variables
669
+ loop
670
+ method
671
+ methods
672
+ proc
673
+ rand
674
+ !~
675
+ <=>
676
+ ===
677
+ =~
678
+ class
679
+ clone
680
+ dup
681
+ enum_for
682
+ eql?
683
+ frozen?
684
+ hash
685
+ inspect
686
+ instance_of?
687
+ instance_variable_defined?
688
+ instance_variable_get
689
+ instance_variables
690
+ is_a?
691
+ itself
692
+ kind_of?
693
+ nil?
694
+ object_id
695
+ private_methods
696
+ protected_methods
697
+ public_method
698
+ public_methods
699
+ public_send
700
+ respond_to?
701
+ respond_to_missing?
702
+ __send__
703
+ send
704
+ singleton_class
705
+ singleton_method
706
+ singleton_methods
707
+ tainted?
708
+ tap
709
+ to_enum
710
+ to_s
711
+ untrusted?
712
+ ]
713
+ ).freeze
714
+ }.freeze
715
+
716
+ ##
717
+ # @private List of Ruby class methods that the evaluator allows
718
+ # during expression evaluation
719
+ RUBY_CLASS_METHOD_WHITELIST = {
720
+ # Classes
721
+ Debugger => hashify(%I[allow_mutating_methods!]).freeze
722
+ }.freeze
723
+
724
+ ##
725
+ # @private List of Ruby instance methods that the evaluator allows
726
+ # during expression evaluation
727
+ RUBY_INSTANCE_METHOD_WHITELIST = {
728
+ Evaluator => hashify(%I[allow_mutating_methods!]).freeze
771
729
  }.freeze
772
730
 
773
731
  PROHIBITED_OPERATION_MSG = "Prohibited operation detected".freeze
@@ -775,230 +733,329 @@ module Google
775
733
  COMPILATION_FAIL_MSG = "Unable to compile expression".freeze
776
734
  LONG_EVAL_MSG = "Evaluation exceeded time limit".freeze
777
735
 
778
- EXPRESSION_EVALUATION_TIME_THRESHOLD = 0.05
736
+ EVALUATOR_REFERENCE = :__evaluator__
779
737
 
780
- class << self
781
- ##
782
- # @private Read-only evaluates a single expression in a given
783
- # context binding. Handles any exceptions raised.
784
- #
785
- # @param [Binding] binding The binding object from the context
786
- # @param [String] expression A string of code to be evaluates
787
- #
788
- # @return [Object] The result Ruby object from evaluating the
789
- # expression. If the expression is blocked from mutating
790
- # the state of program. A
791
- # {Google::Cloud::Debugger::MutationError} will be returned.
792
- #
793
- def readonly_eval_expression binding, expression
794
- compilation_result = validate_compiled_expression expression
795
- return compilation_result if compilation_result.is_a?(Exception)
738
+ ##
739
+ # @private
740
+ # Read-only evaluates a single expression in a given
741
+ # context binding. Handles any exceptions raised.
742
+ #
743
+ # @param [Binding] binding The binding object from the context
744
+ # @param [String] expression A string of code to be evaluated
745
+ #
746
+ # @return [Object] The result Ruby object from evaluating the
747
+ # expression. If the expression is blocked from mutating
748
+ # the state of program. A
749
+ # {Google::Cloud::Debugger::MutationError} will be returned.
750
+ #
751
+ def self.readonly_eval_expression binding, expression
752
+ new.readonly_eval_expression binding, expression
753
+ end
796
754
 
797
- readonly_eval_expression_exec binding, expression
798
- rescue => e
799
- "Unable to evaluate expression: #{e.message}"
800
- end
755
+ ##
756
+ # @private
757
+ # Returns the evaluator currently running, or nil if an evaluation
758
+ # is not currently running.
759
+ #
760
+ # @return [Evaluator, nil]
761
+ #
762
+ def self.current
763
+ Thread.current.thread_variable_get EVALUATOR_REFERENCE
764
+ end
801
765
 
802
- private
766
+ ##
767
+ # Create a new Evaluator.
768
+ # @private
769
+ #
770
+ # @param [boolean, nil] allow_mutating_methods whether to allow
771
+ # calling of potentially mutating methods, or nil to default to
772
+ # the current configuration setting.
773
+ # @param [Numeric, nil] time_limit the time limit in seconds, or nil
774
+ # to default to the current configuration setting.
775
+ #
776
+ def initialize allow_mutating_methods: nil, time_limit: nil
777
+ @allow_mutating_methods =
778
+ if allow_mutating_methods.nil?
779
+ Debugger.configure.allow_mutating_methods
780
+ else
781
+ allow_mutating_methods
782
+ end
783
+ @time_limit = time_limit ||
784
+ Debugger.configure.evaluation_time_limit
785
+ end
803
786
 
804
- ##
805
- # @private Actually read-only evaluates an expression in a given
806
- # context binding. The evaluation is done in a separate thread due
807
- # to this method may be run from Ruby Trace call back, where
808
- # addtional code tracing is disabled in original thread.
809
- #
810
- # @param [Binding] binding The binding object from the context
811
- # @param [String] expression A string of code to be evaluates
812
- #
813
- # @return [Object] The result Ruby object from evaluating the
814
- # expression. It returns Google::Cloud::Debugger::MutationError
815
- # if a mutation is caught.
816
- #
817
- def readonly_eval_expression_exec binding, expression
818
- # The evaluation is most likely triggered from a trace callback,
819
- # where addtional nested tracing is disabled by VM. So we need to
820
- # do evaluation in a new thread, where function calls can be
821
- # traced.
822
- thr = Thread.new do
823
- begin
824
- binding.eval wrap_expression(expression)
825
- rescue => e
826
- # Treat all StandardError as mutation and set @mutation_cause
827
- unless e.instance_variable_get :@mutation_cause
828
- e.instance_variable_set(
829
- :@mutation_cause,
830
- Google::Cloud::Debugger::EvaluationError::UNKNOWN_CAUSE)
831
- end
787
+ ##
788
+ # Allow calling of mutating methods even if mutation detection is
789
+ # configured to be active. This may be called only during debugger
790
+ # condition or expression evaluation.
791
+ #
792
+ # If you pass in a block, it will be evaluated with mutation
793
+ # detection disabled, and the original setting will be restored
794
+ # afterward. If you do not pass a block, this evaluator will
795
+ # permanently allow mutating methods.
796
+ # @private
797
+ #
798
+ def allow_mutating_methods!
799
+ old = @allow_mutating_methods
800
+ @allow_mutating_methods = true
801
+ return unless block_given?
832
802
 
833
- e
834
- end
835
- end
803
+ result = yield
804
+ @allow_mutating_methods = old
805
+ result
806
+ end
836
807
 
837
- thr.join EXPRESSION_EVALUATION_TIME_THRESHOLD
808
+ ##
809
+ # Read-only evaluates a single expression in a given
810
+ # context binding. Handles any exceptions raised.
811
+ # @private
812
+ #
813
+ # @param [Binding] binding The binding object from the context
814
+ # @param [String] expression A string of code to be evaluates
815
+ #
816
+ # @return [Object] The result Ruby object from evaluating the
817
+ # expression. If the expression is blocked from mutating
818
+ # the state of program. A
819
+ # {Google::Cloud::Debugger::MutationError} will be returned.
820
+ #
821
+ def readonly_eval_expression binding, expression
822
+ compilation_result = validate_compiled_expression expression
823
+ return compilation_result if compilation_result.is_a?(Exception)
838
824
 
839
- # Force terminate evaluation thread if not finished already and
840
- # return an Exception
841
- if thr.alive?
842
- thr.kill
825
+ readonly_eval_expression_exec binding, expression
826
+ rescue StandardError => e
827
+ "Unable to evaluate expression: #{e.message}"
828
+ end
843
829
 
844
- Google::Cloud::Debugger::EvaluationError.new LONG_EVAL_MSG
845
- else
846
- thr.value
847
- end
848
- end
830
+ private
849
831
 
850
- ##
851
- # @private Compile the expression into YARV instructions. Return
852
- # Google::Cloud::Debugger::MutationError if any prohibited YARV
853
- # instructions are found.
854
- #
855
- # @param [String] expression String of code expression
856
- #
857
- # @return [String,Google::Cloud::Debugger::MutationError] It returns
858
- # the compile YARV instructions if no prohibited bytecodes are
859
- # found. Otherwise return Google::Cloud::Debugger::MutationError.
860
- #
861
- def validate_compiled_expression expression
832
+ ##
833
+ # @private Actually read-only evaluates an expression in a given
834
+ # context binding. The evaluation is done in a separate thread due
835
+ # to this method may be run from Ruby Trace call back, where
836
+ # addtional code tracing is disabled in original thread.
837
+ #
838
+ # @param [Binding] binding The binding object from the context
839
+ # @param [String] expression A string of code to be evaluates
840
+ #
841
+ # @return [Object] The result Ruby object from evaluating the
842
+ # expression. It returns Google::Cloud::Debugger::MutationError
843
+ # if a mutation is caught.
844
+ #
845
+ def readonly_eval_expression_exec binding, expression
846
+ # The evaluation is most likely triggered from a trace callback,
847
+ # where addtional nested tracing is disabled by VM. So we need to
848
+ # do evaluation in a new thread, where function calls can be
849
+ # traced.
850
+ thr = Thread.new do
862
851
  begin
863
- yarv_instructions =
864
- RubyVM::InstructionSequence.compile(expression).disasm
865
- rescue ScriptError
866
- return Google::Cloud::Debugger::MutationError.new(
867
- COMPILATION_FAIL_MSG,
868
- Google::Cloud::Debugger::EvaluationError::PROHIBITED_YARV
869
- )
870
- end
852
+ Thread.current.thread_variable_set EVALUATOR_REFERENCE, self
853
+ binding.eval wrap_expression(expression)
854
+ rescue StandardError, EvaluationError => e
855
+ # Treat all StandardError as mutation and set @mutation_cause
856
+ unless e.instance_variable_get :@mutation_cause
857
+ e.instance_variable_set(
858
+ :@mutation_cause,
859
+ Google::Cloud::Debugger::EvaluationError::UNKNOWN_CAUSE
860
+ )
861
+ end
871
862
 
872
- unless immutable_yarv_instructions? yarv_instructions
873
- return Google::Cloud::Debugger::MutationError.new(
874
- MUTATION_DETECTED_MSG,
875
- Google::Cloud::Debugger::EvaluationError::PROHIBITED_YARV
876
- )
863
+ e
877
864
  end
878
-
879
- yarv_instructions
880
865
  end
881
866
 
882
- ##
883
- # @private Helps checking if a given set of YARV instructions
884
- # contains any prohibited bytecode or instructions.
885
- #
886
- # @param [String] yarv_instructions Compiled YARV instructions
887
- # string
888
- # @param [Boolean] allow_localops Whether allows local variable
889
- # write operations
890
- #
891
- # @return [Boolean] True if the YARV instructions don't contain any
892
- # prohibited operations. Otherwise false.
893
- #
894
- def immutable_yarv_instructions? yarv_instructions,
895
- allow_localops: false
896
- if allow_localops
897
- byte_code_blacklist_regex = BYTE_CODE_BLACKLIST_REGEX
898
- else
899
- byte_code_blacklist_regex = FULL_BYTE_CODE_BLACKLIST_REGEX
900
- end
867
+ thr.join @time_limit
901
868
 
902
- func_call_flag_blacklist_regex = FUNC_CALL_FLAG_BLACKLIST_REGEX
869
+ # Force terminate evaluation thread if not finished already and
870
+ # return an Exception
871
+ if thr.alive?
872
+ thr.kill
903
873
 
904
- catch_table_type_blacklist_regex = CATCH_TABLE_BLACKLIST_REGEX
874
+ Google::Cloud::Debugger::EvaluationError.new LONG_EVAL_MSG
875
+ else
876
+ thr.value
877
+ end
878
+ end
905
879
 
906
- !(yarv_instructions.match(func_call_flag_blacklist_regex) ||
907
- yarv_instructions.match(byte_code_blacklist_regex) ||
908
- yarv_instructions.match(catch_table_type_blacklist_regex))
880
+ ##
881
+ # @private Compile the expression into YARV instructions. Return
882
+ # Google::Cloud::Debugger::MutationError if any prohibited YARV
883
+ # instructions are found.
884
+ #
885
+ # @param [String] expression String of code expression
886
+ #
887
+ # @return [String,Google::Cloud::Debugger::MutationError] It returns
888
+ # the compile YARV instructions if no prohibited bytecodes are
889
+ # found. Otherwise return Google::Cloud::Debugger::MutationError.
890
+ #
891
+ def validate_compiled_expression expression
892
+ begin
893
+ yarv_instructions =
894
+ RubyVM::InstructionSequence.compile(expression).disasm
895
+ rescue ScriptError
896
+ return Google::Cloud::Debugger::MutationError.new(
897
+ COMPILATION_FAIL_MSG,
898
+ Google::Cloud::Debugger::EvaluationError::PROHIBITED_YARV
899
+ )
909
900
  end
910
901
 
911
- ##
912
- # @private Wraps expression with tracing code
913
- def wrap_expression expression
914
- """
915
- begin
916
- Google::Cloud::Debugger::Breakpoint::Evaluator.send(
917
- :enable_method_trace_for_thread)
918
- #{expression}
919
- ensure
920
- Google::Cloud::Debugger::Breakpoint::Evaluator.send(
921
- :disable_method_trace_for_thread)
922
- end
923
- """
902
+ unless immutable_yarv_instructions? yarv_instructions
903
+ return Google::Cloud::Debugger::MutationError.new(
904
+ MUTATION_DETECTED_MSG,
905
+ Google::Cloud::Debugger::EvaluationError::PROHIBITED_YARV
906
+ )
924
907
  end
925
908
 
926
- ##
927
- # @private Evaluation tracing callback function. This is called
928
- # everytime a Ruby function is called during evaluation of
929
- # an expression.
930
- #
931
- # @param [Object] receiver The receiver of the function being called
932
- # @param [Symbol] mid The method name
933
- #
934
- # @return [NilClass] Nil if no prohibited operations are found.
935
- # Otherwise raise Google::Cloud::Debugger::MutationError error.
936
- #
937
- def trace_func_callback receiver, mid
938
- meth = nil
939
- begin
940
- meth = receiver.method mid
941
- rescue
942
- raise Google::Cloud::Debugger::EvaluationError.new(
943
- PROHIBITED_OPERATION_MSG,
944
- Google::Cloud::Debugger::EvaluationError::META_PROGRAMMING)
945
- end
909
+ yarv_instructions
910
+ end
946
911
 
947
- yarv_instructions = RubyVM::InstructionSequence.disasm meth
912
+ ##
913
+ # @private Helps checking if a given set of YARV instructions
914
+ # contains any prohibited bytecode or instructions.
915
+ #
916
+ # @param [String] yarv_instructions Compiled YARV instructions
917
+ # string
918
+ # @param [Boolean] allow_localops Whether allows local variable
919
+ # write operations
920
+ #
921
+ # @return [Boolean] True if the YARV instructions don't contain any
922
+ # prohibited operations. Otherwise false.
923
+ #
924
+ def immutable_yarv_instructions? yarv_instructions,
925
+ allow_localops: false
926
+ byte_code_blacklist_regex = if allow_localops
927
+ BYTE_CODE_BLACKLIST_REGEX
928
+ else
929
+ FULL_BYTE_CODE_BLACKLIST_REGEX
930
+ end
948
931
 
949
- return if immutable_yarv_instructions?(yarv_instructions,
950
- allow_localops: true)
951
- fail Google::Cloud::Debugger::MutationError.new(
952
- MUTATION_DETECTED_MSG,
953
- Google::Cloud::Debugger::EvaluationError::PROHIBITED_YARV)
954
- end
932
+ func_call_flag_blacklist_regex = FUNC_CALL_FLAG_BLACKLIST_REGEX
955
933
 
956
- ##
957
- # @private Evaluation tracing callback function. This is called
958
- # everytime a C function is called during evaluation of
959
- # an expression.
960
- #
961
- # @param [Object] receiver The receiver of the function being called
962
- # @param [Class] defined_class The Class of where the function is
963
- # defined
964
- # @param [Symbol] mid The method name
965
- #
966
- # @return [NilClass] Nil if no prohibited operations are found.
967
- # Otherwise raise Google::Cloud::Debugger::MutationError error.
968
- #
969
- def trace_c_func_callback receiver, defined_class, mid
970
- if receiver.is_a?(Class) || receiver.is_a?(Module)
971
- invalid_op =
972
- !validate_c_class_method(defined_class, receiver, mid)
973
- else
974
- invalid_op = !validate_c_instance_method(defined_class, mid)
934
+ catch_table_type_blacklist_regex = CATCH_TABLE_BLACKLIST_REGEX
935
+
936
+ !(yarv_instructions.match(func_call_flag_blacklist_regex) ||
937
+ yarv_instructions.match(byte_code_blacklist_regex) ||
938
+ yarv_instructions.match(catch_table_type_blacklist_regex))
939
+ end
940
+
941
+ ##
942
+ # @private Wraps expression with tracing code
943
+ def wrap_expression expression
944
+ """
945
+ begin
946
+ ::Google::Cloud::Debugger::Breakpoint::Evaluator.send(
947
+ :enable_method_trace_for_thread)
948
+ #{expression}
949
+ ensure
950
+ ::Google::Cloud::Debugger::Breakpoint::Evaluator.send(
951
+ :disable_method_trace_for_thread)
975
952
  end
953
+ """
954
+ end
976
955
 
977
- return unless invalid_op
956
+ ##
957
+ # @private Evaluation tracing callback function. This is called
958
+ # everytime a Ruby function is called during evaluation of
959
+ # an expression.
960
+ #
961
+ # @param [Object] receiver The receiver of the function being called
962
+ # @param [Symbol] mid The method name
963
+ #
964
+ # @return [NilClass] Nil if no prohibited operations are found.
965
+ # Otherwise raise Google::Cloud::Debugger::MutationError error.
966
+ #
967
+ def trace_func_callback receiver, defined_class, mid
968
+ return if @allow_mutating_methods
969
+ if receiver.is_a?(Class) || receiver.is_a?(Module)
970
+ if whitelisted_ruby_class_method? defined_class, receiver, mid
971
+ return
972
+ end
973
+ elsif whitelisted_ruby_instance_method? defined_class, mid
974
+ return
975
+ end
978
976
 
979
- Google::Cloud::Debugger::Breakpoint::Evaluator.send(
980
- :disable_method_trace_for_thread)
981
- fail Google::Cloud::Debugger::MutationError.new(
977
+ yarv_instructions = begin
978
+ RubyVM::InstructionSequence.disasm receiver.method mid
979
+ rescue StandardError
980
+ raise Google::Cloud::Debugger::EvaluationError.new(
982
981
  PROHIBITED_OPERATION_MSG,
983
- Google::Cloud::Debugger::EvaluationError::PROHIBITED_C_FUNC)
982
+ Google::Cloud::Debugger::EvaluationError::META_PROGRAMMING
983
+ )
984
984
  end
985
985
 
986
- ##
987
- # @private Helper method to verify wehter a C level class method
988
- # is allowed or not.
989
- def validate_c_class_method klass, receiver, mid
990
- IMMUTABLE_CLASSES.include?(receiver) ||
991
- (C_CLASS_METHOD_WHITELIST[receiver] || {})[mid] ||
992
- (C_INSTANCE_METHOD_WHITELIST[klass] || {})[mid]
993
- end
986
+ return if immutable_yarv_instructions?(yarv_instructions,
987
+ allow_localops: true)
988
+ raise Google::Cloud::Debugger::MutationError.new(
989
+ MUTATION_DETECTED_MSG,
990
+ Google::Cloud::Debugger::EvaluationError::PROHIBITED_YARV
991
+ )
992
+ end
994
993
 
995
- ##
996
- # @private Helper method to verify wehter a C level instance method
997
- # is allowed or not.
998
- def validate_c_instance_method klass, mid
999
- IMMUTABLE_CLASSES.include?(klass) ||
1000
- (C_INSTANCE_METHOD_WHITELIST[klass] || {})[mid]
994
+ ##
995
+ # @private Evaluation tracing callback function. This is called
996
+ # everytime a C function is called during evaluation of
997
+ # an expression.
998
+ #
999
+ # @param [Object] receiver The receiver of the function being called
1000
+ # @param [Class] defined_class The Class of where the function is
1001
+ # defined
1002
+ # @param [Symbol] mid The method name
1003
+ #
1004
+ # @return [NilClass] Nil if no prohibited operations are found.
1005
+ # Otherwise raise Google::Cloud::Debugger::MutationError error.
1006
+ #
1007
+ def trace_c_func_callback receiver, defined_class, mid
1008
+ return if @allow_mutating_methods
1009
+ if receiver.is_a?(Class) || receiver.is_a?(Module)
1010
+ invalid_op =
1011
+ !validate_c_class_method(defined_class, receiver, mid)
1012
+ else
1013
+ invalid_op = !validate_c_instance_method(defined_class, mid)
1001
1014
  end
1015
+
1016
+ return unless invalid_op
1017
+
1018
+ Google::Cloud::Debugger::Breakpoint::Evaluator.send(
1019
+ :disable_method_trace_for_thread
1020
+ )
1021
+ raise Google::Cloud::Debugger::MutationError.new(
1022
+ PROHIBITED_OPERATION_MSG,
1023
+ Google::Cloud::Debugger::EvaluationError::PROHIBITED_C_FUNC
1024
+ )
1025
+ end
1026
+
1027
+ ##
1028
+ # @private Helper method to verify whether a C level class method
1029
+ # is allowed or not.
1030
+ def validate_c_class_method klass, receiver, mid
1031
+ IMMUTABLE_CLASSES.include?(receiver) ||
1032
+ (C_CLASS_METHOD_WHITELIST[receiver] || {})[mid] ||
1033
+ (C_INSTANCE_METHOD_WHITELIST[klass] || {})[mid]
1034
+ end
1035
+
1036
+ ##
1037
+ # @private Helper method to verify whether a C level instance method
1038
+ # is allowed or not.
1039
+ def validate_c_instance_method klass, mid
1040
+ IMMUTABLE_CLASSES.include?(klass) ||
1041
+ (C_INSTANCE_METHOD_WHITELIST[klass] || {})[mid]
1042
+ end
1043
+
1044
+ ##
1045
+ # @private Helper method to verify whether a ruby class method
1046
+ # is allowed or not.
1047
+ def whitelisted_ruby_class_method? klass, receiver, mid
1048
+ IMMUTABLE_CLASSES.include?(klass) ||
1049
+ (RUBY_CLASS_METHOD_WHITELIST[receiver] || {})[mid] ||
1050
+ (RUBY_INSTANCE_METHOD_WHITELIST[klass] || {})[mid]
1051
+ end
1052
+
1053
+ ##
1054
+ # @private Helper method to verify whether a ruby instance method
1055
+ # is allowed or not.
1056
+ def whitelisted_ruby_instance_method? klass, mid
1057
+ IMMUTABLE_CLASSES.include?(klass) ||
1058
+ (RUBY_INSTANCE_METHOD_WHITELIST[klass] || {})[mid]
1002
1059
  end
1003
1060
  end
1004
1061
  end
@@ -1006,7 +1063,7 @@ module Google
1006
1063
  ##
1007
1064
  # @private Custom error type used to identify evaluation error during
1008
1065
  # breakpoint expression evaluation.
1009
- class EvaluationError < StandardError
1066
+ class EvaluationError < Exception
1010
1067
  UNKNOWN_CAUSE = :unknown_cause
1011
1068
  PROHIBITED_YARV = :prohibited_yarv
1012
1069
  PROHIBITED_C_FUNC = :prohibited_c_func