3

Rubyモジュール用の単純なC拡張機能を構築していますが、拡張機能内で別のC関数を呼び出すと、セグメンテーション違反で問題が発生します。実行の基本的なフローは次のようになります。

  1. Rubyクラスを作成し、そのクラスでインスタンスメソッドを呼び出します。
  2. 私の拡張機能でCメソッドを呼び出します。
  3. 別のファイルで別のC関数を呼び出しますが、コンパイルはOKです

壊れそうな最後のジャンプです。関数呼び出し以外の機能はほとんどなく、問題を再現することができました。私は標準を持っていて、extconf.rbまっすぐなMakeでコンパイルすると、への呼び出しでsegfaultされencrypt()ます。実行時に、次のコマンドを発行します。

$ ruby​​ extconf.rb
$きれいにする
$ make
$ 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 Supplement -flat_namespace -o calc.bundle calc.odeslib.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]セグメンテーション違反
ルビー1.8.7(2011-02-18パッチレベル334)[i686-darwin10]

zsh:ruby -r des -eを中止します'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;
}

なぜこれがひどく壊れているのですか?ruby 1.8.7 (2011-02-18 patchlevel 334) [i686-darwin10]1時間以内にMacPortsからコンパイルされたMacBookProで実行しています。私のgcc --versioni686-apple-darwin10-gcc-4.2.1 (GCC) 4.2.1 (Apple Inc. build 5666) (dot 3)

4

1 に答える 1

0

encrypt関数名はRubyC拡張ライブラリの上位のどこかに予約されていることがわかりました。関数の名前を変更すると、すべてが機能します。

于 2011-04-05T15:14:54.793 に答える