Расширение Ruby C - 64-битный указатель усекается, вызывая ошибку - PullRequest
2 голосов
/ 01 сентября 2011

Я пытаюсь получить расширение ruby, написанное на c, и работаю с ruby ​​1.9.2 на Mac OSX. Я продолжаю получать ошибку, вызванную 64-битным указателем, возвращаемым функцией, усеченной до 32-битного значения и пытающейся получить доступ к нехватке памяти.

Вот что я понял по этому поводу. VALUE - это long, определенный в исходном коде ruby, и код не будет компилироваться, если sizeof (long) не равен 8 байтам.

В file_b.c:

VALUE
rb_helper_function_foo(VALUE file)
{
  VALUE blah;

  ...

  //Using gdb, blah right here is a 64bit address, ex: 0x1 009d 62a0
  return blah;
}

In file_a.c

VALUE
func_do_stuff(int argc, VALUE *argv, VALUE obj)
{
  VALUE filename, file_path;

  ...

  // But here, the size of what is returned is 4 bytes
  // file_path has a size of 8 bytes though
  file_path = rb_helper_function_foo(filename);

  //This statement will segfault :-(
  if(!RTEST(file_path))
  {
    ...
  }
  ...
}

В конце вызова функции возвращаемое значение имеет правильный адрес, но возвращаются только младшие 4 байта: 0x009d52a0 вместо 0x1009d52a0. Доступ к низкому адресу памяти вызывает сбой.

В коде сборки, который вызывается во время возврата, есть эта инструкция

movslq %eax, %r12

, который копирует только младшие 4 байта, но мне нужно скопировать все 8 байтов% rax.

Я на ruby ​​1.9.2-p290 (хотя он сделал то же самое с p180), Mac OSX 10.6.8, использую xcode 4.0.1 (с gcc 4.2.1), но я также попытался перейти на gcc 4.6 0,1. Он также ранее пробовал xcode 3.2.

Спасибо за любую помощь, которую вы можете оказать мне.

1 Ответ

3 голосов
/ 01 сентября 2011

Может быть, это так просто, как rb_helper_function_foo не объявлено в модуле компиляции file_a.c - поэтому компилятор предполагает, что он возвращает int вместо VALUE?

...