Skip to content
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

[c++] Make operators new and delete weak symbols by default #747

Merged
merged 2 commits into from
Oct 14, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
14 changes: 11 additions & 3 deletions examples/nucleo_g071rb/custom_allocator/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ extern "C" void* _sbrk_r(struct _reent *, ptrdiff_t size)
}
return (void*) heap;
}
extern "C" void operator_delete(void* ptr)
{
free(ptr);
}

// ----------------------------------------------------------------------------
int main()
Expand All @@ -47,17 +51,21 @@ int main()
traits.value, start, end, size);
}

void* ptr;
uint8_t* ptr;
size_t counter{0};
while (true)
{
LedD13::toggle();
modm::delay(200ms);

// leak memory until heap is exhausted
ptr = malloc(1024);
if (ptr) counter++;
ptr = new uint8_t[1024];
if (ptr) {
ptr[0] = counter;
counter++;
}
MODM_LOG_INFO << "Allocated " << counter << "kb of heap!" << modm::endl;
// delete ptr;
}

return 0;
Expand Down
3 changes: 2 additions & 1 deletion ext/gcc/module_c++.lb
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ or:

## AVR

A partial port of GCC 8 libstdc++ is provided:
A partial port of GCC libstdc++ is provided:
See https://github.com/modm-io/avr-libstdcpp.
"""

Expand Down Expand Up @@ -82,6 +82,7 @@ def build(env):
"with_exceptions": with_exceptions,
"with_threadsafe_statics": with_threadsafe_statics,
"with_memory_traits": env.has_module(":architecture:memory"),
"with_heap": env.has_module(":platform:heap"),
"is_avr": is_avr,
}
env.outbasepath = "modm/ext/gcc"
Expand Down
37 changes: 31 additions & 6 deletions ext/gcc/new_delete.cpp.in
Original file line number Diff line number Diff line change
Expand Up @@ -78,26 +78,51 @@ new_assert(size_t size)
}

// ----------------------------------------------------------------------------
modm_weak
void* operator new (std::size_t size) { return new_assert<false>(size); }
modm_weak
void* operator new[](std::size_t size) { return new_assert<false>(size); }

modm_weak
void* operator new (std::size_t size, const std::nothrow_t&) noexcept { return malloc(size); }
modm_weak
void* operator new[](std::size_t size, const std::nothrow_t&) noexcept { return malloc(size); }

%% if with_memory_traits
modm_weak
void* operator new (std::size_t size, modm::MemoryTraits traits) { return new_assert<true>(size, traits); }
modm_weak
void* operator new[](std::size_t size, modm::MemoryTraits traits) { return new_assert<true>(size, traits); }

modm_weak
void* operator new (std::size_t size, modm::MemoryTraits traits, const std::nothrow_t&) noexcept { return malloc_traits(size, traits.value); }
modm_weak
void* operator new[](std::size_t size, modm::MemoryTraits traits, const std::nothrow_t&) noexcept { return malloc_traits(size, traits.value); }
%% endif

// ----------------------------------------------------------------------------
void operator delete (void *ptr) noexcept { free(ptr); }
void operator delete[](void* ptr) noexcept { free(ptr); }
extern "C" modm_weak
void operator_delete(modm_unused void* ptr)
{
%% if with_heap
free(ptr);
%% else
modm_assert_continue_fail_debug(0, "delete",
"operator delete was called without heap implementation!", ptr);
%% endif
}
ASMfreaK marked this conversation as resolved.
Show resolved Hide resolved

modm_weak
void operator delete (void* ptr) noexcept { operator_delete(ptr); }
modm_weak
void operator delete[](void* ptr) noexcept { operator_delete(ptr); }

void operator delete (void* ptr, std::size_t) noexcept { free(ptr); }
void operator delete[](void* ptr, std::size_t) noexcept { free(ptr); }
modm_weak
void operator delete (void* ptr, std::size_t) noexcept { operator_delete(ptr); }
modm_weak
void operator delete[](void* ptr, std::size_t) noexcept { operator_delete(ptr); }

void operator delete (void* ptr, const std::nothrow_t&) noexcept { free(ptr); }
void operator delete[](void* ptr, const std::nothrow_t&) noexcept { free(ptr); }
modm_weak
void operator delete (void* ptr, const std::nothrow_t&) noexcept { operator_delete(ptr); }
modm_weak
void operator delete[](void* ptr, const std::nothrow_t&) noexcept { operator_delete(ptr); }
16 changes: 16 additions & 0 deletions src/modm/platform/heap/cortex/module.md
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,22 @@ extern "C" void* _sbrk_r(struct _reent *, ptrdiff_t size)
```


### Providing operator delete

Unfortunately virtual C++ destructors can emit a call to `operator delete` even
for classes with static allocation and also in program without a single call to
`operator new` or `malloc`. Therefore if this module is not included, calls to
`operator delete` are ignored and you must overwrite this behavior with this
function that only points to `free`.
salkinium marked this conversation as resolved.
Show resolved Hide resolved

```cpp
extern "C" void operator_delete(void* ptr)
{
free(ptr);
}
```


### Wrapping malloc

To use a completely custom allocator, you need to replace the newlib allocator
Expand Down