Project

General

Profile

Bug #18886

Updated by ioquatix (Samuel Williams) over 2 years ago

Given the following program, `thing.name` and `thing.shape` don't trigger `c_call` trace points (or any trace points actually). 

 ```ruby 
 pp RUBY_VERSION 

 trace_point = TracePoint.new(:line, :call, :c_call, :a_call) do |trace| 
   puts trace.event 

   
	 if trace.event == :call 
     
		 # Ruby doesn't always mark call-sites in sub-expressions, so we use this approach to compute a call site and mark it: 
     
		 if location = caller_locations(2, 1).first and path = location.path 
       
			 puts "> #{path}:#{location.lineno}:#{trace.event}" 
     #{path}:#{location.lineno}:#{trace.event}:#{trace.method_id}" 
		 end 
   
	 end 
  
   
	
	 if path = trace.path 
     
		 puts "= #{path}:#{trace.lineno}:#{trace.event}" 
   #{path}:#{trace.lineno}:#{trace.event}:#{trace.method_id}" 
	 end 
 end 

 trace_point.enable 

 # This will trigger call trace points 
 # class Thing 
   
 #  	 def name 
     
 #  		 :cat 
   
 #  	 end 
  
   
	
 #  	 def shape 
     
 #  		 :square 
   
 #  	 end 
 # end 
 # thing = Thing.new 

 # Thing = Struct.new(:name, :shape) 
 # thing = Thing.new(:cat, :rectangle) 

 [ 
   
	 name: thing.name, 
   
	 shape: thing.shape, 
 ] 
 ``` 

 ## Current HEAD 

 ``` 
 = ../test.rb:30:line: 
 = ../test.rb:30:c_call:new 
 = ../test.rb:30:c_call:inherited 
 = ../test.rb:30:c_call:singleton_method_added 
 = ../test.rb:30:c_call:singleton_method_added 
 = ../test.rb:30:c_call:singleton_method_added 
 = ../test.rb:30:c_call:singleton_method_added 
 = ../test.rb:30:c_call:singleton_method_added 
 = ../test.rb:30:c_call:method_added 
 = ../test.rb:30:c_call:method_added 
 = ../test.rb:30:c_call:method_added 
 = ../test.rb:30:c_call:method_added 
 = ../test.rb:30:c_call:const_added 
 = ../test.rb:31:line: 
 = ../test.rb:31:c_call:new 
 = ../test.rb:31:c_call:initialize 
 = ../test.rb:34:line: 
 ``` 

 ## Proposed PR 

 ``` 
 = ../test.rb:30:line: 
 = ../test.rb:30:c_call:new 
 = ../test.rb:30:c_call:inherited 
 = ../test.rb:30:c_call:singleton_method_added 
 = ../test.rb:30:c_call:singleton_method_added 
 = ../test.rb:30:c_call:singleton_method_added 
 = ../test.rb:30:c_call:singleton_method_added 
 = ../test.rb:30:c_call:singleton_method_added 
 = ../test.rb:30:c_call:method_added 
 = ../test.rb:30:c_call:method_added 
 = ../test.rb:30:c_call:method_added 
 = ../test.rb:30:c_call:method_added 
 = ../test.rb:30:c_call:const_added 
 = ../test.rb:31:line: 
 = ../test.rb:31:c_call:new 
 = ../test.rb:31:c_call:initialize 
 = ../test.rb:34:line: 
 = ../test.rb:34:c_call:name 
 = ../test.rb:35:c_call:shape 
 ``` 

 The reason is the internal implementation of struct doesn't have trace point instrumentation in `vm_call_opt_struct_aset` or `vm_call_opt_struct_aref`. 

 Proposed fix: https://github.com/ruby/ruby/pull/6071 but this would need a review, maybe @jeremyevans0 and @ko1 can help.

Back