2

gSoapAPI関数を呼び出すルーチンがありますsoap_malloc。しかし、プログラムは、segmentation faultによって割り当てられたメモリにアクセスしようとするたびに私に与えてくれますsoap_mallocgdbデバッグに使用する場合。内部soap_mallocでは、レジスタに格納されている戻り値%rax0x7fffec0018f0です。しかし、戻ったときに、に%rax変更されました0xffffffffec0018f0。下位32ビットのみが保持され、上位32ビットはすべてに変更されました1。そして、それは非常に高いアドレスにアクセスすることにつながり、したがってルーチンが停止しました。これがどのように起こっているのかについてのアイデアを私に与えてくれてありがとう。でマルチスレッドプログラムを実行していUbuntu12.04 x86-64ます。

これは私がそれを呼ぶ方法です:

void *temp = soap_malloc(soap, 96);

そして、これはsoap_malloc実装です(そのelse部分のみが実行され、マクロSOAP_MALLOCは2番目の引数をに渡すだけmallocです。SOAP_CANARY定数です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;
}

これはの定義ですSOAP_NON_NULL

static const char soap_padding[4] = "\0\0\0";
#define SOAP_NON_NULL (soap_padding)

更新(2013-03-12
私は明示的soap_mallocに戻ることを宣言しvoid *、問題は解決しました。以前は、結果をに割り当てるときに、戻り値がに切り捨てられint、符号ビットが拡張されていました。1void *temp

4

1 に答える 1

3

呼び出し元のコードには、soap_malloc()スコープ内の関数の適切なプロトタイプがありますか?

は、つまりデフォルトのリターンタイプvoid *に変換されているようです。intこれは、関数が適切に宣言されていない場合に発生します。

于 2013-03-11T12:54:32.967 に答える