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.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top