google-cloud-debugger 0.25.0 → 0.26.1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 123026733717c135b469d6151982edc6b0cd8f24
4
- data.tar.gz: 0ee45f3037ad8503a1b05dd08274e207e580d6dc
3
+ metadata.gz: 7a8f4cd45e74a4f18bf53c08fb05284529937c6b
4
+ data.tar.gz: '0718436023043859a8c9b958dc43bb623fb7ec79'
5
5
  SHA512:
6
- metadata.gz: 555b2972eb3db4112e4cb51c2a0f72adfc1c058f9519ffa31fd8d367280db39e91a9be14c10a07b9fd7d3b73c1e37c29f81fee13e66ddd1e7b68311568ef328b
7
- data.tar.gz: 7c7780ab4ffd74371586bb256cd4c22094af3b2b2d5a9bdebbbb36ff8c2c49c7abe97f5bf687448869409d8a07a4d312e61370f7b03d2ae07fdf905f9cbaf792
6
+ metadata.gz: 323fde821b65e2167e7ea0b56f2ff988203d62d5391032890be39636bec869750e4bf701a7756b50b59b7b9eb11c71819a8a0df3830574304b7b3d38e1cfa595
7
+ data.tar.gz: e68aa3d18c0aaf72db470b4dba4e1ecf439da21b43aeb081a552a49d8da093121795ffd32beec52fda075b68a90564cc70a88b579fca4008b1f2b6386032920c
@@ -26,12 +26,17 @@ eval_trace_callback(void *data, rb_trace_arg_t *trace_arg)
26
26
  VALUE klass = rb_tracearg_defined_class(trace_arg);
27
27
  VALUE obj = rb_tracearg_self(trace_arg);
28
28
  VALUE method_id = rb_tracearg_method_id(trace_arg);
29
+ ID trace_func_cb_id;
30
+ ID trace_c_func_cb_id;
31
+
32
+ CONST_ID(trace_func_cb_id, "trace_func_callback");
33
+ CONST_ID(trace_c_func_cb_id, "trace_c_func_callback");
29
34
 
30
35
  if (event & RUBY_EVENT_CALL) {
31
- rb_funcall(evaluator, rb_intern("trace_func_callback"), 2, obj, method_id);
36
+ rb_funcall(evaluator, trace_func_cb_id, 2, obj, method_id);
32
37
  }
33
38
  if (event & RUBY_EVENT_C_CALL) {
34
- rb_funcall(evaluator, rb_intern("trace_c_func_callback"), 3, obj, klass, method_id);
39
+ rb_funcall(evaluator, trace_c_func_cb_id, 3, obj, klass, method_id);
35
40
  }
36
41
 
37
42
  return;
@@ -40,13 +45,24 @@ eval_trace_callback(void *data, rb_trace_arg_t *trace_arg)
40
45
  static VALUE
41
46
  rb_disable_method_trace_for_thread(VALUE self)
