Вызов ruby_init и ruby_finalize несколько раз - PullRequest
0 голосов
/ 24 сентября 2018

В настоящее время я пытаюсь протестировать некоторые API Ruby (2.3) C с помощью google test.

Но мои тесты дают сбой, потому что я создал прибор, вызывающий ruby_init при настройке и ruby_finalizeна разрыве.

Затем я создал «синглтон» внутри прибора, который решает проблему, но я хотел бы знать, есть ли другой, более простой, способ сделать это.

Я бы хотел, чтобы все мои тесты выполнялись на правильной / чистой виртуальной машине.

Ниже приведен простой пример, который воспроизводит ошибку:

#include <ruby.h>

int
main()
{
  ruby_init();
  ruby_finalize();

  ruby_init();
  ruby_finalize();
}

Ошибка:

Program terminated with signal SIGABRT, Aborted.
#0  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51
51  ../sysdeps/unix/sysv/linux/raise.c: No such file or directory.
[Current thread is 1 (Thread 0x7fa7f769a040 (LWP 6525))]
(gdb) bt
#0  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51
#1  0x00007fa7f6305c5d in __GI_abort () at abort.c:90
#2  0x00007fa7f634aaad in __libc_message (action=action@entry=do_abort, fmt=fmt@entry=0x7fa7f645957b "%s\n") at ../sysdeps/posix/libc_fatal.c:181
#3  0x00007fa7f6352298 in malloc_printerr (str=str@entry=0x7fa7f645ae88 "double free or corruption (!prev)") at malloc.c:5368
#4  0x00007fa7f635358c in _int_free (av=0x7fa7f668dc40 <main_arena>, p=0x7fa7f8023b50, have_lock=<optimized out>) at malloc.c:4288
#5  0x00007fa7f7092a8d in objspace_xfree (objspace=0x7fa7f7fb3d20, ptr=0x7fa7f8023b60, old_size=<optimized out>) at gc.c:7720
#6  0x00007fa7f70a514f in rb_io_fptr_finalize (fptr=0x7fa7f8023b60) at io.c:4338
#7  0x00007fa7f70897b1 in run_final (objspace=0x7fa7f7fb3d20, zombie=140359397235560) at gc.c:2691
#8  finalize_list (objspace=objspace@entry=0x7fa7f7fb3d20, zombie=140359397235560) at gc.c:2707
#9  0x00007fa7f7089870 in finalize_deferred (objspace=objspace@entry=0x7fa7f7fb3d20) at gc.c:2728
#10 0x00007fa7f7094280 in rb_objspace_call_finalizer (objspace=0x7fa7f7fb3d20) at gc.c:2794
#11 rb_gc_call_finalizer_at_exit () at gc.c:2780
#12 0x00007fa7f76b97e2 in main ()

1 Ответ

0 голосов
/ 18 октября 2018

Вы пробовали ruby_cleanup(0) вместо этого?

Глядя на источник , похоже, что ruby_finalize просто гарантирует, что код Ruby завершает работу (например, вызывает at_exit перехватчики)возможно убивает любые рубиновые темы)Принимая во внимание, что ruby_cleanup вызывает finalize, а затем очищает саму виртуальную машину.

Edit:

На основании моих тестов этот ответ не работает (несмотря на то, что он принят),Вы не можете перезапустить виртуальную машину Ruby в том же процессе.Единственный обходной путь, о котором я мог подумать, - это запустить виртуальную машину на развилке, чтобы вы могли гарантировать ее полную очистку.

...