[ruby-core:70080] [Ruby trunk - Bug #11383] Infinite loop in str_buf_cat triggered by str_gsub

From: nobu@...
Date: 2015-07-22 07:18:34 UTC
List: ruby-core #70080
Issue #11383 has been updated by Nobuyoshi Nakada.

File bug-11383.log added
Description updated

Very interesting.
An empty string is usually embedding, and I can't tell why there is an empty non-embed string.
Couldn't you show its content, `*(struct RString *)str`?

----------------------------------------
Bug #11383: Infinite loop in str_buf_cat triggered by str_gsub
https://bugs.ruby-lang.org/issues/11383#change-53494

* Author: Laurent Farcy
* Status: Open
* Priority: Normal
* Assignee: 
* ruby -v: ruby 2.2.2p95 (2015-04-13 revision 50295) [x86_64-linux]
* Backport: 2.0.0: UNKNOWN, 2.1: UNKNOWN, 2.2: UNKNOWN
----------------------------------------
I've got a Ruby program which reads some RSS/Atom feeds to load each of them into a relational database. It makes use of a modified version of SimpleRSS v1.2.

After moving to Ruby 2.2.2, I observe 100% CPU usage from time to time. Using gdb, I was able to identify the culprit: it's a call to `str_buf_cat` from `str_gsub`. Here's the section of code that loops in `string.c` (from line 2198 til line 2204).

~~~c
	while (total > capa) {
	    if (capa > LONG_MAX / 2) {
		capa = (total + 4095) / 4096 * 4096;
		break;
	    }
	    capa = 2 * capa;
	}
~~~

`capa` is equal to 0 when the while block infinitely loops. I guess it's somehow unexpected...

Unfortunately, since the VM is looping, I cannot determine the piece of 'my' code where `gsub` is used. `rb_eval`, as found in https://github.com/michaelklishin/gdb-macros-for-ruby/blob/master/gdb_macros_for_ruby, cannot work because rb_finish cannot terminate.

But I was able to dump the backtrace and all the args and locals that lead to the infinite loop.


---Files--------------------------------
bug-11383.log (22.8 KB)


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

In This Thread

Prev Next