ruby-core@ruby-lang.org archive (unofficial mirror)
 help / color / mirror / Atom feed
* [ruby-core:90085] [Ruby trunk Bug#15346] Core dump during GC if covering a special require
       [not found] <redmine.issue-15346.20181127054646@ruby-lang.org>
@ 2018-11-27  5:46 ` hunter_spawn
  2018-11-27  7:40 ` [ruby-core:90086] " mame
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 5+ messages in thread
From: hunter_spawn @ 2018-11-27  5:46 UTC (permalink / raw)
  To: ruby-core

Issue #15346 has been reported by MaxLap (Maxime Lapointe).

----------------------------------------
Bug #15346: Core dump during GC if covering a special require
https://bugs.ruby-lang.org/issues/15346

* Author: MaxLap (Maxime Lapointe)
* Status: Open
* Priority: Normal
* Assignee: 
* Target version: 
* ruby -v: ruby 2.6.0dev (2018-11-27 trunk 66002) [x86_64-linux]
* Backport: 2.4: UNKNOWN, 2.5: UNKNOWN
----------------------------------------
On my environment, (ruby-head, updated today) the following script generates a core dump almost all the time. (I join a core dump to this report)

I am running on Ubuntu 16.04, I first saw the problem on Travis-CI and managed to make this much simpler reproduction code.

~~~ ruby
# Just setting up a file to require, this could be in a regular file and be required.
require 'tempfile'
f = Tempfile.new(['ruby', '.rb'])
f.write(<<-RUBY)
  a = 123
  begin
  ensure
    a
  end
RUBY
f.close

# Now the actual code to trigger the problem
require 'coverage'
Coverage.start
load f.path # require can do the same thing, but less frequently

# The problem is during GC, so we trigger it ourself
puts 'gc time!'
GC.start

# When it doesn't crash the first time, doing the load/require again seems to take care of it
puts '2nd gc'
load f.path
GC.start

puts 'gc done, try again!'
~~~

The problem seems related to the content of the ensure, if it's too simple, things break? It's weird.
If the content of the ensure is:
  a
  puts 'something'
  #=> All good

  puts 'something'
  a
  #=> Core dump

  puts 'something'; a
  #=> All good

  a + 1
  #=> All good

My personal guess is, if the last line of the ensure is useless, ruby optimizes it away, but that causes a problem with Coverage.


---Files--------------------------------
cov-require_core_dump.txt (10.4 KB)


-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [ruby-core:90086] [Ruby trunk Bug#15346] Core dump during GC if covering a special require
       [not found] <redmine.issue-15346.20181127054646@ruby-lang.org>
  2018-11-27  5:46 ` [ruby-core:90085] [Ruby trunk Bug#15346] Core dump during GC if covering a special require hunter_spawn
@ 2018-11-27  7:40 ` mame
  2018-11-27  8:00 ` [ruby-core:90087] " mame
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 5+ messages in thread
From: mame @ 2018-11-27  7:40 UTC (permalink / raw)
  To: ruby-core

Issue #15346 has been updated by mame (Yusuke Endoh).


This report is awesome.  Thank you very much!

The coverage counters are initialized with `counter[lineno - 1] = 0`.  However, the lineno of ensure clause is 0 (for unknown reason).  So it caused write access for index -1, which broke malloc header.

For now, I did a preventive commit to prevent this behavior (just ignore when lineno == 0).  I'll continue to investigate the reason why the lineno is 0.

Again, I really appreciate you!

----------------------------------------
Bug #15346: Core dump during GC if covering a special require
https://bugs.ruby-lang.org/issues/15346#change-75211

* Author: MaxLap (Maxime Lapointe)
* Status: Open
* Priority: Normal
* Assignee: 
* Target version: 
* ruby -v: ruby 2.6.0dev (2018-11-27 trunk 66002) [x86_64-linux]
* Backport: 2.4: UNKNOWN, 2.5: UNKNOWN
----------------------------------------
On my environment, (ruby-head, updated today) the following script generates a core dump almost all the time. (I join a core dump to this report)

I am running on Ubuntu 16.04, I first saw the problem on Travis-CI and managed to make this much simpler reproduction code.

~~~ ruby
# Just setting up a file to require, this could be in a regular file and be required.
require 'tempfile'
f = Tempfile.new(['ruby', '.rb'])
f.write(<<-RUBY)
  a = 123
  begin
  ensure
    a
  end
RUBY
f.close

# Now the actual code to trigger the problem
require 'coverage'
Coverage.start
load f.path # require can do the same thing, but less frequently

# The problem is during GC, so we trigger it ourself
puts 'gc time!'
GC.start

# When it doesn't crash the first time, doing the load/require again seems to take care of it
puts '2nd gc'
load f.path
GC.start

puts 'gc done, try again!'
~~~

The problem seems related to the content of the ensure, if it's too simple, things break? It's weird.
If the content of the ensure is:
  a
  puts 'something'
  #=> All good

  puts 'something'
  a
  #=> Core dump

  puts 'something'; a
  #=> All good

  a + 1
  #=> All good

My personal guess is, if the last line of the ensure is useless, ruby optimizes it away, but that causes a problem with Coverage.


---Files--------------------------------
cov-require_core_dump.txt (10.4 KB)


-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [ruby-core:90087] [Ruby trunk Bug#15346] Core dump during GC if covering a special require
       [not found] <redmine.issue-15346.20181127054646@ruby-lang.org>
  2018-11-27  5:46 ` [ruby-core:90085] [Ruby trunk Bug#15346] Core dump during GC if covering a special require hunter_spawn
  2018-11-27  7:40 ` [ruby-core:90086] " mame
@ 2018-11-27  8:00 ` mame
  2018-11-27 22:14 ` [ruby-core:90098] " hunter_spawn
  2019-01-20  4:34 ` [ruby-core:91185] " nagachika00
  4 siblings, 0 replies; 5+ messages in thread
From: mame @ 2018-11-27  8:00 UTC (permalink / raw)
  To: ruby-core

Issue #15346 has been updated by mame (Yusuke Endoh).


The commit was r66025.  (I have no idea why the commit is not automatically related to this ticket.)

I investigated the reason why lineno is 0.  In Ruby bytecode, each instruction has lineno information.  However, the ensure clause has no significant code (because the return value of ensure is just discarded), so the compiler does emit no instruction for the code.  So, the lineno of the ensure clause cannot be identified, which led to lineno 0.  This behavior looks benign, and coverage initialization can ignore them.

So, I'd like to make r66025 final for this issue.  Let me know if you found any weird behavior.  Thank you very much.

----------------------------------------
Bug #15346: Core dump during GC if covering a special require
https://bugs.ruby-lang.org/issues/15346#change-75213

* Author: MaxLap (Maxime Lapointe)
* Status: Closed
* Priority: Normal
* Assignee: 
* Target version: 
* ruby -v: ruby 2.6.0dev (2018-11-27 trunk 66002) [x86_64-linux]
* Backport: 2.4: UNKNOWN, 2.5: UNKNOWN
----------------------------------------
On my environment, (ruby-head, updated today) the following script generates a core dump almost all the time. (I join a core dump to this report)

I am running on Ubuntu 16.04, I first saw the problem on Travis-CI and managed to make this much simpler reproduction code.

~~~ ruby
# Just setting up a file to require, this could be in a regular file and be required.
require 'tempfile'
f = Tempfile.new(['ruby', '.rb'])
f.write(<<-RUBY)
  a = 123
  begin
  ensure
    a
  end
RUBY
f.close

# Now the actual code to trigger the problem
require 'coverage'
Coverage.start
load f.path # require can do the same thing, but less frequently

# The problem is during GC, so we trigger it ourself
puts 'gc time!'
GC.start

# When it doesn't crash the first time, doing the load/require again seems to take care of it
puts '2nd gc'
load f.path
GC.start

puts 'gc done, try again!'
~~~

The problem seems related to the content of the ensure, if it's too simple, things break? It's weird.
If the content of the ensure is:
  a
  puts 'something'
  #=> All good

  puts 'something'
  a
  #=> Core dump

  puts 'something'; a
  #=> All good

  a + 1
  #=> All good

My personal guess is, if the last line of the ensure is useless, ruby optimizes it away, but that causes a problem with Coverage.


---Files--------------------------------
cov-require_core_dump.txt (10.4 KB)


-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [ruby-core:90098] [Ruby trunk Bug#15346] Core dump during GC if covering a special require
       [not found] <redmine.issue-15346.20181127054646@ruby-lang.org>
                   ` (2 preceding siblings ...)
  2018-11-27  8:00 ` [ruby-core:90087] " mame
@ 2018-11-27 22:14 ` hunter_spawn
  2019-01-20  4:34 ` [ruby-core:91185] " nagachika00
  4 siblings, 0 replies; 5+ messages in thread
From: hunter_spawn @ 2018-11-27 22:14 UTC (permalink / raw)
  To: ruby-core

Issue #15346 has been updated by MaxLap (Maxime Lapointe).


Wow, very fast handling, thank you.

I confirm that this seems to have solved things on my end. Travis has not updated their ruby-head yet, but I assume it will be fine there too.

Thanks again

----------------------------------------
Bug #15346: Core dump during GC if covering a special require
https://bugs.ruby-lang.org/issues/15346#change-75221

* Author: MaxLap (Maxime Lapointe)
* Status: Closed
* Priority: Normal
* Assignee: 
* Target version: 
* ruby -v: ruby 2.6.0dev (2018-11-27 trunk 66002) [x86_64-linux]
* Backport: 2.4: UNKNOWN, 2.5: UNKNOWN
----------------------------------------
On my environment, (ruby-head, updated today) the following script generates a core dump almost all the time. (I join a core dump to this report)

I am running on Ubuntu 16.04, I first saw the problem on Travis-CI and managed to make this much simpler reproduction code.

~~~ ruby
# Just setting up a file to require, this could be in a regular file and be required.
require 'tempfile'
f = Tempfile.new(['ruby', '.rb'])
f.write(<<-RUBY)
  a = 123
  begin
  ensure
    a
  end
RUBY
f.close

# Now the actual code to trigger the problem
require 'coverage'
Coverage.start
load f.path # require can do the same thing, but less frequently

# The problem is during GC, so we trigger it ourself
puts 'gc time!'
GC.start

# When it doesn't crash the first time, doing the load/require again seems to take care of it
puts '2nd gc'
load f.path
GC.start

puts 'gc done, try again!'
~~~

The problem seems related to the content of the ensure, if it's too simple, things break? It's weird.
If the content of the ensure is:
  a
  puts 'something'
  #=> All good

  puts 'something'
  a
  #=> Core dump

  puts 'something'; a
  #=> All good

  a + 1
  #=> All good

My personal guess is, if the last line of the ensure is useless, ruby optimizes it away, but that causes a problem with Coverage.


---Files--------------------------------
cov-require_core_dump.txt (10.4 KB)


-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [ruby-core:91185] [Ruby trunk Bug#15346] Core dump during GC if covering a special require
       [not found] <redmine.issue-15346.20181127054646@ruby-lang.org>
                   ` (3 preceding siblings ...)
  2018-11-27 22:14 ` [ruby-core:90098] " hunter_spawn
@ 2019-01-20  4:34 ` nagachika00
  4 siblings, 0 replies; 5+ messages in thread
From: nagachika00 @ 2019-01-20  4:34 UTC (permalink / raw)
  To: ruby-core

Issue #15346 has been updated by nagachika (Tomoyuki Chikanaga).

Backport changed from 2.4: UNKNOWN, 2.5: REQUIRED to 2.4: DONTNEED, 2.5: DONTNEED

I misunderstood this could be reproducible in 2.5 but it isn't.

----------------------------------------
Bug #15346: Core dump during GC if covering a special require
https://bugs.ruby-lang.org/issues/15346#change-76416

* Author: MaxLap (Maxime Lapointe)
* Status: Closed
* Priority: Normal
* Assignee: 
* Target version: 
* ruby -v: ruby 2.6.0dev (2018-11-27 trunk 66002) [x86_64-linux]
* Backport: 2.4: DONTNEED, 2.5: DONTNEED
----------------------------------------
On my environment, (ruby-head, updated today) the following script generates a core dump almost all the time. (I join a core dump to this report)

I am running on Ubuntu 16.04, I first saw the problem on Travis-CI and managed to make this much simpler reproduction code.

~~~ ruby
# Just setting up a file to require, this could be in a regular file and be required.
require 'tempfile'
f = Tempfile.new(['ruby', '.rb'])
f.write(<<-RUBY)
  a = 123
  begin
  ensure
    a
  end
RUBY
f.close

# Now the actual code to trigger the problem
require 'coverage'
Coverage.start
load f.path # require can do the same thing, but less frequently

# The problem is during GC, so we trigger it ourself
puts 'gc time!'
GC.start

# When it doesn't crash the first time, doing the load/require again seems to take care of it
puts '2nd gc'
load f.path
GC.start

puts 'gc done, try again!'
~~~

The problem seems related to the content of the ensure, if it's too simple, things break? It's weird.
If the content of the ensure is:
  a
  puts 'something'
  #=> All good

  puts 'something'
  a
  #=> Core dump

  puts 'something'; a
  #=> All good

  a + 1
  #=> All good

My personal guess is, if the last line of the ensure is useless, ruby optimizes it away, but that causes a problem with Coverage.


---Files--------------------------------
cov-require_core_dump.txt (10.4 KB)


-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2019-01-20  4:34 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <redmine.issue-15346.20181127054646@ruby-lang.org>
2018-11-27  5:46 ` [ruby-core:90085] [Ruby trunk Bug#15346] Core dump during GC if covering a special require hunter_spawn
2018-11-27  7:40 ` [ruby-core:90086] " mame
2018-11-27  8:00 ` [ruby-core:90087] " mame
2018-11-27 22:14 ` [ruby-core:90098] " hunter_spawn
2019-01-20  4:34 ` [ruby-core:91185] " nagachika00

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).