Does the calling code have a proper prototype for the soap_malloc()
function in scope?
It seems the void *
is being converted to int
, i.e. the default return type. This happens if the function hasn't been properly declared.
题
I have a routine calling gSoap
API function soap_malloc
. But the program gives me a segmentation fault
whenever I try to access the memory allocated by soap_malloc
. When I use gdb
to debug it. I find that inside soap_malloc
, return value stored in register %rax
is 0x7fffec0018f0
. But on return, %rax
changed to 0xffffffffec0018f0
. Only the lower 32-bit was retained, the higher 32-bit all changed to 1
. And that lead to accessing an address which is quite high, therefore caused the routine stopped. Thanks for you all to give me any ideas on how can this be happening. I'm running my multi-thread program in Ubuntu12.04 x86-64
.
This is how I call it:
void *temp = soap_malloc(soap, 96);
And this is the soap_malloc
implementation(only that else
part is executed, and macro SOAP_MALLOC
is just passing the second argument to malloc
, SOAP_CANARY
is 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;
}
This is the definition of SOAP_NON_NULL
:
static const char soap_padding[4] = "\0\0\0";
#define SOAP_NON_NULL (soap_padding)
Updates(2013-03-12)
I explicitly declared soap_malloc
as returning void *
and the problem solved. Previously, the returned value is truncated to int
and the sign bit 1
was extended when assigning the result to void *temp
.
解决方案
Does the calling code have a proper prototype for the soap_malloc()
function in scope?
It seems the void *
is being converted to int
, i.e. the default return type. This happens if the function hasn't been properly declared.