【问题标题】:How to fix a segmentation fault with Ruby 2.0.0p645如何使用 Ruby 2.0.0p645 修复分段错误
【发布时间】:2016-04-07 02:41:17
【问题描述】:

当我在 Sinatra/Ruby 应用程序中解析联盟提要时,出现错误:

/opt/rh/ruby200/root/usr/share/ruby/net/http/response.rb:368: [BUG]
Segmentation fault ruby 2.0.0p645 (2015-04-13) [x86_64-linux]

我想知道这是 Ruby 的错误还是代码有问题,如果是,我可以做些什么来修复它?

Link to the error

这是解析联盟提要的代码:

        feeds.each { |name, hash|
            puts "=== PARSING #{name.upcase} FEED ==="
            start = Time.now
            open(hash[:url]) { |feed|
                send(hash[:action], feed)
            }
            duration = Time.now - start
            puts "Feed syndication completed in #{duration.to_s} seconds."
            puts
        }

        # Close DB connection
        puts "Disconnecting"
        @db.disconnect
    end

    def parseAllianceData(xml)
        start = Time.now
        allianceData = XMLObject.new xml
        duration = Time.now - start

        puts "XML parsed in #{duration.to_s} seconds."
        puts "Alliances found: #{allianceData.alliances.count}"

        @db[:feeds].insert(
            :generated_at => allianceData.server.datagenerationdatetime,
            :type => "Alliance",
            :is_current => true)

        start = Time.now
        allianceData.alliances.each { |alliance|
            capital_last_moved_at = (alliance.alliancecapitallastmoved rescue nil)
            taxrate_last_changed_at = (alliance.alliancetaxratelastchanged rescue nil)
            @db[:alliance].insert(
                :id => alliance.alliance[:id],
                :ticker => alliance.allianceticker,
                :name => alliance.alliance,
                :founded_at => alliance.foundeddatetime,
                :founded_by_player_id => alliance.foundedbyplayerid[:id],
                :capital_town_id => alliance.alliancecapitaltownid[:id],
                :member_count => alliance.membercount,
                :total_population => (alliance.totalpopulation rescue 0),
                :tax_rate => (alliance.alliancetaxrate.to_i) / 100.0,
                :tax_rate_last_changed_at => taxrate_last_changed_at,
                :capital_town_last_moved_at => capital_last_moved_at)

            alliance.roles.each { |role|
                @db[:alliance_roles].insert(
                    :id => role.role[:id],
                    :name => role.role,
                    :alliance_id => alliance.alliance[:id],
                    :hierarchy_id => role.heirarchy[:id])
            }
        }
        duration = Time.now - start
        puts "Database populated in #{duration.to_s} seconds."

【问题讨论】:

  • 尝试使用 Ruby 2.2.5 看看是否可行。
  • 很遗憾我不能这样做,因为我正在使用 s 服务器 (openshift) 运行代码,因为我在计算机上安装 gem 时遇到了许多问题
  • 忘记在帖子中添加。在它执行 PARSING ALLIANCE FEED 之前,它会执行 PARSING PLAYERS FEED,它工作正常 === PARSING PLAYERS FEED === XML 在 2.067214038 秒内解析。玩家发现:5968 数据库在 213.937264445 秒内填充。 Feed 联合在 216.276557037 秒内完成。
  • 这通常是一个安装问题(例如,针对一个版本的库进行编译,然后加载另一个版本)
  • 我能够很好地让 ruby​​ 在我的笔记本电脑上工作,我现在正在使用最新的 ruby​​,它似乎没有问题

标签: ruby-on-rails ruby sinatra


【解决方案1】:

我在您的示例中发现了一行危险的代码:

send(hash[:action], feed)

它从外部源 (hash[:action]) 获取一些字符串并将其转换为方法调用。这是非常危险的,因为你永远不知道你会得到什么字符串。那里可能有一个字符串不能被做成一个方法调用,所以 Ruby 崩溃了。

我建议检查所有支持的操作并明确调用方法。例如,您可以使用 case 语句来实现。

action = hash[:action]

case action
when 'action1'
  call_method1
when 'action2'
  call_method2
else
  puts "unsupported action: #{action}"
end

【讨论】:

    猜你喜欢
    • 2012-09-04
    • 1970-01-01
    • 2015-07-12
    • 2022-11-21
    • 2017-06-04
    • 1970-01-01
    • 1970-01-01
    • 2021-07-18
    相关资源
    最近更新 更多