2011-01-06 12 views
6

Attualmente sto lavorando su un codice di elaborazione dati utilizzando libxml2. Sono bloccato su una perdita di memoria impossibile da rimuovere. Ecco un codice minimo per generarlo:ho trovato un bug libxml2 (perdita di memoria nell'analisi multithreading)?

#include <stdlib.h> 
#include <stdio.h> 
#include <libxml/parser.h> 
#include <libxml/tree.h> 
#include <omp.h> 

int main(void) 
{ 
    xmlDoc *doc; 
    int tn; 
    char fname[32]; 

    omp_set_num_threads(2); 
    xmlInitParser(); 
    #pragma omp parallel private(doc,tn,fname) 
    { 
     tn = omp_get_thread_num(); 
     sprintf(fname,"testdoc%d.xml",tn); 
     doc = xmlReadFile(fname,NULL,0); 
     printf("document %s parsed on thread %d (%p)\n",fname,tn,doc); 
     xmlFreeDoc(doc); 
    } 
    xmlCleanupParser(); 

    return EXIT_SUCCESS; 
} 

In fase di esecuzione, l'uscita è:

document testdoc0.xml parsed on thread 0 (0x1005413a0) 
document testdoc1.xml parsed on thread 1 (0x1005543c0) 

conferma che abbiamo davvero multi-threading e che doc è davvero privato nella regione parallelo. Si può notare che ho applicato correttamente le istruzioni di sicurezza del thread per l'utilizzo di libxml2 (http://xmlsoft.org/threads.html). Valgrind riferisce:

HEAP SUMMARY: 
    in use at exit: 9,000 bytes in 8 blocks 
    total heap usage: 956 allocs, 948 frees, 184,464 bytes allocated 

968 bytes in 1 blocks are definitely lost in loss record 6 of 8 
    at 0x1000107AF: malloc (vg_replace_malloc.c:236) 
    by 0x1000B2590: xmlGetGlobalState (in /opt/local/lib/libxml2.2.dylib) 
    by 0x1000B1A18: __xmlDefaultSAXHandler (in /opt/local/lib/libxml2.2.dylib) 
    by 0x100106D18: xmlDefaultSAXHandlerInit (in /opt/local/lib/libxml2.2.dylib) 
    by 0x100041BE7: xmlInitParserCtxt (in /opt/local/lib/libxml2.2.dylib) 
    by 0x100042145: xmlNewParserCtxt (in /opt/local/lib/libxml2.2.dylib) 
    by 0x10004615E: xmlCreateURLParserCtxt (in /opt/local/lib/libxml2.2.dylib) 
    by 0x10005B56B: xmlReadFile (in /opt/local/lib/libxml2.2.dylib) 
    by 0x100000E03: main.omp_fn.0 (in ./xtest) 
    by 0x100028FA3: gomp_thread_start (in /opt/local/lib/gcc44/libgomp.1.dylib) 
    by 0x1001E8535: _pthread_start (in /usr/lib/libSystem.B.dylib) 
    by 0x1001E83E8: thread_start (in /usr/lib/libSystem.B.dylib) 

LEAK SUMMARY: 
    definitely lost: 968 bytes in 1 blocks 
    indirectly lost: 0 bytes in 0 blocks 
    possibly lost: 0 bytes in 0 blocks 
    still reachable: 8,032 bytes in 7 blocks 
     suppressed: 0 bytes in 0 blocks 
Reachable blocks (those to which a pointer was found) are not shown. 
To see them, rerun with: --leak-check=full --show-reachable=yes 

Questo sta lavorando per me qualunque sia il documento XML utilizzato. Sto usando libxml 2.7.8, su Mac OS X 10.6.5 con gcc 4.4.5.

Qualcuno è in grado di riprodurre questo errore?

Grazie,

Antonin

+0

Non vedo ciò che quel codice potrebbe generare tale output. Forse hai tagliato troppo il codice. –

+0

La dimensione della perdita dipende dal file XML che si analizza? – AShelly

+0

@Hans Passant: Non vedo né perché questo codice lo stia facendo, ma lo è, in un ambiente pulito. Voglio sapere se altre persone sono in grado di riprodurlo prima di segnalare un bug. –

risposta

2

Probabilmente si dovrebbe portare questo in su sulla mailing list libxml2.

http://mail.gnome.org/mailman/listinfo/xml

+0

L'ho messo sul bugzilla libxml2, volevo solo postare qualcosa per sapere se qualcuno è in grado di riprodurre il bug. –

3

Dal sito web che avete elencato sopra (http://xmlsoft.org/threads.html):

A partire dalla 2.4.7, marche libxml2 disposizioni per garantire che thread concorrenti possano lavorare in sicurezza in parallelo parsing diversi documenti.

L'esempio sembra utilizzare un xmlReadFile per lo stesso documento (testdoc.xml) per ogni thread. Si afferma inoltre:

Si noti che il filo di sicurezza non può essere garantita per più thread condividono lo stesso documento, il bloccaggio deve essere fatto a livello di applicazione ...

+0

Grazie, hai ragione. Ma purtroppo il codice originale su cui sto lavorando usa documenti davvero diversi, ho modificato il mio codice di esempio (e modificato la mia domanda) e la perdita rimane. –