Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Segfault possibly caused by mysql2 0.4.0 (with test case) #1063

Open
64kramsystem opened this issue Aug 29, 2019 · 4 comments
Open

Segfault possibly caused by mysql2 0.4.0 (with test case) #1063

64kramsystem opened this issue Aug 29, 2019 · 4 comments
Milestone

Comments

@64kramsystem
Copy link

64kramsystem commented Aug 29, 2019

Hello!

I'm getting a segfault under certain circumstances. I'm not sure what is the exact cause, but it may be related to mysql2.

Test setups and issue reproducibility:

  • Ruby 2.4.6, Rails 5.0.7, mysql2 0.5.2 -> ok
  • Ruby 2.4.6, Rails 4.2.11.1, mysql2 0.4.10 -> kaboom!
  • Ruby 2.5.5, Rails 4.2.11.1, mysql2 0.4.10 -> kaboom!
  • Other setups also caused the segfault

My system is an Ubuntu 18.04-based distro. The db is MySQL 8.0.13 (defaults: utf8m4/utf8mb4_0900_ai_ci; note that Rails sets, by default, the charset to utf8).
I've reproduced it on two separate machines (but configured in a very similar way).

Test case, to be run with bash:

MYSQL_USER=
export MYSQL_PWD=
export MYSQL_SOCKET= # fill only if required

ruby -v # 2.4.6
gem install rails --version '~> 4.2.0'
rails new testjor
cd !$
bin/spring binstub --remove --all # rails new --skip-spring has no effect
echo "gem 'mysql2', '~> 0.4.0'" >> Gemfile
bundle install
bundle exec gem list '^(rails|mysql2)$' # 0.4.10/4.2.11.1
echo 'class MyModel < ActiveRecord::Base; end' > app/models/my_model.rb
mysql -u "$MYSQL_USER" -e 'CREATE SCHEMA testissue; CREATE TABLE testissue.my_models (id INT PRIMARY KEY AUTO_INCREMENT, myint INT, mystr VARCHAR(255))'
perl -i -pe 's/db\/development.sqlite3/testissue/' config/database.yml
perl -i -pe 's/(adapter:) sqlite3/$1 mysql2/' !$
[[ "$MYSQL_SOCKET" != "" ]] && perl -i -lpe '/adapter/ && print "  socket: $ENV{MYSQL_SOCKET}"' !$
bundle exec rails r "MyModel.count" # kaboom!

Segfault output:

<gems_path>/activerecord-4.2.11.1/lib/active_record/connection_adapters/mysql2_adapter.rb:57: [BUG] Segmentation fault at 0x0000000000000ba9
ruby 2.4.6p354 (2019-04-01 revision 67394) [x86_64-linux]

