2010-10-29 9 views
0

Je mettais à jour le système d'exploitation sur l'un de nos build de Centos 5.3 32bit à Centos 5.5 32bit. Après avoir fait la mise à jour du paquet j'ai redémarré, vérifié une copie propre de la source, construit et exécuté les tests unitaires. Tous les tests unitaires qui reposent sur notre classe de base MemMap ont commencé à échouer.Pourquoi MAP_GROWSDOWN provoque-t-il des erreurs SIGBUS après la mise à niveau vers Centos 5.5?

L'erreur se produit lorsque nous essayons de définir la valeur de la page de garde après le mappage de la mémoire. Après avoir piquer autour, j'ai été en mesure d'isoler le problème à notre utilisation de l'indicateur MAP_GROWSDOWN, les tests fonctionnent bien sans elle, mais se plantent lorsque le drapeau est défini. Ces tests ont fonctionné correctement lorsque le système de build fonctionnait sous 5.3, mais ont immédiatement commencé à se bloquer lorsque nous sommes passés à 5.5. Ils fonctionnent également très bien sur ma machine de développement qui tourne également en 5.5 mais c'est du vrai matériel; le système de construction est une machine virtuelle XEN. C'est un morceau de code stable qui n'a pas été modifié dans plusieurs versions et qui a une couverture de test unitaire au nord de 80%.

Alors je suppose que ma question est la suivante: pourquoi cela se produit-il?

int flags = MAP_ANONYMOUS|MAP_PRIVATE|MAP_GROWSDOWN; 
int prot = PROT_EXEC|PROT_READ|PROT_WRITE; 
size_t length = 524288; 

long rv = ::sysconf(_SC_PAGESIZE); 
if (rv < 0) 
    throw SystemException(errno); 
size_t pagelength = size_t(rv); 

// Adjust length for guard page 
length = pagelength * (((length + pagelength - 1)/pagelength) + 1); 

m_addr = ::mmap(NULL, length, prot, flags, -1, 0); 
if (m_addr == MAP_FAILED) 
    throw SystemException(errno); 

m_stackaddr = static_cast<void *>(static_cast<char *>(m_addr) + pagelength); 
m_length = length - pagelength; 

// Fill the guard page with an interesting pattern 
unsigned int *g = static_cast<unsigned int *>(m_addr); 
for (size_t i=0; i < pagelength; i += sizeof(unsigned int)) 
    *g++ = 0xBADC0FFEU; <-- SIGBUS HAPPENS HERE ON FIRST ITERATION 
+1

Quel est le but de 'MAP_GROWSDOWN' si vous êtes en train de salir (et de forcer à être mappé) le bas du mappage de toute façon? – ephemient

Répondre

Questions connexes