42
47
  {
43
- VALUE current_thread = rb_thread_current();
44
- VALUE thread_variables_hash = rb_ivar_get(current_thread, rb_intern("locals"));
45
- VALUE trace_set = rb_hash_aref(thread_variables_hash, rb_str_new2("gcloud_eval_trace_set"));
48
+ VALUE current_thread;
49
+ VALUE thread_variables_hash;
50
+ VALUE trace_set;
51
+ ID locals_id;
52
+ ID eval_trace_thread_id;
53
+ VALUE eval_trace_thread_flag;
54
+
55
+ CONST_ID(locals_id, "locals");
56
+ CONST_ID(eval_trace_thread_id, "gcloud_eval_trace_set");
57
+ eval_trace_thread_flag = ID2SYM(eval_trace_thread_id);
58
+
59
+ current_thread = rb_thread_current();
60
+ thread_variables_hash = rb_ivar_get(current_thread, locals_id);
61
+ trace_set = rb_hash_aref(thread_variables_hash, eval_trace_thread_flag);
46
62
 
47
63
  if (RTEST(trace_set)) {
48
64
  rb_thread_remove_event_hook(current_thread, (rb_event_hook_func_t)eval_trace_callback);
49
- rb_hash_aset(thread_variables_hash, rb_str_new2("gcloud_eval_trace_set"), Qfalse);
65
+ rb_hash_aset(thread_variables_hash, eval_trace_thread_flag, Qfalse);
50
66
  }
51
67
 
52
68
  return Qnil;
@@ -55,13 +71,24 @@ rb_disable_method_trace_for_thread(VALUE self)
55
71
  static VALUE
56
72
  rb_enable_method_trace_for_thread(VALUE self)
57
73
  {
58
- VALUE current_thread = rb_thread_current();
59
- VALUE thread_variables_hash = rb_ivar_get(current_thread, rb_intern("locals"));
60
- VALUE trace_set = rb_hash_aref(thread_variables_hash, rb_str_new2("gcloud_eval_trace_set"));
74
+ VALUE current_thread;
75
+ VALUE thread_variables_hash;
76
+ VALUE trace_set;
77
+ ID locals_id;
78
+ ID eval_trace_thread_id;
79
+ VALUE eval_trace_thread_flag;
80
+
81
+ CONST_ID(locals_id, "locals");
82
+ CONST_ID(eval_trace_thread_id, "gcloud_eval_trace_set");
83
+ eval_trace_thread_flag = ID2SYM(eval_trace_thread_id);
84
+
85
+ current_thread = rb_thread_current();
86
+ thread_variables_hash = rb_ivar_get(current_thread, locals_id);
87
+ trace_set = rb_hash_aref(thread_variables_hash, eval_trace_thread_flag);
61
88
 
62
89
  if (!RTEST(trace_set)) {
63
90
  rb_thread_add_event_hook2(current_thread, (rb_event_hook_func_t)eval_trace_callback, RUBY_EVENT_CALL | RUBY_EVENT_C_CALL, self, RUBY_EVENT_HOOK_FLAG_RAW_ARG | RUBY_EVENT_HOOK_FLAG_SAFE);
64
- rb_hash_aset(thread_variables_hash, rb_str_new2("gcloud_eval_trace_set"), Qtrue);
91
+ rb_hash_aset(thread_variables_hash, eval_trace_thread_flag, Qtrue);
65
92
  }
66
93
 
67
94
  return Qnil;
@@ -150,6 +150,12 @@ line_trace_callback(rb_event_flag_t event, VALUE data, VALUE obj, ID mid, VALUE
150
150
  VALUE matching_breakpoint;
151
151
  int matching_breakpoints_len;
152
152
 
153
+ ID callers_id;
154
+ ID breakpoint_hit_id;
155
+
156
+ CONST_ID(callers_id, "callers");
157
+ CONST_ID(breakpoint_hit_id, "breakpoint_hit");
158
+
153
159
  // If matching result isn't an array, it means we're in completely wrong file,
154
160
  // or not on the right line. Turn line tracing off if we're in wrong file.
155
161
  if (!RB_TYPE_P(matching_result, T_ARRAY)) {
@@ -162,13 +168,13 @@ line_trace_callback(rb_event_flag_t event, VALUE data, VALUE obj, ID mid, VALUE
162
168
  c_matching_breakpoints = RARRAY_PTR(matching_result);
163
169
  matching_breakpoints_len = RARRAY_LEN(matching_result);
164
170
  trace_binding = rb_binding_new();
165
- call_stack_bindings = rb_funcall(trace_binding, rb_intern("callers"), 0);
171
+ call_stack_bindings = rb_funcall(trace_binding, callers_id, 0);
166
172
  rb_ary_pop(call_stack_bindings);
167
173
 
168
174
  // Evaluate each of the matching breakpoint
169
175
  for (i = 0; i < matching_breakpoints_len; i++) {
170
176
  matching_breakpoint = c_matching_breakpoints[i];
171
- rb_funcall(self, rb_intern("eval_breakpoint"), 2, matching_breakpoint, call_stack_bindings);
177
+ rb_funcall(self, breakpoint_hit_id, 2, matching_breakpoint, call_stack_bindings);
172
178
  }
173
179
 
174
180
  return;
@@ -185,16 +191,23 @@ disable_line_trace_for_thread(VALUE thread)
185
191
  {
186
192
  VALUE thread_variables_hash;
187
193
  VALUE line_trace_set;
194
+ ID locals_id;
195
+ ID line_trace_thread_id;
196
+ VALUE line_trace_thread_flag;
197
+
198
+ CONST_ID(locals_id, "locals");
199
+ CONST_ID(line_trace_thread_id, "gcloud_line_trace_set");
200
+ line_trace_thread_flag = ID2SYM(line_trace_thread_id);
188
201
 
189
202
  if (!RTEST(thread)) {
190
203
  thread = rb_thread_current();
191
204
  }
192
- thread_variables_hash = rb_ivar_get(thread, rb_intern("locals"));
193
- line_trace_set = rb_hash_aref(thread_variables_hash, rb_str_new2("gcloud_line_trace_set"));
205
+ thread_variables_hash = rb_ivar_get(thread, locals_id);
206
+ line_trace_set = rb_hash_aref(thread_variables_hash, line_trace_thread_flag);
194
207
 
195
208
  if (RTEST(line_trace_set)) {
196
209
  rb_thread_remove_event_hook(thread, line_trace_callback);
197
- rb_hash_aset(thread_variables_hash, rb_str_new2("gcloud_line_trace_set"), Qfalse);
210
+ rb_hash_aset(thread_variables_hash, line_trace_thread_flag, Qfalse);
198
211
  }
199
212
 
200
213
  return Qnil;
@@ -208,13 +221,24 @@ disable_line_trace_for_thread(VALUE thread)
208
221
  static VALUE
209
222
  enable_line_trace_for_thread(VALUE self)
210
223
  {
211
- VALUE current_thread = rb_thread_current();
212
- VALUE thread_variables_hash = rb_ivar_get(current_thread, rb_intern("locals"));
213
- VALUE line_trace_set = rb_hash_aref(thread_variables_hash, rb_str_new2("gcloud_line_trace_set"));
224
+ VALUE current_thread;
225
+ VALUE thread_variables_hash;
226
+ VALUE line_trace_set;
227
+ ID locals_id;
228
+ ID line_trace_thread_id;
229
+ VALUE line_trace_thread_flag;
230
+
231
+ CONST_ID(locals_id, "locals");
232
+ CONST_ID(line_trace_thread_id, "gcloud_line_trace_set");
233
+ line_trace_thread_flag = ID2SYM(line_trace_thread_id);
234
+
235
+ current_thread = rb_thread_current();
236
+ thread_variables_hash = rb_ivar_get(current_thread, locals_id);
237
+ line_trace_set = rb_hash_aref(thread_variables_hash, line_trace_thread_flag);
214
238
 
215
239
  if (!RTEST(line_trace_set)) {
216
240
  rb_thread_add_event_hook(current_thread, line_trace_callback, RUBY_EVENT_LINE, self);
217
- rb_hash_aset(thread_variables_hash, rb_str_new2("gcloud_line_trace_set"), Qtrue);
241
+ rb_hash_aset(thread_variables_hash, line_trace_thread_flag, Qtrue);
218
242
  }
219
243
 
220
244
  return Qnil;
@@ -236,18 +260,26 @@ return_trace_callback(void *data, rb_trace_arg_t *trace_arg)
236
260
  {
237
261
  VALUE match_found;
238
262
  VALUE self = (VALUE) data;
239
- VALUE caller_locations = rb_funcall(rb_mKernel, rb_intern("caller_locations"), 2, INT2NUM(0), INT2NUM(1));
263
+ VALUE caller_locations;
240
264
  VALUE *c_caller_locations;
241
265
  VALUE caller_location;
242
266
  VALUE caller_path;
243
267
 
268
+ ID caller_locations_id;
269
+ ID absolute_path_id;
270
+
271
+ CONST_ID(caller_locations_id, "caller_locations");
272
+ CONST_ID(absolute_path_id, "absolute_path");
273
+
274
+ caller_locations = rb_funcall(rb_mKernel, caller_locations_id, 2, INT2NUM(0), INT2NUM(1));
275
+
244
276
  if(!RTEST(caller_locations)) {
245
277
  return;
246
278
  }
247
279
 
248
280
  c_caller_locations = RARRAY_PTR(caller_locations);
249
281
  caller_location = c_caller_locations[0];
250
- caller_path = rb_funcall(caller_location, rb_intern("absolute_path"), 0);
282
+ caller_path = rb_funcall(caller_location, absolute_path_id, 0);
251
283
 
252
284
  if(!RTEST(caller_path)) {
253
285
  return;
@@ -273,16 +305,23 @@ disable_return_trace_for_thread(VALUE thread)
273
305
  {
274
306
  VALUE thread_variables_hash;
275
307
  VALUE return_trace_set;
308
+ ID locals_id;
309
+ ID return_trace_thread_id;
310
+ VALUE return_trace_thread_flag;
311
+
312
+ CONST_ID(locals_id, "locals");
313
+ CONST_ID(return_trace_thread_id, "gcloud_return_trace_set");
314
+ return_trace_thread_flag = ID2SYM(return_trace_thread_id);
276
315
 
277
316
  if (!RTEST(thread)) {
278
317
  thread = rb_thread_current();
279
318
  }
280
- thread_variables_hash = rb_ivar_get(thread, rb_intern("locals"));
281
- return_trace_set = rb_hash_aref(thread_variables_hash, rb_str_new2("gcloud_return_trace_set"));
319
+ thread_variables_hash = rb_ivar_get(thread, locals_id);
320
+ return_trace_set = rb_hash_aref(thread_variables_hash, return_trace_thread_flag);
282
321
 
283
322
  if (RTEST(return_trace_set)) {
284
323
  rb_thread_remove_event_hook(thread, (rb_event_hook_func_t)return_trace_callback);
285
- rb_hash_aset(thread_variables_hash, rb_str_new2("gcloud_return_trace_set"), Qfalse);
324
+ rb_hash_aset(thread_variables_hash, return_trace_thread_flag, Qfalse);
286
325
  }
287
326
 
288
327
  return Qnil;
@@ -296,14 +335,26 @@ disable_return_trace_for_thread(VALUE thread)
296
335
  static VALUE
297
336
  enable_return_trace_for_thread(VALUE self)
298
337
  {
299
- VALUE current_thread = rb_thread_current();
300
- VALUE thread_variables_hash = rb_ivar_get(current_thread, rb_intern("locals"));
301
- VALUE return_trace_set = rb_hash_aref(thread_variables_hash, rb_str_new2("gcloud_return_trace_set"));
338
+ VALUE current_thread;
339
+ VALUE thread_variables_hash;
340
+ VALUE return_trace_set;
341
+
342
+ ID locals_id;
343
+ ID return_trace_thread_id;
344
+ VALUE return_trace_thread_flag;
345
+
346
+ CONST_ID(locals_id, "locals");
347
+ CONST_ID(return_trace_thread_id, "gcloud_return_trace_set");
348
+ return_trace_thread_flag = ID2SYM(return_trace_thread_id);
349
+
350
+ current_thread = rb_thread_current();
351
+ thread_variables_hash = rb_ivar_get(current_thread, locals_id);
352
+ return_trace_set = rb_hash_aref(thread_variables_hash, return_trace_thread_flag);
302
353
 
303
354
  if (!RTEST(return_trace_set)) {
304
355
  int return_tracepoint_event = RUBY_EVENT_END | RUBY_EVENT_RETURN | RUBY_EVENT_C_RETURN | RUBY_EVENT_B_RETURN;
305
356
  rb_thread_add_event_hook2(current_thread, (rb_event_hook_func_t)return_trace_callback, return_tracepoint_event, self, RUBY_EVENT_HOOK_FLAG_RAW_ARG | RUBY_EVENT_HOOK_FLAG_SAFE);
306
- rb_hash_aset(thread_variables_hash, rb_str_new2("gcloud_return_trace_set"), Qtrue);
357
+ rb_hash_aset(thread_variables_hash, return_trace_thread_flag, Qtrue);
307
358
  }
308
359
 
309
360
  return Qnil;
@@ -398,9 +449,14 @@ rb_disable_traces(VALUE self)
398
449
  int c_threads_len;
399
450
  VALUE thread;
400
451
  int i;
452
+ ID alive_q_id;
453
+ ID list_id;
454
+
455
+ CONST_ID(alive_q_id, "alive?");
456
+ CONST_ID(list_id, "list");
401
457
 
402
458
  file_tracepoint = rb_iv_get(self, "@file_tracepoint");
403
- threads = rb_funcall(rb_cThread, rb_intern("list"), 0);
459
+ threads = rb_funcall(rb_cThread, list_id, 0);
404
460
  c_threads_len = RARRAY_LEN(threads);
405
461
  c_threads = RARRAY_PTR(threads);
406
462
  UNUSED(fiber_tracepoint);
@@ -416,7 +472,7 @@ rb_disable_traces(VALUE self)
416
472
 
417
473
  for (i = 0; i < c_threads_len; i++) {
418
474
  thread = c_threads[i];
419
- if (RTEST(rb_funcall(thread, rb_intern("alive?"), 0))) {
475
+ if (RTEST(rb_funcall(thread, alive_q_id, 0))) {
420
476
  disable_line_trace_for_thread(thread);
421
477
  disable_return_trace_for_thread(thread);
422
478
  }
@@ -13,12 +13,13 @@
13
13
  # limitations under the License.
14
14
 
15
15
 
16
- require "google/cloud/debugger/async_actor"
17
16
  require "google/cloud/debugger/breakpoint_manager"
18
17
  require "google/cloud/debugger/debuggee"
19
18
  require "google/cloud/debugger/debugger_c"
20
19
  require "google/cloud/debugger/tracer"
21
20
  require "google/cloud/debugger/transmitter"
21
+ require "google/cloud/logging"
22
+ require "stackdriver/core/async_actor"
22
23
 
23
24
  module Google
24
25
  module Cloud
@@ -46,9 +47,13 @@ module Google
46
47
  # agent.start
47
48
  #
48
49
  class Agent
50
+ ##
51
+ # Name of the logpoints log file.
52
+ DEFAULT_LOG_NAME = "debugger_logpoints"
53
+
49
54
  ##
50
55
  # @private Debugger Agent is an asynchronous actor
51
- include AsyncActor
56
+ include Stackdriver::Core::AsyncActor
52
57
 
53
58
  ##
54
59
  # @private The gRPC Service object.
@@ -81,6 +86,10 @@ module Google
81
86
  # @return [Google::Cloud::Debugger::Transmiter]
82
87
  attr_reader :transmitter
83
88
 
89
+ ##
90
+ # The logger used to write the results of Logpoints.
91
+ attr_accessor :logger
92
+
84
93
  ##
85
94
  # @private The last exception captured in the agent child thread
86
95
  attr_reader :last_exception
@@ -90,23 +99,30 @@ module Google
90
99
  #
91
100
  # @param [Google::Cloud::Debugger::Service] service The gRPC Service
92
101
  # object
102
+ # @param [Google::Cloud::Logging::Logger] logger The logger used
103
+ # to write the results of Logpoints.
93
104
  # @param [String] module_name Name for the debuggee application.
94
105
  # Optional.
95
106
  # @param [String] module_version Version identifier for the debuggee
96
107
  # application. Optional.
97
108
  #
98
- def initialize service, module_name:, module_version:
109
+ def initialize service, logger: nil, module_name:, module_version:
99
110
  super()
100
111
 
101
112
  @service = service
102
113
  @debuggee = Debuggee.new service, module_name: module_name,
103
114
  module_version: module_version
104
115
  @tracer = Debugger::Tracer.new self
105
- @breakpoint_manager = BreakpointManager.new service
116
+ @breakpoint_manager = BreakpointManager.new self, service
106
117
  @breakpoint_manager.on_breakpoints_change =
107
118
  method :breakpoints_change_callback
108
119
 
109
- @transmitter = Transmitter.new service, self
120
+ @transmitter = Transmitter.new self, service
121
+
122
+ @logger = logger || default_logger
123
+
124
+ # Agent actor thread needs to force exit immediately.
125
+ set_cleanup_options timeout: 0
110
126
  end
111
127
 
112
128
  ##
@@ -126,7 +142,6 @@ module Google
126
142
  # Once Debugger Agent is stopped, it cannot be started again.
127
143
  #
128
144
  def stop
129
- tracer.stop
130
145
  transmitter.stop
131
146
  async_stop
132
147
  end
@@ -154,6 +169,16 @@ module Google
154
169
  @last_exception = e
155
170
  end
156
171
 
172
+ ##
173
+ # @private Callback function when the async actor thread state changes
174
+ def on_async_state_change
175
+ if async_running?
176
+ tracer.start
177
+ else
178
+ tracer.stop
179
+ end
180
+ end
181
+
157
182
  private
158
183
 
159
184
  ##
@@ -184,19 +209,17 @@ module Google
184
209
  end
185
210
 
186
211
  ##
187
- # @private Override AsyncActor#async_stop to immediately kill the child
188
- # thread instead of waiting for it to return, because the breakpoints
189
- # are queried with a hanging long poll mechanism.
190
- def async_stop
191
- @startup_lock.synchronize do
192
- unless @thread.nil?
193
- tracer.stop
194
-
195
- @async_state = :stopped
196
- @thread.kill
197
- @thread.join
198
- end
199
- end
212
+ # @private Create a default logger
213
+ def default_logger
214
+ project_id = @service.project
215
+ credentials = @service.credentials
216
+ logging = Google::Cloud::Logging::Project.new(
217
+ Google::Cloud::Logging::Service.new(
218
+ project_id, credentials))
219
+ resource =
220
+ Google::Cloud::Logging::Middleware.build_monitored_resource
221
+
222
+ logging.logger DEFAULT_LOG_NAME, resource
200
223
  end
201
224
  end
202
225
  end
@@ -29,10 +29,26 @@ module Google
29
29
  # Breakpoint identifier, unique in the scope of the debuggee.
30
30
  attr_accessor :id
31
31
 
32
- # TODO: Implement logpoint
33
- # attr_accessor :action
34
- # attr_accessor :log_message_format
35
- # attr_accessor :log_level
32
+ ##
33
+ # Action to take when a breakpoint is hit. Either :CAPTURE or :LOG.
34
+ # @return [Symbol]
35
+ attr_accessor :action
36
+
37
+ ##
38
+ # Only relevant when action is LOG. Defines the message to log when the
39
+ # breakpoint hits. The message may include parameter placeholders $0,
40
+ # $1, etc. These placeholders are replaced with the evaluated value of
41
+ # the appropriate expression. Expressions not referenced in
42
+ # logMessageFormat are not logged.
43
+ attr_accessor :log_message_format
44
+
45
+ ##
46
+ # Indicates the severity of the log. Only relevant when action is LOG.
47
+ attr_accessor :log_level
48
+
49
+ ##
50
+ # The evaluated log message when action is LOG.
51
+ attr_accessor :evaluated_log_message
36
52
 
37
53
  ##
38
54
  # Breakpoint source location.
@@ -128,7 +144,7 @@ module Google
128
144
  super()
129
145
 
130
146
  @id = id
131
- # @action = :capture
147
+ @action = :CAPTURE
132
148
  @location = SourceLocation.new.tap do |sl|
133
149
  sl.path = path
134
150
  sl.line = line.to_i
@@ -144,19 +160,23 @@ module Google
144
160
  # from a Google::Devtools::Clouddebugger::V2::Breakpoint object.
145
161
  def self.from_grpc grpc
146
162
  return new if grpc.nil?
147
- new(grpc.id).tap do |b|
148
- b.location = Breakpoint::SourceLocation.from_grpc grpc.location
163
+ new.tap do |b|
164
+ b.id = grpc.id
165
+ b.action = grpc.action
149
166
  b.condition = grpc.condition
150
- b.is_final_state = grpc.is_final_state
151
- b.expressions = grpc.expressions.to_a
167
+ b.create_time = timestamp_from_grpc grpc.create_time
152
168
  b.evaluated_expressions =
153
169
  Breakpoint::Variable.from_grpc_list grpc.evaluated_expressions
154
- b.create_time = timestamp_from_grpc grpc.create_time
170
+ b.expressions = grpc.expressions.to_a
155
171
  b.final_time = timestamp_from_grpc grpc.final_time
156
- b.user_email = grpc.user_email
157
- b.status = grpc.status
158
172
  b.labels = hashify_labels grpc.labels
173
+ b.log_message_format = grpc.log_message_format
174
+ b.log_level = grpc.log_level
175
+ b.location = Breakpoint::SourceLocation.from_grpc grpc.location
176
+ b.is_final_state = grpc.is_final_state
177
+ b.status = grpc.status
159
178
  b.stack_frames = stack_frames_from_grpc grpc
179
+ b.user_email = grpc.user_email
160
180
  end
161
181
  end
162
182
 
@@ -243,9 +263,11 @@ module Google
243
263
  end
244
264
 
245
265
  ##
246
- # Evaluate the breakpoint unless it's already marked as completed. Use
247
- # "@stack_frames" and "@evaluated_expressions" instance variables to
248
- # store the result snapshot. Set breakpoint to complete when done.
266
+ # Evaluate the breakpoint unless it's already marked as completed.
267
+ # Store evaluted results in @evaluated_expressions, @stack_frames, and
268
+ # @evaluated_log_message, depends on the action of breakpoint. Mark
269
+ # breakpoint complete if successfully evaluated a breakpoint with
270
+ # :CAPTURE action.
249
271
  #
250
272
  # @param [Array<Binding>] call_stack_bindings An array of Ruby Binding
251
273
  # objects, from the call stack that leads to the triggering of the
@@ -253,28 +275,13 @@ module Google
253
275
  #
254
276
  # @return [Boolean] True if evaluated successfully; false otherwise.
255
277
  #
256
- def eval_call_stack call_stack_bindings
257
- synchronize do
258
- return false if complete?
259
-
260
- top_frame_binding = call_stack_bindings[0]
261
-
262
- # Abort evaluation if breakpoint condition isn't met
263
- return false unless check_condition top_frame_binding
264
-
265
- begin
266
- @stack_frames = Evaluator.eval_call_stack call_stack_bindings
267
- unless expressions.empty?
268
- @evaluated_expressions =
269
- Evaluator.eval_expressions top_frame_binding, @expressions
270
- end
271
- rescue
272
- return false
273
- end
274
-
275
- complete
278
+ def evaluate call_stack_bindings
279
+ case action
280
+ when :CAPTURE
281
+ evaluate_snapshot_point call_stack_bindings
282
+ when :LOG
283
+ evaluate_logpoint call_stack_bindings[0]
276
284
  end
277
- true
278
285
  end
279
286
 
280
287
  ##
@@ -342,6 +349,55 @@ module Google
342
349
 
343
350
  private
344
351
 
352
+ ##
353
+ # @private Evaluate snapshot point
354
+ def evaluate_snapshot_point call_stack_bindings
355
+ synchronize do
356
+ top_binding = call_stack_bindings[0]
357
+
358
+ return false if complete? || !check_condition(top_binding)
359
+
360
+ begin
361
+ unless expressions.empty?
362
+ @evaluated_expressions =
363
+ Evaluator.eval_expressions top_binding, @expressions
364
+ end
365
+
366
+ @stack_frames = Evaluator.eval_call_stack call_stack_bindings
367
+
368
+ complete
369
+ rescue
370
+ return false
371
+ end
372
+ end
373
+
374
+ true
375
+ end
376
+
377
+ ##
378
+ # @private Evaluate logpoint
379
+ def evaluate_logpoint binding
380
+ synchronize do
381
+ return false if complete? || !check_condition(binding)
382
+
383
+ begin
384
+ unless expressions.empty?
385
+ @evaluated_expressions = expressions.map do |expression|
386
+ Evaluator.readonly_eval_expression binding, expression
387
+ end
388
+ end
389
+ @evaluated_log_message =
390
+ Evaluator.format_message log_message_format,
391
+ evaluated_expressions
392
+ rescue
393
+ return false
394
+ end
395
+ end
396
+
397
+ true
398
+ end
399
+
400
+
345
401
  ##
346
402
  # @private Formats the labels so they can be saved to a
347
403
  # Google::Devtools::Clouddebugger::V2::Breakpoint object.