-- Control frame information -----------------------------------------------
c:0027 p:---- s:0151 e:000150 CFUNC  :each
c:0026 p:0022 s:0146 E:0004c8 METHOD <gems_path>/activerecord-4.2.11.1/lib/active_record/connection_adapters/mysql2_adapter.rb:57 [FINISH]
c:0025 p:---- s:0141 e:000140 CFUNC  :each
c:0024 p:---- s:0138 E:000130 CFUNC  :map
c:0023 p:0014 s:0134 E:0005b8 BLOCK  <gems_path>/activerecord-4.2.11.1/lib/active_record/connection_adapters/abstract_mysql_adapter.rb:4
c:0022 p:0017 s:0130 e:000129 METHOD <gems_path>/activerecord-4.2.11.1/lib/active_record/connection_adapters/abstract_mysql_adapter.rb:3
c:0021 p:0028 s:0124 E:000490 METHOD <gems_path>/activerecord-4.2.11.1/lib/active_record/connection_adapters/abstract_mysql_adapter.rb:4
c:0020 p:0028 s:0118 e:000114 METHOD <gems_path>/activerecord-4.2.11.1/lib/active_record/connection_adapters/schema_cache.rb:43
c:0019 p:0033 s:0110 e:000108 METHOD <gems_path>/activerecord-4.2.11.1/lib/active_record/attributes.rb:93
c:0018 p:0022 s:0105 e:000104 METHOD <gems_path>/activerecord-4.2.11.1/lib/active_record/model_schema.rb:260
c:0017 p:0010 s:0101 e:000100 METHOD <gems_path>/activerecord-4.2.11.1/lib/active_record/relation/calculations.rb:232
c:0016 p:0108 s:0096 e:000095 METHOD <gems_path>/activerecord-4.2.11.1/lib/active_record/relation/calculations.rb:258
c:0015 p:0159 s:0080 e:000079 METHOD <gems_path>/activerecord-4.2.11.1/lib/active_record/relation/calculations.rb:227
c:0014 p:0079 s:0072 e:000071 METHOD <gems_path>/activerecord-4.2.11.1/lib/active_record/relation/calculations.rb:133
c:0013 p:0063 s:0065 e:000064 METHOD <gems_path>/activerecord-4.2.11.1/lib/active_record/relation/calculations.rb:48
c:0012 p:0022 s:0059 e:000058 METHOD <gems_path>/activerecord-4.2.11.1/lib/active_record/querying.rb:13
c:0011 p:0012 s:0051 e:000050 EVAL   <gems_path>/railties-4.2.11.1/lib/rails/commands/runner.rb:62 [FINISH]
c:0010 p:---- s:0048 e:000047 CFUNC  :eval
c:0009 p:0285 s:0040 E:001720 TOP    <gems_path>/railties-4.2.11.1/lib/rails/commands/runner.rb:62 [FINISH]
c:0008 p:---- s:0035 e:000034 CFUNC  :require
c:0007 p:0015 s:0030 E:000ec8 METHOD <gems_path>/railties-4.2.11.1/lib/rails/commands/commands_tasks.rb:123
c:0006 p:0010 s:0025 E:0002f0 METHOD <gems_path>/railties-4.2.11.1/lib/rails/commands/commands_tasks.rb:90
c:0005 p:0036 s:0021 E:000438 METHOD <gems_path>/railties-4.2.11.1/lib/rails/commands/commands_tasks.rb:39
c:0004 p:0123 s:0016 E:001320 TOP    <gems_path>/railties-4.2.11.1/lib/rails/commands.rb:17 [FINISH]
c:0003 p:---- s:0011 e:000010 CFUNC  :require
c:0002 p:0037 s:0006 E:000600 EVAL   bin/rails:4 [FINISH]
c:0001 p:0000 s:0003 E:001d70 (none) [FINISH]

-- Ruby level backtrace information ----------------------------------------
bin/rails:4:in `<main>'
bin/rails:4:in `require'
<gems_path>/railties-4.2.11.1/lib/rails/commands.rb:17:in `<top (required)>'
<gems_path>/railties-4.2.11.1/lib/rails/commands/commands_tasks.rb:39:in `run_command!'
<gems_path>/railties-4.2.11.1/lib/rails/commands/commands_tasks.rb:90:in `runner'
<gems_path>/railties-4.2.11.1/lib/rails/commands/commands_tasks.rb:123:in `require_command!'
<gems_path>/railties-4.2.11.1/lib/rails/commands/commands_tasks.rb:123:in `require'
<gems_path>/railties-4.2.11.1/lib/rails/commands/runner.rb:62:in `<top (required)>'
<gems_path>/railties-4.2.11.1/lib/rails/commands/runner.rb:62:in `eval'
<gems_path>/railties-4.2.11.1/lib/rails/commands/runner.rb:62:in `<top (required)>'
<gems_path>/activerecord-4.2.11.1/lib/active_record/querying.rb:13:in `count'
<gems_path>/activerecord-4.2.11.1/lib/active_record/relation/calculations.rb:48:in `count'
<gems_path>/activerecord-4.2.11.1/lib/active_record/relation/calculations.rb:133:in `calculate'
<gems_path>/activerecord-4.2.11.1/lib/active_record/relation/calculations.rb:227:in `perform_calculation'
<gems_path>/activerecord-4.2.11.1/lib/active_record/relation/calculations.rb:258:in `execute_simple_calculation'
<gems_path>/activerecord-4.2.11.1/lib/active_record/relation/calculations.rb:232:in `aggregate_column'
<gems_path>/activerecord-4.2.11.1/lib/active_record/model_schema.rb:260:in `column_names'
<gems_path>/activerecord-4.2.11.1/lib/active_record/attributes.rb:93:in `columns'
<gems_path>/activerecord-4.2.11.1/lib/active_record/connection_adapters/schema_cache.rb:43:in `columns'
<gems_path>/activerecord-4.2.11.1/lib/active_record/connection_adapters/abstract_mysql_adapter.rb:471:in `columns'
<gems_path>/activerecord-4.2.11.1/lib/active_record/connection_adapters/abstract_mysql_adapter.rb:324:in `execute_and_free'
<gems_path>/activerecord-4.2.11.1/lib/active_record/connection_adapters/abstract_mysql_adapter.rb:472:in `block in columns'
<gems_path>/activerecord-4.2.11.1/lib/active_record/connection_adapters/abstract_mysql_adapter.rb:472:in `map'
<gems_path>/activerecord-4.2.11.1/lib/active_record/connection_adapters/abstract_mysql_adapter.rb:472:in `each'
<gems_path>/activerecord-4.2.11.1/lib/active_record/connection_adapters/mysql2_adapter.rb:57:in `each_hash'
<gems_path>/activerecord-4.2.11.1/lib/active_record/connection_adapters/mysql2_adapter.rb:57:in `each'

