Domanda

Ho un tipo di matrice che contiene un'array void*, che rappresenta una serie di oggetti (che sono tutti di un tipo in una determinata matrice, ad esempio, tutti gli interi C, tutti i galleggianti, i raddoppiati, una varietà di strutture, o possibilmente anche Tutti i VALUE di rubino).

Assegnazione della memoria e collezione di rifiuti sembra funzionare correttamente fino a cercare di creare una matrice di generatori di VALUEs.

Ho la seguente funzione di marchio definita:

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)));
}
.

Quindi la marcatura solo se è in realtà una matrice VALUE, in caso contrario, NULL viene passato a Data_Wrap_Struct per la funzione Mark.

Ma sto ottenendo un segfault quando testo alcune delle funzioni della matrice di VALUE (vedi GIST) .

In particolare, sembra Segfault la prima volta che provo a chiamare un metodo Ruby sul primo oggetto nell'array VALUE*:

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 è un globale definito nella mia funzione Init come rb_intern("*").

È possibile che questo non sia un problema di raccolta della spazzatura, ma il GC è la parte di Ruby che capisco il minimo - e il mio Segfault è anche quasi identico a Questa traccia , che il poster attribuisce al GC.

Allora, le mie domande:

    .
  1. Se è il GC, qual è il modo appropriato per contrassegnare una serie di VALUEs?

  2. Se non è il GC, come posso andare a diagnosticare questo tipo di errore? Non ho mai visto niente del genere.

  3. Modifica:

    si scopre che questo è un esempio di mancata inizializzazione di VALUEs creata in c.

    In altre parole, assicurati di fare *(VALUE*)a = INT2FIX(0) prima di provare a accedere a a.

    Io penso ancora che la domanda sia rilevante. Non sono riuscito a trovare alcuni buoni esempi di marcatura per la raccolta di rifiuti puliti e spazzate, su Stackoverflow o altrove. Se è possibile fornire un tale esempio e / o spiegazione, segnerò come una risposta corretta a questa domanda.

È stato utile?

Soluzione

Ruby's Mark-and-Sweep GC funziona in due fasi.

Il primo stadio segna gli oggetti in diretta.Funziona ricorsivamente chiamando la funzione di marcatura di ciascun "Live Objects" noto.Il set iniziale di oggetti live è prodotto scansionando la pila C di ciascun filettatura rubino nota o di ciascun oggetto globale registrato (c'è una funzione C per registrare / deregistrati oggetti "noti dal vivo").La funzione di marcatura dell'oggetto X dovrebbe quindi chiamare rb_gc_mark per ciascun oggetto a cui si riferisce.In altre parole, quello che fai è esattamente ciò che dovresti fare.

Tuttavia, come notato in seguito, non qualsiasi valore possibile è un oggetto rubino valido.Tuttavia, credo che l'inizializzazione con Qnil (I.e. Nil) sarebbe più ruby-ish.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top