I have a matrix type which contains a void*
array, representing an array of objects (which are all of one type in a given matrix, e.g., all C integers, all floats, doubles, a variety of structs, or possibly even all Ruby VALUE
s).
Memory allocation and garbage collection seems to work correctly until I try to create a matrix of VALUE
s.
I have the following mark function defined:
void mark_dense_storage(void* s) {
size_t i;
DENSE_STORAGE* storage = (DENSE_STORAGE*)s;
if (storage && storage->dtype == RUBY_OBJECT)
for (i = 0; i < count_dense_storage_elements(s); ++i)
rb_gc_mark(*((VALUE*)(storage->elements + i*sizeof(VALUE)));
}
So it only does marking if it's actually a VALUE
matrix — otherwise, NULL
gets passed to Data_Wrap_Struct
for the mark function.
But I'm getting a segfault when I test some of the VALUE
matrix functions (see gist).
Specifically, it seems to segfault the first time I try to call a Ruby method on the very first object in the VALUE*
array:
C[i+j*ldc] = rb_funcall(C[i+j*ldc], nm_id_mult, 1, beta); // C[i+j*ldc] = C[i+j*ldc]*beta
nm_id_mult
is a global defined in my Init
function as rb_intern("*")
.
It's possible this isn't a garbage collection problem, but the GC is the part of Ruby that I understand the least — and my segfault is also almost identical to this trace, which the poster attributes to the GC.
So, my questions:
If it's the GC, what's the appropriate way to mark an array of
VALUE
s?If it's not the GC, how do I go about diagnosing this type of error? I've never seen anything like it.
EDIT:
Turns out that this is an example of failure to initialize VALUE
s created in C.
In other words, make sure to do *(VALUE*)a = INT2FIX(0)
before you try to access a
.
I do still think the question is relevant. I haven't managed to find any really good examples of marking for clean-and-sweep garbage collection, on StackOverflow or elsewhere. If you can provide such an example and/or explanation, I'll mark that as a correct answer to this question.