-- Machine register context ------------------------------------------------
 RIP: 0x00007f4377f83f20 RBP: 0x0000000000000ba9 RSP: 0x00007fffc3818e28
 RAX: 0x0000000000000000 RBX: 0x0000563ebd500a18 RCX: 0x00007f437161a580
 RDX: 0x00007f43782e1310 RDI: 0x0000000000000ba9 RSI: 0x0000000000000ba9
  R8: 0x00007f437832d010  R9: 0x0000563eba9885a0 R10: 0x0000000000000030
 R11: 0x00007f4377e73540 R12: 0x0000000000000ba9 R13: 0xffffffffffffffff
 R14: 0x0000563eba98f770 R15: 0x0000000000000000 EFL: 0x0000000000010206

-- C level backtrace information -------------------------------------------
<ruby_path>/lib/libruby.so.2.4(rb_vm_bugreport+0x769) [0x7f43780075c9]
<ruby_path>/lib/libruby.so.2.4(rb_bug_context+0xd4) [0x7f4377e86a94]
<ruby_path>/lib/libruby.so.2.4(sigsegv+0x3e) [0x7f4377f7b1ae]
[0x7f4377a31f20]
[0x7f4377f83f20]
<ruby_path>/lib/libruby.so.2.4(st_lookup+0x2c) [0x7f4377f8478c]
<ruby_path>/lib/libruby.so.2.4(rb_enc_find_index+0x3b) [0x7f4377e7357b]
[0x7f4371414a21]
[0x7f4371413a0f]
<ruby_path>/lib/libruby.so.2.4(vm_call_cfunc+0xde) [0x7f4377fea83e]
<ruby_path>/lib/libruby.so.2.4(vm_call_method+0xd3) [0x7f4377ffac43]
<ruby_path>/lib/libruby.so.2.4(vm_exec_core+0x5d8) [0x7f4377ff28f8]
<ruby_path>/lib/libruby.so.2.4(vm_exec+0x7c) [0x7f4377ff8f0c]
<ruby_path>/lib/libruby.so.2.4(rb_call0+0xb8) [0x7f4377ffe2f8]
<ruby_path>/lib/libruby.so.2.4(rb_iterate0+0xb6) [0x7f4377fece56]
<ruby_path>/lib/libruby.so.2.4(rb_block_call+0x3c) [0x7f4377fed00c]
<ruby_path>/lib/libruby.so.2.4(vm_call0_body.constprop.152+0x290) [0x7f4377ffdc30]
<ruby_path>/lib/libruby.so.2.4(rb_call0+0xb8) [0x7f4377ffe2f8]
<ruby_path>/lib/libruby.so.2.4(rb_iterate0+0xb6) [0x7f4377fece56]
<ruby_path>/lib/libruby.so.2.4(rb_lambda_call+0x59) [0x7f4377fed0c9]
<ruby_path>/lib/libruby.so.2.4(enum_collect+0x45) [0x7f4377e78a75]
<ruby_path>/lib/libruby.so.2.4(vm_call_cfunc+0xde) [0x7f4377fea83e]
<ruby_path>/lib/libruby.so.2.4(vm_call_method+0xd3) [0x7f4377ffac43]
<ruby_path>/lib/libruby.so.2.4(vm_exec_core+0x5d8) [0x7f4377ff28f8]
<ruby_path>/lib/libruby.so.2.4(vm_exec+0x7c) [0x7f4377ff8f0c]
<ruby_path>/lib/libruby.so.2.4(eval_string_with_cref+0x1d1) [0x7f4377ffcd31]
<ruby_path>/lib/libruby.so.2.4(rb_f_eval+0xde) [0x7f4377ffd29e]
<ruby_path>/lib/libruby.so.2.4(vm_call_cfunc+0xde) [0x7f4377fea83e]
<ruby_path>/lib/libruby.so.2.4(vm_call_method+0xd3) [0x7f4377ffac43]
<ruby_path>/lib/libruby.so.2.4(vm_exec_core+0x449) [0x7f4377ff2769]
<ruby_path>/lib/libruby.so.2.4(vm_exec+0x7c) [0x7f4377ff8f0c]
<ruby_path>/lib/libruby.so.2.4(rb_load_internal0+0xab) [0x7f4377ed21ab]
<ruby_path>/lib/libruby.so.2.4(rb_require_internal+0x848) [0x7f4377ed4948]
<ruby_path>/lib/libruby.so.2.4(rb_require_safe+0x9) [0x7f4377ed4a49]
<ruby_path>/lib/libruby.so.2.4(vm_call_cfunc+0xde) [0x7f4377fea83e]
<ruby_path>/lib/libruby.so.2.4(vm_call_method+0xd3) [0x7f4377ffac43]
<ruby_path>/lib/libruby.so.2.4(vm_exec_core+0x449) [0x7f4377ff2769]
<ruby_path>/lib/libruby.so.2.4(vm_exec+0x7c) [0x7f4377ff8f0c]
<ruby_path>/lib/libruby.so.2.4(rb_load_internal0+0xab) [0x7f4377ed21ab]
<ruby_path>/lib/libruby.so.2.4(rb_require_internal+0x848) [0x7f4377ed4948]
<ruby_path>/lib/libruby.so.2.4(rb_require_safe+0x9) [0x7f4377ed4a49]
<ruby_path>/lib/libruby.so.2.4(vm_call_cfunc+0xde) [0x7f4377fea83e]
<ruby_path>/lib/libruby.so.2.4(vm_call_method+0xd3) [0x7f4377ffac43]
<ruby_path>/lib/libruby.so.2.4(vm_exec_core+0x449) [0x7f4377ff2769]
<ruby_path>/lib/libruby.so.2.4(vm_exec+0x7c) [0x7f4377ff8f0c]
<ruby_path>/lib/libruby.so.2.4(ruby_exec_internal+0xad) [0x7f4377e8cc2d]
<ruby_path>/lib/libruby.so.2.4(ruby_exec_node+0x1d) [0x7f4377e8eacd]
<ruby_path>/lib/libruby.so.2.4(ruby_run_node+0x1e) [0x7f4377e9183e]
<ruby_path>/bin/ruby(main+0x4b) [0x563eb9f4f8eb] main.c:36

