CHERIoT RTOS
A compartmentalised RTOS for CHERIoT hardware
Loading...
Searching...
No Matches
anonymous_namespace{debug.hh}::StackUsageCheck< Mode, Expected, Fn > Class Template Reference

Check the (dynamic) stack usage of a function, including all of its callees. More...

#include <debug.hh>

Public Member Functions

 StackUsageCheck ()=default
 Default constructor, does nothing.
 ~StackUsageCheck ()
 Destructor, runs at the end of the function to print the message.

Detailed Description

template<StackCheckMode Mode, size_t Expected, DebugContext Fn>
class anonymous_namespace{debug.hh}::StackUsageCheck< Mode, Expected, Fn >

Check the (dynamic) stack usage of a function, including all of its callees.

This is intended to be used in compartment entry points to check the stack size that is required for that entry point. Use this with some test vectors that explore different code paths to identify the maximum stack usage. This can then be used with the [[cheriot::minimum_stack]] attribute to ensure that the switcher will never invoke the entry point with insufficient stack.

Note that this records only the stack usage for the current compartment invocation (including any invoked shared libraries). If this compartment calls others, then a larger stack may be required. This failure is recoverable: cross-compartment calls should always be assumed to potentially fail. This check is to ensure that an attacker cannot cause stack overflow to crash the compartment, not to ensure that an attacker cannot cause stack overflow to make the operation that they requested fail.

Stack checks run in one of three modes:

  • Disabled: The checks do not run.
  • Logging: The checks run and print a message if the stack usage exceeds expectations.
  • Asserting: After printing the message, the function will trap.

In logging mode, one message will be printed for each invocation of the function that exceeds the previous maximum stack usage.

An instance of this should be created as a local variable on entry to a function. The destructor (which prints the message) will then run after any other destructors, ensuring the most accurate stack usage measurement.

Unfortunately, default arguments for templates are not evaluated in the enclosing scope and so __builtin_FUNCTION() cannot be used here. Instead, we must pass this explicitly, typically as something like:

Definition at line 1103 of file debug.hh.

Constructor & Destructor Documentation

◆ ~StackUsageCheck()

template<StackCheckMode Mode, size_t Expected, DebugContext Fn>
anonymous_namespace{debug.hh}::StackUsageCheck< Mode, Expected, Fn >::~StackUsageCheck ( )
inline

The documentation for this class was generated from the following file: