rails:3369
From: eiichi_maekawa@m...
Date: Tue, 26 Jan 2010 10:47:18 +0900
Subject: [rails:3369] MySQLにDBIでアクセスすると、Segmentation faultが発生
前川です。 rubyメーリングにも投稿しましたが、反応がありませんでした。 mysqlのデータをdbiを使用して取得したいのですが、 ("SELECT * FROM aplist")を実行すると、Segmentation faultが発生します。 ググってみたら、 http://rubyforge.org/tracker/index.php?func=detail&aid=26791&group_id=234&atid=967 に、同様のレポートがありましたが、解決していないのでしょうか? どなたか、ご存知でしたら、ご教示ください。 パソコンの設定で、発生したり、しなかったりする?? テーブル名(show tables)、db名("show databases")の取得は、 問題なく実行できます。 よろしくお願いします。 バージョンは、以下です。 C:\>ruby -v ruby 1.8.7 (2010-01-10 patchlevel 249) [i386-mswin32] MySQL;;5.1 C:\>gem list --local *** LOCAL GEMS *** actionmailer (2.3.4) actionpack (2.3.4) activerecord (2.3.4) activeresource (2.3.4) activesupport (2.3.4) deprecated (2.0.1) linecache (0.43) mysql (2.8.1) rack (1.0.0) rails (2.3.4) rake (0.8.7) ruby-debug-base (0.10.3) ruby-debug-ide (0.4.5) sinatra (0.9.4) sqlite3-ruby (1.2.5) ソースコード #!D:/Ruby/bin/ruby.exe -Ks require "dbi" begin #dbh = DBI.connect('DBI:Mysql:fbsys:a28341', 'dbuser01', 'dbkey') dbh = DBI.connect("DBI:Mysql:fbsys:localhost", "root", "dbkey") #sth = dbh.prepare("SHOW TABLES") #←OK sth = dbh.prepare("SELECT * FROM aplist") #sth = dbh.prepare("SHOW COLUMNS FROM aplist") #sth = dbh.prepare('DESCRIBE aplist') #sth = dbh.prepare("show databases") #OK puts dbh puts sth sth.execute puts 'count='+sth.rows.to_s #テーブル数のみ有効? count = 0 sth.fetch { |row| p row count = count + 1 } sth.finish puts 'increment count='+count.to_s #DB例外発生時の処理 rescue DBI::DatabaseError => e p "An error occurred" p "Error code: #{e.err}" p "Error message: #{e.errstr}" #切断漏れしないようにensureでdisconnectします。 ensure dbh.disconnect if dbh end デバッガでの実行結果 すべて、step (s) で実行しました。 #以下、デバッガでの実施結果 162行ほどあります。冗長とは思いましたが、 #すべて、貼り付けました。 D:\Apache2.2\htdocs\ruby_prg\em_ruby\em_db>ruby -r debug dbi_mysql_connect.rb Debug.rb Emacs support available. dbi_mysql_connect.rb:3:require "dbi" (rdb:1) l [-2, 7] in dbi_mysql_connect.rb 1 2 => 3 require "dbi" 4 5 begin 6 #dbh = DBI.connect('DBI:Mysql:fbsys:a28341', 'dbuser01', 'dbkey') 7 dbh = DBI.connect("DBI:Mysql:fbsys:localhost", "root", "dbkey") (rdb:1) b 15 Set breakpoint 1 at dbi_mysql_connect.rb:15 (rdb:1) b Breakpoints: 1 dbi_mysql_connect.rb:15 (rdb:1) l [8, 17] in dbi_mysql_connect.rb 8 #sth = dbh.prepare("SHOW TABLES") #←OK 9 sth = dbh.prepare("SELECT * FROM aplist") 10 #sth = dbh.prepare("SHOW COLUMNS FROM aplist") 11 #sth = dbh.prepare('DESCRIBE aplist') 12 #sth = dbh.prepare("show databases") #OK 13 puts dbh 14 puts sth 15 sth.execute 16 puts 'count='+sth.rows.to_s #テーブル数のみ有効? 17 (rdb:1) c D:/Ruby/lib/ruby/1.8/rational.rb:78: `undefined method `gcd' for Rational(1, 2):Rational' (NoMethodError) from D:/Ruby/lib/ruby/site_ruby/1.8/dbi.rb:39:in `require' from D:/Ruby/lib/ruby/site_ruby/1.8/dbi.rb:39 from dbi_mysql_connect.rb:3:in `require' from dbi_mysql_connect.rb:3 D:/Ruby/lib/ruby/1.8/rational.rb:78: gcd = num.gcd(den) (rdb:1) w --> #1 D:/Ruby/lib/ruby/1.8/rational.rb:78:in `reduce' #2 D:/Ruby/lib/ruby/1.8/rational.rb:35:in `Rational' #3 D:/Ruby/lib/ruby/1.8/date.rb:517 #4 D:/Ruby/lib/ruby/1.8/date.rb:230 (rdb:1) c #<DBI::DatabaseHandle:0x3b2ea14> #<DBI::StatementHandle:0x3b2a450> Breakpoint 1, toplevel at dbi_mysql_connect.rb:15 dbi_mysql_connect.rb:15: sth.execute (rdb:1) w --> #1 dbi_mysql_connect.rb:15 (rdb:1) s D:/Ruby/lib/ruby/site_ruby/1.8/dbi/handles/statement.rb:108: cancel # cancel before (rdb:1) s D:/Ruby/lib/ruby/site_ruby/1.8/dbi/handles/statement.rb:147: sanity_check (rdb:1) s D:/Ruby/lib/ruby/site_ruby/1.8/dbi/handles/statement.rb:372: raise InterfaceError, "Statement was already closed!" if @ handle.nil? (rdb:1) s D:/Ruby/lib/ruby/site_ruby/1.8/dbi/handles/statement.rb:372: raise InterfaceError, "Statement was already closed!" if @ handle.nil? (rdb:1) s D:/Ruby/lib/ruby/site_ruby/1.8/dbi/handles/statement.rb:374: params.each_key do |key| (rdb:1) s D:/Ruby/lib/ruby/site_ruby/1.8/dbi/handles/statement.rb:148: @handle.cancel if @fetchable (rdb:1) s D:/Ruby/lib/ruby/site_ruby/1.8/dbi/handles/statement.rb:148: @handle.cancel if @fetchable (rdb:1) s D:/Ruby/lib/ruby/site_ruby/1.8/dbi/handles/statement.rb:149: @fetchable = false (rdb:1) s D:/Ruby/lib/ruby/site_ruby/1.8/dbi/handles/statement.rb:109: sanity_check({:prepared => true }) (rdb:1) s D:/Ruby/lib/ruby/site_ruby/1.8/dbi/handles/statement.rb:372: raise InterfaceError, "Statement was already closed!" if @ handle.nil? (rdb:1) s D:/Ruby/lib/ruby/site_ruby/1.8/dbi/handles/statement.rb:372: raise InterfaceError, "Statement was already closed!" if @ handle.nil? (rdb:1) s D:/Ruby/lib/ruby/site_ruby/1.8/dbi/handles/statement.rb:374: params.each_key do |key| (rdb:1) s D:/Ruby/lib/ruby/site_ruby/1.8/dbi/handles/statement.rb:375: case key (rdb:1) s D:/Ruby/lib/ruby/site_ruby/1.8/dbi/handles/statement.rb:376: when :fetchable (rdb:1) s D:/Ruby/lib/ruby/site_ruby/1.8/dbi/handles/statement.rb:378: when :executed (rdb:1) s D:/Ruby/lib/ruby/site_ruby/1.8/dbi/handles/statement.rb:380: when :prepared (rdb:1) s D:/Ruby/lib/ruby/site_ruby/1.8/dbi/handles/statement.rb:381: check_prepared (rdb:1) s D:/Ruby/lib/ruby/site_ruby/1.8/dbi/handles/statement.rb:389: raise InterfaceError, "Statement wasn't prepared before." unless @prepared (rdb:1) s D:/Ruby/lib/ruby/site_ruby/1.8/dbi/handles/statement.rb:389: raise InterfaceError, "Statement wasn't prepared before." unless @prepared (rdb:1) s D:/Ruby/lib/ruby/site_ruby/1.8/dbi/handles/statement.rb:111: if @convert_types (rdb:1) s D:/Ruby/lib/ruby/site_ruby/1.8/dbi/handles/statement.rb:111: if @convert_types (rdb:1) s D:/Ruby/lib/ruby/site_ruby/1.8/dbi/handles/statement.rb:112: bindvars = DBI::Utils::ConvParam.conv_param (dbh.driver _name, *bindvars) (rdb:1) s D:/Ruby/lib/ruby/site_ruby/1.8/dbi/handles/database.rb:18: return @driver_name.dup if @driver_name (rdb:1) s D:/Ruby/lib/ruby/site_ruby/1.8/dbi/handles/database.rb:18: return @driver_name.dup if @driver_name (rdb:1) s D:/Ruby/lib/ruby/site_ruby/1.8/dbi/utils.rb:52: params.collect { |param| DBI::TypeUtil.convert(driver_name, param) } (rdb:1) s D:/Ruby/lib/ruby/site_ruby/1.8/dbi/handles/statement.rb:115: @handle.bind_params(*bindvars) (rdb:1) s D:/Ruby/lib/ruby/site_ruby/1.8/dbi/base_classes/statement.rb:75: bindvars.each_with_index {|val,i| bind_param (i+1, val, nil) } (rdb:1) s D:/Ruby/lib/ruby/site_ruby/1.8/dbi/base_classes/statement.rb:76: self (rdb:1) s D:/Ruby/lib/ruby/site_ruby/1.8/dbi/handles/statement.rb:116: @handle.execute (rdb:1) s D:/Ruby/lib/ruby/site_ruby/1.8/dbd/mysql/statement.rb:33: sql = @prep_stmt.bind(@params) (rdb:1) s D:/Ruby/lib/ruby/site_ruby/1.8/dbi/sql/preparedstatement.rb:63: if @arg_index < args.size (rdb:1) s D:/Ruby/lib/ruby/site_ruby/1.8/dbi/sql/preparedstatement.rb:63: if @arg_index < args.size (rdb:1) s D:/Ruby/lib/ruby/site_ruby/1.8/dbi/sql/preparedstatement.rb:65: elsif @arg_index > args.size (rdb:1) s D:/Ruby/lib/ruby/site_ruby/1.8/dbi/sql/preparedstatement.rb:69: @unbound.each do |res_pos, arg_pos| (rdb:1) s D:/Ruby/lib/ruby/site_ruby/1.8/dbi/sql/preparedstatement.rb:73: @result.join("") (rdb:1) s D:/Ruby/lib/ruby/site_ruby/1.8/dbd/mysql/statement.rb:34: @mutex.synchronize { (rdb:1) s D:/Ruby/lib/ruby/site_ruby/1.8/dbd/mysql/statement.rb:35: @handle.query_with_result = true (rdb:1) s D:/Ruby/lib/ruby/site_ruby/1.8/dbd/mysql/statement.rb:36: @res_handle = @handle.query(sql) (rdb:1) s D:/Ruby/lib/ruby/site_ruby/1.8/dbd/mysql/statement.rb:37: @column_info = self.column_info (rdb:1) s D:/Ruby/lib/ruby/site_ruby/1.8/dbd/mysql/statement.rb:119: retval = [] (rdb:1) s D:/Ruby/lib/ruby/site_ruby/1.8/dbd/mysql/statement.rb:121: return [] if @res_handle.nil? (rdb:1) s D:/Ruby/lib/ruby/site_ruby/1.8/dbd/mysql/statement.rb:121: return [] if @res_handle.nil? (rdb:1) s D:/Ruby/lib/ruby/site_ruby/1.8/dbd/mysql/statement.rb:123: unique_key_flag = MysqlField.const_get (:UNIQUE_KEY_FLAG) (rdb:1) s D:/Ruby/lib/ruby/site_ruby/1.8/dbd/mysql/statement.rb:124: multiple_key_flag = MysqlField.const_get (:MULTIPLE_KEY_FLAG) (rdb:1) s D:/Ruby/lib/ruby/site_ruby/1.8/dbd/mysql/statement.rb:125: indexed = (unique_key_flag | multiple_key_flag) (rdb:1) s D:/Ruby/lib/ruby/site_ruby/1.8/dbd/mysql/statement.rb:125: indexed = (unique_key_flag | multiple_key_flag) (rdb:1) s D:/Ruby/lib/ruby/site_ruby/1.8/dbd/mysql/statement.rb:130: @res_handle.fetch_fields.each {|col| (rdb:1) s D:/Ruby/lib/ruby/site_ruby/1.8/dbd/mysql/statement.rb:130: [BUG] Segmentation fault ruby 1.8.7 (2010-01-10 patchlevel 249) [i386-mswin32] This application has requested the Runtime to terminate it in an unusual way. Please contact the application's support team for more information. D:\Apache2.2\htdocs\ruby_prg\em_ruby\em_db> statement.rb:130:の@res_handle.fetch_fields.each {|col|で、 Segmentation Faultが生じています。 どうすれば解決できるか、ご指導のほど、お願いします。 別の手法(とみたさんのmysqlを使用した場合)のサンプルコードでは、 問題なく、データが取れています。 #!D:/Ruby/bin/ruby.exe # #MySQLへのアクセスサンプルプログラム # 2009/05/19 CODED BY E.MAEKAWA # # ################################################ require "mysql" #MySQLライブラリ require "rubygems" mydb = Mysql.new('サーバ名','ユーザ名','パスワード','DB名') puts 'mydbの結果は'+ mydb.to_s #接続確認 res = mydb.query('SELECT * from aplist') puts 'mydb.queryの結果は'+ res.to_s #結果確認 puts '【データダンプ】' res.each do |row| #puts row[0].to_s puts row.to_s puts row.length end #テーブル名 取得 res = mydb.list_tables() #テーブル名を返す puts res.length #テーブル名の数(返されたデータ数) puts res #list_tablesの結果(テーブル名 arcd 等) puts '【each doの出力】' res.each do |name| #テーブル名の格納 res→nemeへ puts name end puts '【flattenの出力】' resData = res.flatten #res を一次元の配列にする。 puts resData puts 'テーブルの数' puts resData.length # 一次元配列になったデータの数 puts 'テーブル名一覧' puts res.to_s #=begin res.each do |row| #puts row[0].to_s puts row.to_s puts row.length end 了 冗長ではありますが、ご指導のほど、よろしくお願いします。 -- ML: rails@r... 使い方: http://QuickML.com/
-> 3369 2010-01-26 02:47 [eiichi_maekawa@m... ] MySQLにDBIでアクセスすると、Segmentation faultが発生 3370 2010-01-26 03:19 ┗[eiichi_maekawa@m... ] 解決しました;; MySQLにDBIでアクセスすると、Segmentation faultが発生