-- Other runtime information -----------------------------------------------

[...]
@sodabrew
Copy link
Collaborator

Yes, this is correct. There's no release of mysql2 0.4.x that supports the new MySQL 8 encodings.

Is the bug report is that a version of mysql2 older than the current release causes crashes, but the current release does not?

... there's been a few people asking for a new release of the 0.4.x branch. Gaaaah agh, time and effort, etc.

@sodabrew sodabrew added this to the 0.4.11 milestone Aug 29, 2019
@64kramsystem
Copy link
Author

Is the bug report is that a version of mysql2 older than the current release causes crashes, but the current release does not?

If I understand correctly, yes: mysql2 v0.5.2 (at least when paired with Rails 5.0.7) does not cause the segfault.

@krisleech
Copy link

Firstly, thanks for the great work maintaining the mysql2 gem.

I ran in to this today after upgrading Ubuntu. The README seems to suggest that mysql2 version 0.4 works with MySQL 8.x.

The solution for me was simple:

-gem 'mysql2', '< 0.5' # [1]
+gem 'mysql2', '~>0.5.0' # [1]

(I have mysql2 pinned because ActiveRecord needs a specific version)

  • Ubuntu 19.10
  • MySQL 8.0.17
  • mysql2 0.4.x segfaults
  • mysql2 0.5.x works
  • Rails 5.2.3

@krisleech
Copy link

Setting the collation might be of help to those using Rails and MySQL 8.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants