Skip to content

unittests/unicoap: statically allocate option buffers #21610

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
Jul 24, 2025

Conversation

mguetschow
Copy link
Contributor

@mguetschow mguetschow commented Jul 17, 2025

Contribution description

unicoap unittests would currently fail due to stack overflow on most hardware. They indeed allocate much more memory than needed.

The default unittest stacksize is set to THREAD_STACKSIZE_LARGE which is 2048 for cortexm_common, so 900 bytes will largely fit. However, some other architectures (e.g., atmega8) define much smaller stack sizes per default, where the reduced buffer would not fit. Should we rather make them static so they work for all architectures? We then wouldn't be able to use the convenience macro anymore.

EDIT: Changed to statically allocated buffers now using a new convenience macro UNICOAP_OPTIONS_ALLOC_STATIC.

Testing procedure

make -C tests/unittests BOARD=nrf52840dk tests-unicoap flash term

on master:

Welcome to pyterm!
Type '/exit' to exit.
r
2025-07-17 14:28:14,931 # READY
s
2025-07-17 14:28:16,637 # START
2025-07-17 14:28:16,643 # main(): This is RIOT! (Version: 2025.07-devel-571-gd06b6)
2025-07-17 14:28:16,648 # Help: Press s to start test, r to print it is ready

with this PR:

Welcome to pyterm!
Type '/exit' to exit.
r
2025-07-17 14:26:48,657 # READY
s
2025-07-17 14:26:49,469 # START
2025-07-17 14:26:49,471 # ................
2025-07-17 14:26:49,473 # OK (16 tests)

Issues/PRs references

Found while testing #21582

the default unittest stacksize is set to THREAD_STACKSIZE_LARGE which is 2048 for cortexm_common
@mguetschow mguetschow requested a review from miri64 as a code owner July 17, 2025 12:30
@mguetschow mguetschow requested review from carl-tud and removed request for miri64 July 17, 2025 12:30
@github-actions github-actions bot added the Area: tests Area: tests and testing framework label Jul 17, 2025
Copy link
Contributor

@carl-tud carl-tud left a comment

Choose a reason for hiding this comment

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

Thanks, this was my mistake.
For anyone else wondering: The size of the options buffer allocated should be slightly (well, maybe not by 1.3 KB) larger than needed so tests where unicoap writes too much into buffer can fail gracefully instead of memfaulting immediately.

@carl-tud
Copy link
Contributor

carl-tud commented Jul 17, 2025

As a quick fix for making the tests run, modifying the buffer size is the right thing to do.
I think I should a add a macro UNICOAP_OPTIONS_ALLOC_STATIC for these instances. These buffer should've been static from the get-go.

@mguetschow
Copy link
Contributor Author

As a quick fix for making the tests run, modifying the buffer size is the right thing to do. I think I should a add a macro UNICOAP_OPTIONS_ALLOC_STATIC for these instances. These buffer should've been static from the get-go.

Should I adapt the PR to provide that macro instead? Much cleaner solution indeed.

@carl-tud
Copy link
Contributor

carl-tud commented Jul 17, 2025

Okay, then we have two options:

// 1
UNICOAP_OPTIONS_ALLOC_STATIC(my_options, 100);

// or 
// 2
UNICOAP_OPTIONS_ALLOC(my_options, 100, static);

I think I would prefer 2 over 1.

@mguetschow
Copy link
Contributor Author

I'd prefer 1, but that's probably more personal taste.

@carl-tud
Copy link
Contributor

@miri64

@github-actions github-actions bot added Area: network Area: Networking Area: CoAP Area: Constrained Application Protocol implementations Area: sys Area: System labels Jul 17, 2025
@crasbe crasbe added Type: bug The issue reports a bug / The PR fixes a bug (including spelling errors) CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR labels Jul 17, 2025
@@ -193,7 +193,21 @@ static inline void unicoap_options_clear(unicoap_options_t* options)
* the given capacity, then calls @ref unicoap_options_t::unicoap_options_init.
*/
#define UNICOAP_OPTIONS_ALLOC(name, capacity) \
_UNICOAP_OPTIONS_ALLOC(_CONCAT3(name, _storage, __LINE__), name, capacity)
_UNICOAP_OPTIONS_ALLOC(_CONCAT3(name, _storage, __LINE__), name, capacity,)
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
_UNICOAP_OPTIONS_ALLOC(_CONCAT3(name, _storage, __LINE__), name, capacity,)
_UNICOAP_OPTIONS_ALLOC(_CONCAT3(name, _storage, __LINE__), name, capacity)

I guess?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No, in that case we don't want to emit anything before the type (aka, no static).

unicoap_options_t _name; \
# define _UNICOAP_OPTIONS_ALLOC(_buf, _name, capacity, _static) \
_static uint8_t _buf[capacity]; \
unicoap_options_t _name; \
unicoap_options_init(&_name, _buf, capacity);
Copy link
Contributor

Choose a reason for hiding this comment

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

1, I think the static version should work on the root level of a translation unit, too. So I fear we have to replace unicoap_options_init with unicoap_options_t _name = { .entries->data = _buf, .storage_capacity = capacity };

3, And why wouldn't we want to statically allocate the unicoap_options_t, too? Is there a good reason not to? It would make sense because of the lookup array in the options.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

  1. Good point, adapted it accordingly. Note that I do the same for both _STATIC and non-static, with the slight difference that more memory will be zero-initialized for the non-static version compared to using the unicoap_options_init function. But it keeps the macros in sync.

  2. Sure, would make sense, especially if used outside of functions. Adapted.

@riot-ci
Copy link

riot-ci commented Jul 17, 2025

Murdock results

✔️ PASSED

8623772 unittests/unicoap: statically allocate option buffers

Success Failures Total Runtime
10525 0 10525 11m:01s

Artifacts

@mguetschow
Copy link
Contributor Author

I've also added UNICOAP_OPTIONS_ALLOC_STATIC_DEFAULT akin to UNICOAP_OPTIONS_ALLOC_DEFAULT.

@carl-tud
Copy link
Contributor

maybe you could update the pr description to reflect the change

@mguetschow mguetschow changed the title unittests/unicoap: reduce buffer size to fit on stack unittests/unicoap: statically allocate option buffers Jul 18, 2025
@mguetschow
Copy link
Contributor Author

maybe you could update the pr description to reflect the change

Done.

@mguetschow mguetschow added the Process: needs backport Integration Process: The PR is required to be backported to a release or feature branch label Jul 23, 2025
@mguetschow
Copy link
Contributor Author

Sorry, had forgotten to push 🙈 please tell me when to squash

Copy link
Contributor

@Teufelchen1 Teufelchen1 left a comment

Choose a reason for hiding this comment

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

I somewhat wonder if the macros are worth the hassle...

@Teufelchen1
Copy link
Contributor

Yes squash please

@mguetschow mguetschow force-pushed the unicoap-test-stack-overflow branch from dd80c05 to 64352cb Compare July 24, 2025 09:18
@Teufelchen1
Copy link
Contributor

@carl-tud is your review done?

Copy link
Contributor

@carl-tud carl-tud left a comment

Choose a reason for hiding this comment

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

Looks good, thanks.

@Teufelchen1 Teufelchen1 added this pull request to the merge queue Jul 24, 2025
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Jul 24, 2025
@crasbe crasbe added this pull request to the merge queue Jul 24, 2025
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Jul 24, 2025
@Teufelchen1
Copy link
Contributor

Please run dist/tools/insufficient_memory/update_insufficient_memory_board.sh :>

@mguetschow
Copy link
Contributor Author

@crasbe would you mind checking for the necessary Makefile.ci content?

@crasbe
Copy link
Contributor

crasbe commented Jul 24, 2025

@crasbe would you mind checking for the necessary Makefile.ci content?

Already on it :)

@crasbe
Copy link
Contributor

crasbe commented Jul 24, 2025

buechse@skyleaf:~/RIOTstuff/riot-unicoap/RIOT/tests/unittests$ git diff Makefile.ci
diff --git a/tests/unittests/Makefile.ci b/tests/unittests/Makefile.ci
index 3490841797..6e9fdfedef 100644
--- a/tests/unittests/Makefile.ci
+++ b/tests/unittests/Makefile.ci
@@ -79,6 +79,7 @@ BOARD_INSUFFICIENT_MEMORY := \
     pba-d-01-kw2x \
     remote-pa \
     remote-reva \
+    remote-revb \
     samd10-xmini \
     samd20-xpro \
     samd21-xpro \

@crasbe
Copy link
Contributor

crasbe commented Jul 24, 2025

So annoying that it failed at the last minute...

@mguetschow mguetschow force-pushed the unicoap-test-stack-overflow branch from 64352cb to 8623772 Compare July 24, 2025 13:58
@mguetschow
Copy link
Contributor Author

Should run through now 🙏

@mguetschow mguetschow enabled auto-merge July 24, 2025 13:59
@mguetschow mguetschow added this pull request to the merge queue Jul 24, 2025
Merged via the queue into RIOT-OS:master with commit f572bbe Jul 24, 2025
25 checks passed
@mguetschow mguetschow deleted the unicoap-test-stack-overflow branch July 24, 2025 22:29
@mguetschow
Copy link
Contributor Author

Backport provided in #21622

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area: CoAP Area: Constrained Application Protocol implementations Area: network Area: Networking Area: sys Area: System Area: tests Area: tests and testing framework CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR Process: needs backport Integration Process: The PR is required to be backported to a release or feature branch Type: bug The issue reports a bug / The PR fixes a bug (including spelling errors)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants