我正在用C語言將用Ruby編寫的Ruby gem移植到帶有FFI的Ruby中。在jRuby但不是MRI中的FFI代碼段錯誤Ruby
當我使用MRI Ruby運行測試時,沒有任何seg-fault。 在jRuby中運行時,出現seg-fault錯誤。
這是在測試我覺得代碼負責:運行sqlany_execute的時候,但只有當傳遞給SET_VALUE的對象是String類的
if type == Date or type == DateTime then
assert_nil param.set_value(value.strftime("%F %T"));
else
assert_nil param.set_value(value);
end
@api.sqlany_bind_param(stmt, 0, param)
puts "\n#{param.inspect}"
#return if String === value or Date === value or DateTime === value
assert_succeeded @api.sqlany_execute(stmt)
分割發生故障。
sqlany_execute只是使用FFI的attach_function方法。
param.set_value更復雜。我將專注於字符串特定部分。這裏是原來的C代碼
case T_STRING:
s_bind->value.length = malloc(sizeof(size_t));
length = RSTRING_LEN(val);
*s_bind->value.length = length;
s_bind->value.buffer = malloc(length);
memcpy(s_bind->value.buffer, RSTRING_PTR(val), length);
s_bind->value.type = A_STRING;
break;
在我的口,這成爲:
when String
self[:value][:length] = SQLAnywhere::LibC.malloc(FFI::Type::ULONG.size)
length = value.bytesize
self[:value][:length].write_int(length)
self[:value][:buffer] = SQLAnywhere::LibC.malloc(length + 1)
self[:value][:buffer_size] = length + 1
## Don't use put_string as that includes the terminating null
# value.each_byte.each_with_index do |byte, index|
# self[:value][:buffer].put_uchar(index, byte)
# end
self[:value][:buffer].put_string(0, value)
self[:value][:type] = :string
我的問題是:是什麼引起的JRuby賽格故障和什麼都可以我做了嗎?
什麼版本的JRuby? JRuby master是否發生這種情況?有可能這是一個JRuby FFI錯誤,可能已經修復。 –
$ ruby -v jruby 1.7.1(1.9.3p327)2012-12-03 30a153b上OpenJDK 64位服務器虛擬機1.7.0_09-icedtea-mockbuild_2012_12_06_11_04-b00 [linux-amd64] 我會嘗試升級到jRuby 1.7.2 – Chris
@SébastienLeCallonnec我已經更新到jRuby-1.7.2和我的ffi到ffi-1.3.1-java.gem。當使用jRuby-1.7.2時,測試仍然會出現seg錯誤 – Chris