marvin-cpp
marvin-cpp copied to clipboard
[bug report] Crash in ‘ContigBuffer’ Destructor After Catching MARVIN_THROW with try-catch Block
I am currently using this project on Windows, and so far, it's been working well. However, I've noticed that if I use a 'try-catch' block to catch the MARVIN_THROW exception, a crash occurs. Here's the code snippet where the crash occurs after catching the exception:
try { m_server_uptr = std::make_unique<Marvin::TcpServer>([this](boost::asio::io_service& io) { if (m_collector_sptr == nullptr) { m_collector_sptr = std::make_shared<CoutCollector>(io, m_filter_sptr); } MitmAppUPtr app_uptr = std::make_unique<MitmApp>(io, m_collector_sptr, m_filter_sptr); return app_uptr; }); m_server_uptr->listen(port); std::cout << "Mitm Server returned from listen" << std::endl; } catch (const std::exception& e) { std::cout << e.what() << std::endl; }
The crash occurs when I deliberately trigger the MARVIN_THROW. Specifically, it crashes in the destructor of the 'ContigBuffer' class at the marked line:
~ContigBuffer() { if ((m_memPtr != nullptr) && (m_capacity > 0)) { m_strategy->deallocate(m_memPtr); // Here } }
It appears that the 'm_strategy' object is being destructed before 'ContigBuffer'. The root cause of this crash is likely due to 'ContigBuffer' using a reference to 'BufferStrategyInterface', but 'BufferStrategyInterface' might be destructed before 'ContigBuffer'. To potentially resolve this issue and ensure the appropriate destruction order, you might consider adjusting the code to pass std::shared_ptr<BufferStrategyInterface> at this point.
class ContigBuffer { protected: using S = BufferStrategyInterface; using SSPtr = std::shared_ptr<S>; SSPtr m_strategy; //here void* m_memPtr; /// points to the start of the memory slab managed by the instance char* m_cPtr; /// same as memPtr but makes it easier in debugger to see whats in the buffer std::size_t m_length; /// std::size_t m_capacity; /// the capacity of the buffer, the value used for the malloc call std::size_t m_size; /// size of the currently filled portion of the memory slab public: using SPtr = std::shared_ptr<ContigBuffer>; static std::size_t min_buffer_size; ......
Thank you for the email. I am delighted to see someone using this project even though I only did it as a learning exercise.I am not able to do anything on this project at the moment as i am traveling in a remote part of the world for at least another month.Thanks againRobSent from my iPhoneOn 21 Aug 2023, at 19:08, kevin.zhang @.*> wrote: I am currently using this project on Windows, and so far, it's been working well. However, I've noticed that if I use a 'try-catch' block to catch the MARVIN_THROW exception, a crash occurs. Here's the code snippet where the crash occurs after catching the exception: try { m_server_uptr = std::make_uniqueMarvin::TcpServer([this](boost::asio::io_service& io) { if (m_collector_sptr == nullptr) { m_collector_sptr = std::make_shared<CoutCollector>(io, m_filter_sptr); } MitmAppUPtr app_uptr = std::make_unique<MitmApp>(io, m_collector_sptr, m_filter_sptr); return app_uptr; }); m_server_uptr->listen(port); std::cout << "Mitm Server returned from listen" << std::endl; } catch (const std::exception& e) { std::cout << e.what() << std::endl; } The crash occurs when I deliberately trigger the MARVIN_THROW. Specifically, it crashes in the destructor of the 'ContigBuffer' class at the marked line: ~ContigBuffer() { if ((m_memPtr != nullptr) && (m_capacity > 0)) { m_strategy->deallocate(m_memPtr); // Here } } It appears that the 'm_strategy' object is being destructed before 'ContigBuffer'. The root cause of this crash is likely due to 'ContigBuffer' using a reference to 'BufferStrategyInterface', but 'BufferStrategyInterface' might be destructed before 'ContigBuffer'. To address this issue and ensure the correct destruction order, To potentially resolve this issue and ensure the appropriate destruction order, you might consider adjusting the code to pass std::shared_ptr at this point. class ContigBuffer { protected: using S = BufferStrategyInterface; using SSPtr = std::shared_ptr<S>; SSPtr m_strategy; //here void m_memPtr; /// points to the start of the memory slab managed by the instance char m_cPtr; /// same as memPtr but makes it easier in debugger to see whats in the buffer std::size_t m_length; /// std::size_t m_capacity; /// the capacity of the buffer, the value used for the malloc call std::size_t m_size; /// size of the currently filled portion of the memory slab public: using SPtr = std::shared_ptr<ContigBuffer>; static std::size_t min_buffer_size; ......
—Reply to this email directly, view it on GitHub, or unsubscribe.You are receiving this because you are subscribed to this thread.Message ID: @.***>