Fixture's destructor called before retrieving uncaught exception's message
- Dominant language
- C++
- Stars
- 21.5k
- Forks
- 3.5k
- Avg merge
- 3d 16h
- Merged PRs (30d)
- 2
Description
I have a unit test project in which exceptions rely on test fixture's state. This can lead to use-after-free situations, because uncaught exception objects can outlive fixture. Following code illustrates the problem:
```cpp
#include
#include
#include
struct Context
{
Context() { std::cout << "Context::Context\n"; }
~Context() { std::cout << "Context::~Context\n"; }
};
struct ErrorUsingContext : std::exception
{
ErrorUsingContext(Context&) { std::cout << "ErrorUsingContext::ErrorUsingContext\n"; }
~ErrorUsingContext() { std::cout << "ErrorUsingContext::~ErrorUsingContext\n"; }
const char* what() const noexcept override
{
std::cout << "ErrorUsingContext::what\n";
return "description allocated and managed by Context";
}
};
struct Test
{
Context ctx;
};
TEST_CASE_METHOD(Test, "Test")
{
throw ErrorUsingContext(ctx);
}
```
Godbolt: https://godbolt.org/z/xf3x65rhe
Output:
```
Context::Context
ErrorUsingContext::ErrorUsingContext
Context::~Context
ErrorUsingContext::what
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
output.s is a Catch v3.0.0-preview.3 host application.
Run with -? for options
-------------------------------------------------------------------------------
Test
-------------------------------------------------------------------------------
/app/example.cpp:32
...............................................................................
/app/example.cpp:32: FAILED:
due to unexpected exception with message:
description allocated and managed by Context
ErrorUsingContext::~ErrorUsingContext
===============================================================================
test cases: 1 | 1 failed
assertions: 1 | 1 failed
```
`ErrorUsingContext::what` is called after `Context::~Context` which is a problem for me, because, in my case, memory of exception's description string is allocated and managed by the `Context` (strings use custom allocators).
I can work around it, but this could be avoided if uncaught exceptions' description were retrieved and saved by Catch2 before calling fixture's destructor.
Contributor guide
Research direction
Start by reproducing the issue with the provided TEST_CASE_METHOD example and trace Catch2's fixture teardown and unexpected-exception reporting paths. Done means the exception message is retrieved before the fixture is destroyed, with a regression test covering an exception whose what() depends on fixture state.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- testing
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100