J'ai une routine d'appeler la fonction gSoap
API soap_malloc
. Mais le programme me donne un segmentation fault
chaque fois que j'essaie d'accéder à la mémoire allouée par soap_malloc
. Lorsque j'utilise gdb
pour le déboguer. Je trouve que l'intérieur soap_malloc
, la valeur de retour stockée dans le registre %rax
est 0x7fffec0018f0
. Mais au retour, %rax
a été remplacé par 0xffffffffec0018f0
. Seul le 32 bits inférieur a été conservé, le 32 bits le plus élevé a été remplacé par 1
. Et cela conduit à accéder à une adresse qui est assez élevée, donc a entraîné l'arrêt de la routine. Merci à vous tous de me donner des idées sur la façon dont cela peut se produire. Je cours mon programme multi-thread dans Ubuntu12.04 x86-64
.Comment la valeur de retour peut-elle être modifiée?
Voilà comment je l'appelle:
void *temp = soap_malloc(soap, 96);
Et c'est la mise en œuvre soap_malloc
(seule la partie else
est exécutée et macro SOAP_MALLOC
ne fait que passer le second argument de malloc
, SOAP_CANARY
est constant 0xC0DE
):
#ifndef SOAP_MALLOC /* use libc malloc */
# define SOAP_MALLOC(soap, size) malloc(size)
#endif
#ifndef SOAP_CANARY
# define SOAP_CANARY (0xC0DE)
#endif
void* soap_malloc(struct soap *soap, size_t n)
{ register char *p;
if (!n)
return (void*)SOAP_NON_NULL;
if (!soap)
return SOAP_MALLOC(soap, n);
if (soap->fmalloc)
p = (char*)soap->fmalloc(soap, n);
else
{ n += sizeof(short);
n += (-(long)n) & (sizeof(void*)-1); /* align at 4-, 8- or 16-byte boundary */
if (!(p = (char*)SOAP_MALLOC(soap, n + sizeof(void*) + sizeof(size_t))))
{ soap->error = SOAP_EOM;
return NULL;
}
/* set the canary to detect corruption */
*(unsigned short*)(p + n - sizeof(unsigned short)) = (unsigned short)SOAP_CANARY;
/* keep chain of alloced cells for destruction */
*(void**)(p + n) = soap->alist;
*(size_t*)(p + n + sizeof(void*)) = n;
soap->alist = p + n;
}
soap->alloced = 1;
return p;
}
Telle est la définition de SOAP_NON_NULL
:
static const char soap_padding[4] = "\0\0\0";
#define SOAP_NON_NULL (soap_padding)
Mises à jour (12/03/2013 )
Je déclare explicitement soap_malloc
que le retour void *
et le problème résolu. Auparavant, la valeur renvoyée est tronquée à int
et le bit de signe 1
a été étendu lors de l'attribution du résultat à void *temp
.
Pouvez-vous fournir un exemple de code minimal qui reproduit ce problème? –
Dans certains endroits, vous utilisez ** soap_malloc ** dans d'autres applications ** SOAP_MALLOC **. Quelle est la définition de ** SOAP_MALLOC ** ou cette partie de la bibliothèque gSoap? – Jere
@Jere je décris 'SOAP_MALLOC' est une macro qui passe juste le deuxième argument à' malloc'. Désolé pour ça, je vais les éditer dans le corps du code. – leowang