Skip to content

Fix that malloc() doesn't return a null pointer for too large allocations #117

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

Merged
merged 3 commits into from
Sep 4, 2023
Merged

Conversation

alrvid
Copy link
Contributor

@alrvid alrvid commented Aug 31, 2023

The _sbrk() function wasn't implemented. It's used by malloc() to request more heap memory. This function must be defined and correctly implemented if we want malloc() to return a null pointer if more space is requested than is available. It already works that way for the Mbed Core (although with a different implementation), but doesn't for the Renesas Core before this addition.

…ions

The _sbrk() function wasn't implemented. It's used by malloc() to request more heap memory. This function must be defined and correctly implemented if we want malloc() to return a null pointer if more space is requested than is available. It already works that way for the Mbed Core (although with a different implementation), but doesn't for the Renesas Core before this addition.
@alrvid alrvid requested a review from facchinm August 31, 2023 13:20
@facchinm
Copy link
Member

@alrvid I think we are already including this implementation of sbrk() https://github.com/renesas/fsp/blob/master/ra/fsp/src/bsp/mcu/all/bsp_sbrk.c#L68-L102 . Isn't that implementation ok?

@alrvid
Copy link
Contributor Author

alrvid commented Aug 31, 2023

Interesting, because when I call malloc() with very large requests I get a non-null pointer back, and when I add my fix I get a null pointer back. So I assumed that you hadn't implemented it. There must be something else going wrong then, because malloc() doesn't work correctly in this aspect. I've tried it on both the C33 and the Uno R4 with the same result.

@per1234 per1234 added type: imperfection Perceived defect in any part of project topic: code Related to content of the project itself labels Aug 31, 2023
@KurtE
Copy link
Contributor

KurtE commented Sep 1, 2023

Sorry for butting in, but was curious.

Quick comments:
The current code keeps allocations as a multiple of 4 bytes,

caddr_t _sbrk (int incr)
...
    uint32_t      bytes            = (uint32_t) incr;
...
    bytes = (bytes + 3U) & (~3U);
    if (current_heap_end + bytes > &_Heap_Limit)

Code in PR does not round up:

extern "C" void * _sbrk(ptrdiff_t change)
...
if ((programBreak + change) > &__HeapLimit)

Not sure why new one would detect it and the old one did not?

They do have different parameter types: int versus ptrdiff_t
Wish the current code had parentheses...
if ((current_heap_end + bytes) > &_Heap_Limit)
But doubt that is the issue.

This function isn't necessary when the root cause is fixed in the next commit.
The malloc() function doesn't return a null pointer for too large requests. The cause is that the _sbrk() function isn't linked from the Renesas FSP as it should be, but instead from the Arm toolchain. This fix makes sure that the correct version of _sbrk() is linked.
@alrvid
Copy link
Contributor Author

alrvid commented Sep 2, 2023

The issue was that the _sbrk() function from the Renesas FSP wasn't linked as it should. Instead, we got a _sbrk() from the Arm toolchain. Since both these come from .a files, my first fix solved it by overriding the Arm toolchain version (coming from an .o file at link time). But this new fix solves the root cause, and the old one is no longer necessary.

@alrvid
Copy link
Contributor Author

alrvid commented Sep 2, 2023

Another option would be to use -Wl,--undefined=_sbrk because that would link in less extra stuff and not increase the memory consumption so much. But my solution in the PR might have other benefits. Which one do you prefer @facchinm? I can change to -Wl,--undefined=_sbrk if you want me to.

@facchinm
Copy link
Member

facchinm commented Sep 4, 2023

I love the final solution, thank you so much! Merging!

@facchinm facchinm merged commit e53cacb into arduino:main Sep 4, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
topic: code Related to content of the project itself type: imperfection Perceived defect in any part of project
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants