2014-04-22 3 views
1

J'ai ce code:C++ std :: carte std :: bitset segfault

static void XMLCALL 
hackHandler(void *data, const XML_Char *name, const XML_Char **attr) 
{ 
SetPointers* sets = static_cast<SetPointers*>(data); 
if (strcmp(name, "instruction") == 0 || strcmp(name, "load") == 0 || 
    strcmp(name, "modify") == 0||strcmp(name, "store") == 0) { 
    long address(0); 
    long page(0); 
    int offset(0); 
    long size(0); 
    int i(0); 
    for (i = 0; attr[i]; i += 2) { 
     if (strcmp(attr[i], "address") == 0) { 
      address = strtol(attr[i+1], NULL, 16); 
      page = address >> 12; 
      offset = address & 0xFFF; 
      continue; 
     } 
     if (strcmp(attr[i], "size") == 0) { 
      size = strtol(attr[i + 1], NULL, 16); 
     } 
    } 
    map<long, bitset<4096> >::iterator itLocal; 

    itLocal = sets->lCount->find(page); 
    if (itLocal == sets->lCount->end()) { 
     sets->lCount->insert(pair<long, bitset<4096> > 
      (page, bitset<4096>())); 
     itLocal = sets->lCount->find(page); 
    } 
    //now mark the bitmap 
    for (i = 0; i < size; i++) { 
     (itLocal->second)[i + offset] = 1; 
    } 

    if (strcmp(name, "instruction") == 0) { 
     itLocal = sets->lCode->find(page); 
     if (itLocal == sets->lCode->end()) { 
      sets->lCode->insert(pair<long, bitset<4096> > 
       (page, bitset<4096>())); 
      itLocal = sets->lCode->find(page); 
     } 
     for (i = 0; i < size; i++) { 
      (itLocal->second)[i + offset] = 1; 
     } 
    } else { 
     itLocal = sets->lMemory->find(page); 
     if (itLocal == sets->lMemory->end()) { 
      sets->lMemory->insert(pair<long, bitset<4096> > 
       (page, bitset<4096>())); 
      itLocal = sets->lMemory->find(page); 
     } 
     for (i = 0; i < size; i++) { 
      (itLocal->second)[i + offset] = 1; 
     } 
    } 
} 
} 

Cette initiative vise à marquer un bitset, 4096 bits de long, avec un 1 lorsque cet octet d'une page est accessible.

Ce code fonctionne bien sur mon ordinateur de test lorsque j'utilise environ 1 Go de XML pour le tester. Mais quand je le lance sur la chose complète (220GB XML), il donne une erreur de segmentation sur:

sets->lCode->insert(pair<long, bitset<4096> > 
      (page, bitset<4096>())); 

Mais il le fait très tôt dans la course, il est donc difficile de penser que c'est un produit de la taille des données. En tout cas je n'ai eu aucun problème en analysant cet ensemble de données plus grand utilisant un code très semblable (vérifiez mon repo de github au https://github.com/mcmenaminadrian - ce projet est memsize, mais pagestat emploie le code siumilar très). Le seul facteur de différenciation avec ce code semble être l'utilisation de bitset. Est-ce que quelqu'un peut repérer l'erreur qui m'a échappé jusqu'à présent?

(Le code est multithread - est thread bitset sécurité pourrait-il être un problème bibliothèque - mon système de test est Mac OS X, mais le système "production" est Linux - Ubuntu 12.04 LTS)

+1

est-ce que 'i + offset' est garanti être inférieur à '4096'? –

+0

C'est la question évidente - et il devrait être. Je suppose qu'il pourrait y avoir un mauvais morceau de XML qui cause ceci bien que – adrianmcmenamin

+0

je doute que n'importe quelle implémentation commune de récipient de C++ soit thread-safe d'une manière qu'elle permette des opérations de lecture/écriture simultanées. Voir les documents pour [g ++] (http://gcc.gnu.org/onlinedocs/libstdc++/manual/using_concurrency.html) et [msvc] (http://msdn.microsoft.com/en-us/library/c9ceah3b. aspx) – Stephan

Répondre

1

Il n'y a pas vérifie que i + offset est inférieur à 4096. Cela pourrait être la source du problème.

Questions connexes