【问题标题】:Ruby 1.8.7: Segfault on calling function inside C extensionRuby 1.8.7:在 C 扩展中调用函数的 Segfault
【发布时间】:2011-07-30 01:15:07
【问题描述】:

我正在为 Ruby 模块构建一个简单的 C 扩展,当我在扩展中调用另一个 C 函数时遇到了段错误。执行的基本流程是这样的:

  1. 我创建了一个 Ruby 类并在其上调用了一个实例方法,
  2. 在我的扩展中调用一个 C 方法,
  3. 在单独的文件中调用另一个 C 函数,但编译成功

这似乎是最后一次跳跃。我已经能够在几乎没有任何功能但函数调用的情况下重现该问题。我有一个标准的extconf.rb,用直接 Make 编译这个东西,它在调用encrypt() 时会出现段错误。在运行时,我发出以下命令:

$ ruby​​ extconf.rb
$ 清理
$ 制作
$ ruby​​ -r des -e '放置 DES.new.encrypt!'

输出:

创建 Makefile
/usr/bin/gcc-4.2 -I。 -I/opt/local/lib/ruby/1.8/i686-darwin10 -I/opt/local/lib/ruby/1.8/i686-darwin10 -I. -I/opt/local/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -fno-common -std=c99 -arch x86_64 -c calc.c
/usr/bin/gcc-4.2 -I。 -I/opt/local/lib/ruby/1.8/i686-darwin10 -I/opt/local/lib/ruby/1.8/i686-darwin10 -I. -I/opt/local/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -fno-common -std=c99 -arch x86_64 -c deslib.c
/usr/bin/gcc-4.2 -dynamic -bundle -undefined suppress -flat_namespace -o calc.bundle calc.o deslib.o -L。 -L/opt/local/lib -L/opt/local/lib -L. -L/opt/local/lib -arch x86_64 -arch x86_64 -lruby -lpthread -ldl -lobjc
即将做C加密...
./des.rb:42: [BUG] 分段错误
ruby 1.8.7 (2011-02-18 补丁级别 334) [i686-darwin10]

zsh: abort ruby​​ -r des -e 'puts DES.new.encrypt!'

Ruby 类:

class D
    def encrypt!
        self.encrypted = Calc.encrypt(0,0,0)
        return self.encrypted
    end
end

计算模块:

#include "ruby.h"
#include "cryptlib.h"

VALUE Calc = Qnil;
void Init_calc();

VALUE method_encrypt(VALUE self, VALUE m, VALUE k, VALUE n);

void Init_calc() {
    Calc = rb_define_module("Calc");
    rb_define_method(Calc, "encrypt", method_encrypt, 3);
}

VALUE method_encrypt(VALUE self, VALUE m, VALUE k, VALUE n) {
    uint64_t message = NUM2ULONG(m);
    uint64_t key = NUM2ULONG(k);
    int iters = NUM2INT(n);

    printf("About to do C encrypt...\n");
    uint64_t ciphertext = encrypt(message, key, iters);
    printf("Done with C encrypt\n");

    return ULONG2NUM(ciphertext);
}

cryptlib.h:

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>

uint64_t encrypt(uint64_t message, uint64_t key, int iters);

cryptlib.c:

#include "cryptlib.h"

uint64_t encrypt(uint64_t message, uint64_t key, int iters) {
    return 0;
}

为什么会出现这么严重的问题?我在不到一小时前从 MacPorts 编译的 MacBook Pro 上运行 ruby 1.8.7 (2011-02-18 patchlevel 334) [i686-darwin10]。我的gcc --version: i686-apple-darwin10-gcc-4.2.1 (GCC) 4.2.1 (Apple Inc. build 5666) (dot 3)

【问题讨论】:

    标签: c ruby debugging ruby-c-extension


    【解决方案1】:

    事实证明,encrypt 函数名称保留在 Ruby C 扩展库的更高位置。重命名函数,一切正常。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-04-28
      • 1970-01-01
      • 1970-01-01
      • 2014-04-18
      • 1970-01-01
      • 2013-06-27
      • 1970-01-01
      相关资源
      最近更新 更多