Add mj_markStack and mj_freeStack as public API functions.

Also add asan instrumentation to detect stack frame leakages (i.e. `mj_markStack` without a corresponding `mj_freeStack` in the same caller function).

PiperOrigin-RevId: 562625645
Change-Id: I4e3ff66ca0b9d08ed0a95cef45393db8e3053e22
This commit is contained in:
Saran Tunyasuvunakool
2023-09-04 17:03:23 -07:00
committed by Copybara-Service
parent 9308e1d383
commit 94a8705ad0
17 changed files with 311 additions and 45 deletions
+19
View File
@@ -1232,6 +1232,25 @@ mj_resetDataKeyframe
Reset data, set fields from specified keyframe.
.. _mj_markStack:
mj_markStack
~~~~~~~~~~~~
.. mujoco-include:: mj_markStack
Mark a new frame on the :ref:`mjData` stack.
.. _mj_freeStack:
mj_freeStack
~~~~~~~~~~~~
.. mujoco-include:: mj_freeStack
Free the current :ref:`mjData` stack frame. All pointers returned by mj_stackAlloc since the last call
to mj_markStack must no longer be used afterwards.
.. _mj_stackAlloc:
mj_stackAlloc
+2
View File
@@ -43,6 +43,8 @@ General
functionality of allocating ``mjtNum`` arrays is still available through the new function :ref:`mj_stackAllocNum`.
#. Renamed the ``nstack`` field in :ref:`mjModel` and :ref:`mjData` to ``narena``. Changed ``narena``, ``pstack``, and
``maxuse_stack`` to count number of bytes rather than number of :ref:`mjtNum` |-| s.
#. Added new functions ``mj_markStack`` and ``mj_freeStack`` that manages ``mjData`` stack frames in a fully
encapsulated way (i.e. without having to introduce a local variable at the call site).
Python bindings
^^^^^^^^^^^^^^^
+3
View File
@@ -130,6 +130,7 @@ struct mjData_ {
// stack pointer
size_t pstack; // first available mjtNum address in stack
size_t pbase; // value of pstack when mj_markStack was last called
// arena pointer
size_t parena; // first available byte in arena
@@ -2205,6 +2206,8 @@ mjData* mj_copyData(mjData* dest, const mjModel* m, const mjData* src);
void mj_resetData(const mjModel* m, mjData* d);
void mj_resetDataDebug(const mjModel* m, mjData* d, unsigned char debug_value);
void mj_resetDataKeyframe(const mjModel* m, mjData* d, int key);
void mj_markStack(mjData* d);
void mj_freeStack(mjData* d);
void* mj_stackAlloc(mjData* d, size_t bytes, size_t alignment);
mjtNum* mj_stackAllocNum(mjData* d, int size);
int* mj_stackAllocInt(mjData* d, int size);