2013-03-11 2 views
2

У меня есть обычное вызов gSoap Функция API soap_malloc. Но программа дает мне segmentation fault всякий раз, когда я пытаюсь получить доступ к памяти, выделенной soap_malloc. Когда я использую gdb для его отладки. Я считаю, что внутри soap_malloc, возвращаемое значение, хранящееся в регистре %rax, равно 0x7fffec0018f0. Но по возвращении %rax изменен на 0xffffffffec0018f0. Только нижний 32-бит был сохранен, более высокие 32-битные все изменились на 1. И это приводит к доступу к адресу, который является довольно высоким, поэтому вызвал рутинную остановку. Благодарим вас за все, чтобы дать мне какие-нибудь идеи о том, как это может произойти. Я запускаю свою программу с несколькими потоками в Ubuntu12.04 x86-64.Как можно изменить значение ценности?

Это, как я это называю:

void *temp = soap_malloc(soap, 96); 

И это soap_malloc реализация (только что else часть выполнена, и макро SOAP_MALLOC просто передавая второй аргумент 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, а знак знака 1 был продлен при присвоении результата void *temp.

+0

Можете ли вы привести пример минимального кода, который воспроизводит эту проблему? –

+0

В некоторых местах вы используете ** soap_malloc ** в других, которые вы используете ** SOAP_MALLOC **. Что такое определение ** SOAP_MALLOC ** или является частью библиотеки gSoap? – Jere

+0

@ Я описываю «SOAP_MALLOC» - это макрос, который просто передает второй аргумент 'malloc'. Извините за это, я отредактирую их в тело кода. – leowang

ответ

3

Имеет ли код вызова подходящий прототип для функции soap_malloc() в области видимости?

Кажется, что void * преобразуется в int, то есть тип возвращаемого по умолчанию. Это происходит, если функция не была объявлена ​​должным образом.

+0

Извините, я должен был поставить код вызова выше 'soap_malloc'. Я просто использовал 'void * temp' для сохранения возвращаемого значения. – leowang

+0

@leowang Не уверен, что я понимаю вашу коррекцию ... Это не имеет значения. Если вы вызываете простой старый 'malloc()' * без *, включая заголовок, подобный этому: 'void * p = malloc (1024)', вы * будете * получать результат размера 'int'. Тип в левой части '=' не имеет значения. – unwind

+0

Прости, что не понимаю. Что-то не так с 'malloc'? Что вы подразумеваете под заголовком? – leowang