Ruby 1.8.7:在C扩展中调用函数的Segfault

时间:2011-04-05 14:43:19

标签: c ruby debugging ruby-c-extension

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

  1. 我创建了一个Ruby类并在其上调用了一个实例方法,
  2. 在我的扩展程序中调用C方法,
  3. 在单独的文件中调用另一个C函数,但编译好了
  4. 这是最后一次似乎打破的跳跃。我已经能够重现这个问题几乎没有任何功能,但函数调用。我有一个标准extconf.rb,用直接Make编译它,并且在调用encrypt()时会出现段错误。在运行时,我发出以下命令:

    $ ruby extconf.rb
    $ make clean
    $ make
    $ ruby -r des -e 'puts DES.new.encrypt!'

    输出:

    creating 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
    About to do C encrypt...
    ./des.rb:42: [BUG] Segmentation fault
    ruby 1.8.7 (2011-02-18 patchlevel 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

    Calc模块:

    #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 --versioni686-apple-darwin10-gcc-4.2.1 (GCC) 4.2.1 (Apple Inc. build 5666) (dot 3)

1 个答案:

答案 0 :(得分:0)

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