Проблемы с памятью gSoap - PullRequest
       10

Проблемы с памятью gSoap

0 голосов
/ 20 декабря 2011

Это начинает расстраивать меня до чертиков.

Я пытаюсь написать набор фиктивных функций для интерфейса, чтобы протестировать класс, который будет обрабатывать все это дерьмо SOAP. В то же время я надеюсь написать его таким образом, чтобы я мог подключить его к базовой структуре сервера SOAP и создать макет службы, которую я использую для интеграционного тестирования. К сожалению, я столкнулся с проблемой, которую не могу понять, посмотрев документацию.

Для начала я создал структуру контекста мыла RAII:

struct soap_context
{
    soap_context()
        : ctx_(soap_new())
    {
        soap_begin(ctx_);
    }
    ~soap_context()
    {
        soap_destroy(ctx_);
        soap_end(ctx_);
        soap_done(ctx_);
        soap_free(ctx_);
    }

    soap* get() const { return ctx_; }

private:
    soap* ctx_;
};

Из того, что я понимаю, прочитав документацию, которая должна быть излишней. Он должен ОПРЕДЕЛЕННО очищать любую память, которую я выделил с помощью soap_new или soap_malloc с этим контекстом, когда вышеуказанный объект уничтожен. Это не то поведение, которое я наблюдаю.

Интерфейс, с которым я имею дело, действительно ужасен. Он имеет этот блок верхнего уровня, который содержит указатель «return_», который должен быть выделен. Внутри него есть куча мелких капель, которые также должны быть выделены. НИЧЕГО не может быть по значению, это было бы слишком просто!

Меньшие внутренние капли, кажется, уничтожаются правильно, но верхний уровень один ... нет.

Вот мыльный код, который я создал ... некоторые имена изменены, чтобы защитить виновных (ниже называется то, что называется "stupid_inner_bean":

void * soap_calloc(soap* ctx, size_t size)
{
    void * ptr = soap_malloc(ctx, size);
    memset(ptr, 0, size);

    return ptr;
}

int __something_stupid( struct soap* ctx
                            , struct stupid_params * params
                            , struct stupid_response * response )
{
  response->return_ = static_cast<stupid_inner_bean*>(soap_calloc(ctx, sizeof(stupid_inner_bean));

  ... lots of inner stuff created with soap_calloc, but it DOES get freed...

  return SOAP_OK;
}

int soap_call___something_stupid( struct soap *ctx
                                , const char *
                                , const char *
                                , struct stupid_params *params
                                , struct stupid_response *response )
{
    return __something_stupid(ctx, params, response);
}

Затем я вызываю его изнутри некоторых тестов CppUnit:

{

    char * phones[] = {"12345678901","55555555555"};
    stupid_params params =
    {
      "test_user1"
    , "test_pass1"
    , 2
    , phones
    };
    stupid_response response = {};

    soap_context soap_ctx;

    soap_call___something_stupid(soap_ctx.get(), "IGNORED", 0, &params, &response);

    // OK to access directly without checks.  If we crash, we fail the test!
    CPPUNIT_ASSERT(response.return_->error == 0);
}

Есть идеи, что я мог упустить? Документы кажутся довольно конкретными, явно неясными в отношении soap_end (), уничтожающего все, что создано с помощью soap_malloc. FAQ говорит что-то о отладочных сборках и ожидании soap_done, поэтому я назвал это. Пробовал вставлять случайные вызовы soap_begin () ... застрял при каждом вызове soap, который говорит, что он удаляет что-то в деструкторе моего диспетчера контекста ... насколько я могу судить, я сделал все, что мне нужно, а затем кучу другое случайное дерьмо ... но Вальгринд все еще говорит, что это утечка.

Интересно, что если я добавлю функцию очистки в диспетчер контекста и вызову ее между вызовами, я смогу избавиться от некоторых утечек. Почему же деструктор, который делает то же самое, не имеет никакого эффекта?

Я просто сдался и поблагодарил моих счастливых звезд за то, что это только для тестирования. Клиентская программа, похоже, не протекает.

...