Skip to content

operator new: no exception without need for std::nothrow #6309

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 10 commits into from

Conversation

d-a-v
Copy link
Collaborator

@d-a-v d-a-v commented Jul 17, 2019

CLOSED

https://stackoverflow.com/questions/6049563/with-fno-exceptions-what-happens-with-new-t
operator new will never return nullptr.
Either we get an exception, or if everything is compiled with -fno-exception, abort() is called.

(was:)

Overloads operator new so it can return nullptr instead of throwing an exception without need for (std::nothrow).

Requirement: <Arduino.h> must be included prior to any c++ header file

addresses #6269 @mcspr @mhightower83

…of throwing an exception without (std::nothrow)
@d-a-v d-a-v requested review from earlephilhower and devyte July 17, 2019 09:22
@earlephilhower
Copy link
Collaborator

Interesting solution to the problem.

The standard libraries do not ever check the return value of new() != nullptr, they use a catch or they expect their code to stop and your upper lever code to have that catch(). There has been more than one bug where we find std::shared_ptr or some other compound type (which has elements that are new()ed) crashes with a stack trace after doing a new and trying to use the returned object.

Theoretically, it seems like this would let the std:: libs abort() on the failed new (since they should use the base new() and it will throw), and let user code use the broken nothrow new().

Copy link
Collaborator

@earlephilhower earlephilhower left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needs to set the last alloc addr/size on failure to help us debug crashes.

I'll try it out later today on some test cases, too, with and w/o exceptions...

#include <bits/c++config.h>
extern "C++" inline void* operator new (std::size_t size) noexcept
{
return malloc(size);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please check out the old new() and new override, it sets the last-failed-alloc address which this needs to do as well:

void *operator new(size_t size)
{
void *ret = malloc(size);
if (0 != size && 0 == ret) {
umm_last_fail_alloc_addr = __builtin_return_address(0);
umm_last_fail_alloc_size = size;
}
return ret;
}
void *operator new[](size_t size)
{
void *ret = malloc(size);
if (0 != size && 0 == ret) {
umm_last_fail_alloc_addr = __builtin_return_address(0);
umm_last_fail_alloc_size = size;
}
return ret;
}

@d-a-v
Copy link
Collaborator Author

d-a-v commented Jul 17, 2019

This is a hack.

Remove noexcept or move #include <new> before these definitions, and constructors will be called no matter what.

@earlephilhower
Copy link
Collaborator

For reference the prior new override was handled here:
https://github.com/esp8266/Arduino/blob/2.4.2/cores/esp8266/abi.cpp

@d-a-v d-a-v requested a review from earlephilhower July 18, 2019 12:40
@d-a-v d-a-v closed this Jul 18, 2019
earlephilhower added a commit to earlephilhower/Arduino that referenced this pull request Jul 18, 2019
Default mode (no exceptions) will no longer use the stdc++ library new
allocator when there is not enough memory.  Instead, it will return
nullptr.  This is the pre-exceptions-available behavior (2.5.0 and
earlier).

When exceptions are enabled, use the real new and throw exceptions that
can be caught at higher levels, or which will crash the app with an
uncaught exception if they're not handled.

Update to esp8266#6309
d-a-v pushed a commit to d-a-v/Arduino that referenced this pull request Jul 23, 2019
Default mode (no exceptions) will no longer use the stdc++ library new
allocator when there is not enough memory.  Instead, it will return
nullptr.  This is the pre-exceptions-available behavior (2.5.0 and
earlier).

When exceptions are enabled, use the real new and throw exceptions that
can be caught at higher levels, or which will crash the app with an
uncaught exception if they're not handled.

Update to esp8266#6309
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants