1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

Replace Kernel#pp after PP class is defined.

Avoid a race condition which a context switch
occur after replacing Kernel#pp but before
defining PP class.

Following patch, inserting sleep, makes
this problem reproducible.

```
Index: lib/pp.rb
===================================================================
--- lib/pp.rb	(revision 60960)
+++ lib/pp.rb	(working copy)
@@ -26,6 +26,7 @@ module Kernel
   end
   undef __pp_backup__ if method_defined?(:__pp_backup__)
   module_function :pp
+  sleep 1 # thread context switch
 end
 
 ##
```

With the above patch, "uninitialized constant Kernel::PP" can
happen as as follows.

```
% ./ruby -w -Ilib -e '
t1 = Thread.new {
  Thread.current.report_on_exception = true
  pp :foo1
}
t2 = Thread.new {
  Thread.current.report_on_exception = true
  sleep 0.5
  pp :foo2
}
t1.join rescue nil
t2.join rescue nil
'
#<Thread:0x000055dbf926eaa0@-e:6 run> terminated with exception:
Traceback (most recent call last):
	3: from -e:9:in `block in <main>'
	2: from /home/ruby/tst2/ruby/lib/pp.rb:22:in `pp'
	1: from /home/ruby/tst2/ruby/lib/pp.rb:22:in `each'
/home/ruby/tst2/ruby/lib/pp.rb:23:in `block in pp': uninitialized constant Kernel::PP (NameError)
:foo1
```



git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60961 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
akr 2017-12-01 10:48:29 +00:00
parent 58d572d6aa
commit add309c496

View file

@ -2,32 +2,6 @@
require 'prettyprint'
module Kernel
# Returns a pretty printed object as a string.
#
# In order to use this method you must first require the PP module:
#
# require 'pp'
#
# See the PP module for more information.
def pretty_inspect
PP.pp(self, ''.dup)
end
# prints arguments in pretty form.
#
# pp returns argument(s).
alias __pp_backup__ pp if method_defined?(:pp)
def pp(*objs)
objs.each {|obj|
PP.pp(obj)
}
objs.size <= 1 ? objs.first : objs
end
undef __pp_backup__ if method_defined?(:__pp_backup__)
module_function :pp
end
##
# A pretty-printer for Ruby objects.
#
@ -562,3 +536,30 @@ end
end
}
}
module Kernel
# Returns a pretty printed object as a string.
#
# In order to use this method you must first require the PP module:
#
# require 'pp'
#
# See the PP module for more information.
def pretty_inspect
PP.pp(self, ''.dup)
end
# prints arguments in pretty form.
#
# pp returns argument(s).
alias __pp_backup__ pp if method_defined?(:pp)
def pp(*objs)
objs.each {|obj|
PP.pp(obj)
}
objs.size <= 1 ? objs.first : objs
end
undef __pp_backup__ if method_defined?(:__pp_backup__)
module_function :pp
end