memory allocation with memory_pool in IO Thread -> crash

Do not post support requests, bug reports or feature requests. Discuss CEF here. Non-CEF related discussion goes in General Discussion!

memory allocation with memory_pool in IO Thread -> crash

Postby gabyx » Mon Feb 26, 2018 5:36 pm

I have another weird problem:

I wanted to use a memory_pool in my derived class BackenSchemeHandlerFactory from `CefSchemeHandlerFactory` such that it does not always allocate with "new" on the heap.
What I did is the following: I included the awesome library https://github.com/foonathan/memory and used a memory_pool which I use to get some memory node (the size of the Handler it should return)
and then I wrap that thing into a CefRefPtr<handler>. Of course since the memory_pool has allocated the memory, my handler implements a special `Release()` for the CefRefPtr, to properly deallocate and delete itself trough the memory_pool which is stored in the BackenSchemeHandlerFactory.

I have a crash only when running this test code in the BackenSchemeHandlerFactory::Create function, the test code runs fine standalone:
https://github.com/gabyx/ExecutionGraph/blob/devGUI/gui/tests/src/main_MemoryPool.cpp
But the same code crashes while running my CEF Application with the EXC_BAD_ACCESS (code=EXC_I386_GPFLT).
I am really wondering what could be wrong. The deleter is called in CEF_IO_THREAD as well, so there is no ownership problem.
Is there any limitation about memory allocation in the IO Thread on the low-level calls malloc/free, alloca, or new??
If I dont use memory_pool and instead just use "new" everything works of course.
Thanks for any help!!

Code: Select all
#include "include/cef_base.h"

using namespace foonathan::memory;

// A ref counted class (CefRefPtr from Chromium Embedded Framework)
struct A : CefBaseRefCounted
{
    template<typename D>
    A(int a, D&& d)
        : m_a{a}, deleter(d) {}
    ~A() { std::cout << "dtor A :" << m_a[0] << std::endl; }
    int m_a[100];

    std::function<void(A*)> deleter;  // Wrap here the deleter to delete over the pool

    void AddRef() const override { m_refCount.AddRef(); }
    bool Release() const override
    {
        if(m_refCount.Release())
        {
            deleter(const_cast<A*>(this));
            return true;
        }
        return false;
    }
    bool HasOneRef() const override { return m_refCount.HasOneRef(); }

    CefRefCount m_refCount;
};

MY_TEST(MemoryPool, Test1)
{
    using RawAllocator = memory_pool<>;
    using Ptr          = CefRefPtr<A>;
    using RawPtr       = std::unique_ptr<A, allocator_deallocator<A, RawAllocator>>;

    RawAllocator pool(sizeof(A), sizeof(A) * 10);
    std::vector<Ptr> vec;
    for(auto i = 0; i < 30000; ++i)
    {
        auto memory = pool.allocate_node(); // CRASHES here and third call

        // raw_ptr deallocates memory in case of constructor exception
        RawPtr result(static_cast<A*>(memory), {pool});
        // call constructor (placement new)
        ::new(memory) A(i, [&pool](auto* p) { allocator_deleter<A, RawAllocator>{pool}(p); });
        // pass ownership to return value CefRefPtr which will use the internal BackendResourceHandler::m_deleter
        std::cout << "allocated " << i << std::endl;
        vec.emplace_back(Ptr(result.release()));
    }
    std::shuffle(vec.begin(), vec.end(), std::mt19937{});
}

int main(int argc, char** argv)
{
    testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
}
gabyx
Newbie
 
Posts: 7
Joined: Sat Jan 13, 2018 9:06 am

Re: memory allocation with memory_pool in IO Thread -> crash

Postby gabyx » Tue Feb 27, 2018 6:16 pm

I found the error, the memory pool is not the problem, I accidentally did placement new with a wrong size, not according to the pool...
gabyx
Newbie
 
Posts: 7
Joined: Sat Jan 13, 2018 9:06 am


Return to CEF Discussion

Who is online

Users browsing this forum: No registered users and 9 guests