Explain why the child calls _exit() and not exit()

Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
This commit is contained in:
Gilles Peskine
2026-03-23 18:48:19 +01:00
parent 3d57272bbc
commit a5b6f6f778
2 changed files with 17 additions and 0 deletions
+2
View File
@@ -37,6 +37,8 @@ typedef void mbedtls_test_fork_child_callback_t(
* information (test result and failure location) is propagated to the
* parent.
*
* \note Memory leak detection is disabled in the child.
*
* \param child_callback Callback function to run in the child.
* \param param Parameter to pass to the callback function.
* \param[out] child_output On success, data retrieved from the child.
+15
View File
@@ -92,6 +92,21 @@ exit:
/* Label for `_exit()` call: this is where we jump to if the failure
* reporting fails. */
write_done:
/* We must call _exit(), not exit(), because the child must not run the
* things that normally run at exit.
*
* - Do not flush any stdio buffers! Any unflushed buffers are inherited
* from our parent, and if we flushed them, we'd get duplicate output
* since the parent would also write the same buffer content.
* - Do not run atexit hooks, e.g. leak detection code from sanitizers
* such as ASan. The child leaks any number of resources which are
* inherited from the parent but not used in the child. It's the
* parent's job to check for resource leaks.
* (We deliberately do not clean up in the child. One reason is that
* we try to minimize what happens in the child, because it's difficult
* to debug. Another reason is that we must not cause external effects
* such as destroying a PSA persistent key.)
*/
_exit(child_exit_code);
}