Move sanitizer instrumentation to a separate header file. Fixes #2049.

PiperOrigin-RevId: 672986547
Change-Id: I42522f4925237a73168e965364a2dd65c0f067cb
This commit is contained in:
Yuval Tassa
2024-09-10 09:04:19 -07:00
committed by Copybara-Service
parent 8fa7fe7f5b
commit e4d4153352
27 changed files with 89 additions and 45 deletions
+1
View File
@@ -59,6 +59,7 @@ set(MUJOCO_HEADERS
include/mujoco/mjmodel.h include/mujoco/mjmodel.h
include/mujoco/mjplugin.h include/mujoco/mjplugin.h
include/mujoco/mjrender.h include/mujoco/mjrender.h
include/mujoco/mjsan.h
include/mujoco/mjspec.h include/mujoco/mjspec.h
include/mujoco/mjthread.h include/mujoco/mjthread.h
include/mujoco/mjtnum.h include/mujoco/mjtnum.h
+6 -4
View File
@@ -148,6 +148,10 @@ links below, to make this documentation self-contained.
Defines MuJoCo's ``mjtNum`` floating-point type to be either ``double`` or ``float``. See :ref:`mjtNum`. Defines MuJoCo's ``mjtNum`` floating-point type to be either ``double`` or ``float``. See :ref:`mjtNum`.
`mjspec.h <https://github.com/google-deepmind/mujoco/blob/main/include/mujoco/mjspec.h>`__ `mjspec.h <https://github.com/google-deepmind/mujoco/blob/main/include/mujoco/mjspec.h>`__
Defines enums and structs used for :doc:`procedural model editing <modeledit>`. Defines enums and structs used for :doc:`procedural model editing <modeledit>`.
`mjplugin.h <https://github.com/google-deepmind/mujoco/blob/main/include/mujoco/mjplugin.h>`__
Defines data structures required by :ref:`engine plugins<exPlugin>`.
`mjthread.h <https://github.com/google-deepmind/mujoco/blob/main/include/mujoco/mjthread.h>`__
Defines data structures and functions required by :ref:`thread<Thread>`.
`mjmacro.h <https://github.com/google-deepmind/mujoco/blob/main/include/mujoco/mjmacro.h>`__ `mjmacro.h <https://github.com/google-deepmind/mujoco/blob/main/include/mujoco/mjmacro.h>`__
Defines C macros that are useful in user code. Defines C macros that are useful in user code.
`mjxmacro.h <https://github.com/google-deepmind/mujoco/blob/main/include/mujoco/mjxmacro.h>`__ `mjxmacro.h <https://github.com/google-deepmind/mujoco/blob/main/include/mujoco/mjxmacro.h>`__
@@ -157,10 +161,8 @@ links below, to make this documentation self-contained.
`mjexport.h <https://github.com/google-deepmind/mujoco/blob/main/include/mujoco/mjexport.h>`__ `mjexport.h <https://github.com/google-deepmind/mujoco/blob/main/include/mujoco/mjexport.h>`__
Macros used for exporting public symbols from the MuJoCo library. This header should not be used directly by client Macros used for exporting public symbols from the MuJoCo library. This header should not be used directly by client
code. code.
`mjplugin.h <https://github.com/google-deepmind/mujoco/blob/main/include/mujoco/mjplugin.h>`__ `mjsan.h <https://github.com/google-deepmind/mujoco/blob/main/include/mujoco/mjsan.h>`__
Defines data structures required by :ref:`engine plugins<exPlugin>`. Definitions required when building with sanitizer instrumentation.
`mjthread.h <https://github.com/google-deepmind/mujoco/blob/main/include/mujoco/mjthread.h>`__
Defines data structures and functions required by :ref:`thread<Thread>`.
.. _inVersion: .. _inVersion:
-11
View File
@@ -15,17 +15,6 @@
#ifndef MUJOCO_MJMACRO_H_ #ifndef MUJOCO_MJMACRO_H_
#define MUJOCO_MJMACRO_H_ #define MUJOCO_MJMACRO_H_
// include asan interface header, or provide stubs for poison/unpoison macros when not using asan
#ifdef ADDRESS_SANITIZER
#include <sanitizer/asan_interface.h>
#elif defined(_MSC_VER)
#define ASAN_POISON_MEMORY_REGION(addr, size)
#define ASAN_UNPOISON_MEMORY_REGION(addr, size)
#else
#define ASAN_POISON_MEMORY_REGION(addr, size) ((void)(addr), (void)(size))
#define ASAN_UNPOISON_MEMORY_REGION(addr, size) ((void)(addr), (void)(size))
#endif
// max and min (use only for primitive types) // max and min (use only for primitive types)
#define mjMAX(a, b) (((a) > (b)) ? (a) : (b)) #define mjMAX(a, b) (((a) > (b)) ? (a) : (b))
#define mjMIN(a, b) (((a) < (b)) ? (a) : (b)) #define mjMIN(a, b) (((a) < (b)) ? (a) : (b))
+58
View File
@@ -0,0 +1,58 @@
// Copyright 2024 DeepMind Technologies Limited
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef MUJOCO_INCLUDE_MJSAN_H_
#define MUJOCO_INCLUDE_MJSAN_H_
// Include asan interface header, or provide stubs for poison/unpoison macros when not using asan.
#ifdef ADDRESS_SANITIZER
#include <sanitizer/asan_interface.h>
#elif defined(_MSC_VER)
#define ASAN_POISON_MEMORY_REGION(addr, size)
#define ASAN_UNPOISON_MEMORY_REGION(addr, size)
#else
#define ASAN_POISON_MEMORY_REGION(addr, size) ((void)(addr), (void)(size))
#define ASAN_UNPOISON_MEMORY_REGION(addr, size) ((void)(addr), (void)(size))
#endif
// When built and run under address sanitizer (asan), mj_markStack and mj_freeStack are instrumented
// to detect leakage of mjData stack frames. When the compiler inlines several callees that call
// into mark/free into the same function, this instrumentation requires that the compiler retains
// separate mark/free calls for each original callee. The memory-clobbered asm blocks act as a
// barrier to prevent mark/free calls from being combined under optimization.
#ifdef ADDRESS_SANITIZER
#ifdef __cplusplus
extern "C" {
#endif
void mj__markStack(mjData*) __attribute__((noinline));
static inline void mj_markStack(mjData* d) __attribute__((always_inline)) {
asm volatile("" ::: "memory");
mj__markStack(d);
asm volatile("" ::: "memory");
}
void mj__freeStack(mjData*) __attribute__((noinline));
static inline void mj_freeStack(mjData* d) __attribute__((always_inline)) {
asm volatile("" ::: "memory");
mj__freeStack(d);
asm volatile("" ::: "memory");
}
#ifdef __cplusplus
}
#endif // __cplusplus
#endif // ADDRESS_SANITIZER
#endif // MUJOCO_INCLUDE_MJSAN_H_
+2 -30
View File
@@ -29,6 +29,7 @@
#include <mujoco/mjmacro.h> #include <mujoco/mjmacro.h>
#include <mujoco/mjplugin.h> #include <mujoco/mjplugin.h>
#include <mujoco/mjrender.h> #include <mujoco/mjrender.h>
#include <mujoco/mjsan.h>
#include <mujoco/mjspec.h> #include <mujoco/mjspec.h>
#include <mujoco/mjthread.h> #include <mujoco/mjthread.h>
#include <mujoco/mjtnum.h> #include <mujoco/mjtnum.h>
@@ -197,7 +198,7 @@ MJAPI void mj_resetDataDebug(const mjModel* m, mjData* d, unsigned char debug_va
// Reset data. If 0 <= key < nkey, set fields from specified keyframe. // Reset data. If 0 <= key < nkey, set fields from specified keyframe.
MJAPI void mj_resetDataKeyframe(const mjModel* m, mjData* d, int key); MJAPI void mj_resetDataKeyframe(const mjModel* m, mjData* d, int key);
#ifndef ADDRESS_SANITIZER #ifndef ADDRESS_SANITIZER // Stack management functions declared in mjsan.h if ASAN is active.
// Mark a new frame on the mjData stack. // Mark a new frame on the mjData stack.
MJAPI void mj_markStack(mjData* d); MJAPI void mj_markStack(mjData* d);
@@ -1766,35 +1767,6 @@ MJAPI void mjs_defaultKey(mjsKey* key);
// Default plugin attributes. // Default plugin attributes.
MJAPI void mjs_defaultPlugin(mjsPlugin* plugin); MJAPI void mjs_defaultPlugin(mjsPlugin* plugin);
//---------------------------------- Sanitizer instrumentation -------------------------------------
// Most users can ignore these functions, the following comments are primarily for developers.
//
// When built and run under address sanitizer (asan), mj_markStack and mj_freeStack are instrumented
// to detect leakage of mjData stack frames. When the compiler inlines several callees that call
// into mark/free into the same function, this instrumentation requires that the compiler retains
// separate mark/free calls for each original callee. The memory-clobbered asm blocks act as a
// barrier to prevent mark/free calls from being combined under optimization.
#ifdef ADDRESS_SANITIZER
void mj__markStack(mjData*) __attribute__((noinline));
static inline void mj_markStack(mjData* d) __attribute__((always_inline)) {
asm volatile("" ::: "memory");
mj__markStack(d);
asm volatile("" ::: "memory");
}
void mj__freeStack(mjData*) __attribute__((noinline));
static inline void mj_freeStack(mjData* d) __attribute__((always_inline)) {
asm volatile("" ::: "memory");
mj__freeStack(d);
asm volatile("" ::: "memory");
}
#endif // ADDRESS_SANITIZER
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
+1
View File
@@ -21,6 +21,7 @@
#include <mujoco/mjdata.h> #include <mujoco/mjdata.h>
#include <mujoco/mjmacro.h> #include <mujoco/mjmacro.h>
#include <mujoco/mjmodel.h> #include <mujoco/mjmodel.h>
#include <mujoco/mjsan.h> // IWYU pragma: keep
#include "engine/engine_callback.h" #include "engine/engine_callback.h"
#include "engine/engine_collision_convex.h" #include "engine/engine_collision_convex.h"
#include "engine/engine_collision_primitive.h" #include "engine/engine_collision_primitive.h"
+1
View File
@@ -19,6 +19,7 @@
#include <mujoco/mjdata.h> #include <mujoco/mjdata.h>
#include <mujoco/mjmodel.h> #include <mujoco/mjmodel.h>
#include <mujoco/mjsan.h> // IWYU pragma: keep
#include <mujoco/mjtnum.h> #include <mujoco/mjtnum.h>
#include "engine/engine_collision_primitive.h" #include "engine/engine_collision_primitive.h"
#include "engine/engine_io.h" #include "engine/engine_io.h"
+1
View File
@@ -20,6 +20,7 @@
#include <mujoco/mjdata.h> #include <mujoco/mjdata.h>
#include <mujoco/mjmacro.h> #include <mujoco/mjmacro.h>
#include <mujoco/mjmodel.h> #include <mujoco/mjmodel.h>
#include <mujoco/mjsan.h> // IWYU pragma: keep
#include <mujoco/mjxmacro.h> #include <mujoco/mjxmacro.h>
#include "engine/engine_core_smooth.h" #include "engine/engine_core_smooth.h"
#include "engine/engine_io.h" #include "engine/engine_io.h"
+1
View File
@@ -20,6 +20,7 @@
#include <mujoco/mjdata.h> #include <mujoco/mjdata.h>
#include <mujoco/mjmacro.h> #include <mujoco/mjmacro.h>
#include <mujoco/mjmodel.h> #include <mujoco/mjmodel.h>
#include <mujoco/mjsan.h> // IWYU pragma: keep
#include "engine/engine_core_constraint.h" #include "engine/engine_core_constraint.h"
#include "engine/engine_crossplatform.h" #include "engine/engine_crossplatform.h"
#include "engine/engine_io.h" #include "engine/engine_io.h"
+1
View File
@@ -16,6 +16,7 @@
#include <mujoco/mjdata.h> #include <mujoco/mjdata.h>
#include <mujoco/mjmodel.h> #include <mujoco/mjmodel.h>
#include <mujoco/mjsan.h> // IWYU pragma: keep
#include "engine/engine_core_constraint.h" #include "engine/engine_core_constraint.h"
#include "engine/engine_crossplatform.h" #include "engine/engine_crossplatform.h"
#include "engine/engine_io.h" #include "engine/engine_io.h"
+1
View File
@@ -20,6 +20,7 @@
#include <mujoco/mjdata.h> #include <mujoco/mjdata.h>
#include <mujoco/mjmacro.h> #include <mujoco/mjmacro.h>
#include <mujoco/mjmodel.h> #include <mujoco/mjmodel.h>
#include <mujoco/mjsan.h> // IWYU pragma: keep
#include "engine/engine_forward.h" #include "engine/engine_forward.h"
#include "engine/engine_io.h" #include "engine/engine_io.h"
#include "engine/engine_inverse.h" #include "engine/engine_inverse.h"
+1
View File
@@ -20,6 +20,7 @@
#include <mujoco/mjdata.h> #include <mujoco/mjdata.h>
#include <mujoco/mjmacro.h> #include <mujoco/mjmacro.h>
#include <mujoco/mjmodel.h> #include <mujoco/mjmodel.h>
#include <mujoco/mjsan.h> // IWYU pragma: keep
#include <mujoco/mjplugin.h> #include <mujoco/mjplugin.h>
#include "engine/engine_callback.h" #include "engine/engine_callback.h"
#include "engine/engine_collision_driver.h" #include "engine/engine_collision_driver.h"
+1
View File
@@ -19,6 +19,7 @@
#include <mujoco/mjdata.h> #include <mujoco/mjdata.h>
#include <mujoco/mjmacro.h> #include <mujoco/mjmacro.h>
#include <mujoco/mjmodel.h> #include <mujoco/mjmodel.h>
#include <mujoco/mjsan.h> // IWYU pragma: keep
#include "engine/engine_collision_driver.h" #include "engine/engine_collision_driver.h"
#include "engine/engine_core_constraint.h" #include "engine/engine_core_constraint.h"
#include "engine/engine_core_smooth.h" #include "engine/engine_core_smooth.h"
+1
View File
@@ -25,6 +25,7 @@
#include <mujoco/mjmodel.h> #include <mujoco/mjmodel.h>
#include <mujoco/mjmacro.h> #include <mujoco/mjmacro.h>
#include <mujoco/mjplugin.h> #include <mujoco/mjplugin.h>
#include <mujoco/mjsan.h> // IWYU pragma: keep
#include <mujoco/mjxmacro.h> #include <mujoco/mjxmacro.h>
#include "engine/engine_crossplatform.h" #include "engine/engine_crossplatform.h"
#include "engine/engine_macro.h" #include "engine/engine_macro.h"
+1
View File
@@ -19,6 +19,7 @@
#include <mujoco/mjdata.h> #include <mujoco/mjdata.h>
#include <mujoco/mjmodel.h> #include <mujoco/mjmodel.h>
#include <mujoco/mjsan.h> // IWYU pragma: keep
#include <mujoco/mjxmacro.h> #include <mujoco/mjxmacro.h>
#include "engine/engine_core_constraint.h" #include "engine/engine_core_constraint.h"
#include "engine/engine_io.h" #include "engine/engine_io.h"
+1
View File
@@ -22,6 +22,7 @@
#include <mujoco/mjdata.h> #include <mujoco/mjdata.h>
#include <mujoco/mjmacro.h> #include <mujoco/mjmacro.h>
#include <mujoco/mjmodel.h> #include <mujoco/mjmodel.h>
#include <mujoco/mjsan.h> // IWYU pragma: keep
#include <mujoco/mjxmacro.h> #include <mujoco/mjxmacro.h>
#include "engine/engine_core_constraint.h" #include "engine/engine_core_constraint.h"
#include "engine/engine_io.h" #include "engine/engine_io.h"
+1
View File
@@ -21,6 +21,7 @@
#include <mujoco/mjdata.h> #include <mujoco/mjdata.h>
#include <mujoco/mjmacro.h> #include <mujoco/mjmacro.h>
#include <mujoco/mjmodel.h> #include <mujoco/mjmodel.h>
#include <mujoco/mjsan.h> // IWYU pragma: keep
#include <mujoco/mjvisualize.h> #include <mujoco/mjvisualize.h>
#include "engine/engine_io.h" #include "engine/engine_io.h"
#include "engine/engine_plugin.h" #include "engine/engine_plugin.h"
+1
View File
@@ -19,6 +19,7 @@
#include <mujoco/mjdata.h> #include <mujoco/mjdata.h>
#include <mujoco/mjmodel.h> #include <mujoco/mjmodel.h>
#include <mujoco/mjplugin.h> #include <mujoco/mjplugin.h>
#include <mujoco/mjsan.h> // IWYU pragma: keep
#include "engine/engine_callback.h" #include "engine/engine_callback.h"
#include "engine/engine_core_smooth.h" #include "engine/engine_core_smooth.h"
#include "engine/engine_crossplatform.h" #include "engine/engine_crossplatform.h"
+1
View File
@@ -20,6 +20,7 @@
#include <mujoco/mjdata.h> #include <mujoco/mjdata.h>
#include <mujoco/mjmacro.h> #include <mujoco/mjmacro.h>
#include <mujoco/mjmodel.h> #include <mujoco/mjmodel.h>
#include <mujoco/mjsan.h> // IWYU pragma: keep
#include "engine/engine_core_constraint.h" #include "engine/engine_core_constraint.h"
#include "engine/engine_core_smooth.h" #include "engine/engine_core_smooth.h"
#include "engine/engine_forward.h" #include "engine/engine_forward.h"
+1
View File
@@ -20,6 +20,7 @@
#include <mujoco/mjdata.h> #include <mujoco/mjdata.h>
#include <mujoco/mjmacro.h> #include <mujoco/mjmacro.h>
#include <mujoco/mjmodel.h> #include <mujoco/mjmodel.h>
#include <mujoco/mjsan.h> // IWYU pragma: keep
#include "engine/engine_core_constraint.h" #include "engine/engine_core_constraint.h"
#include "engine/engine_core_smooth.h" #include "engine/engine_core_smooth.h"
#include "engine/engine_io.h" #include "engine/engine_io.h"
+1
View File
@@ -19,6 +19,7 @@
#include <mujoco/mjdata.h> #include <mujoco/mjdata.h>
#include <mujoco/mjmodel.h> #include <mujoco/mjmodel.h>
#include <mujoco/mjsan.h> // IWYU pragma: keep
#include "engine/engine_collision_driver.h" #include "engine/engine_collision_driver.h"
#include "engine/engine_core_constraint.h" #include "engine/engine_core_constraint.h"
#include "engine/engine_crossplatform.h" #include "engine/engine_crossplatform.h"
+1
View File
@@ -19,6 +19,7 @@
#include <mujoco/mjdata.h> #include <mujoco/mjdata.h>
#include <mujoco/mjmacro.h> #include <mujoco/mjmacro.h>
#include <mujoco/mjsan.h> // IWYU pragma: keep
#include "engine/engine_io.h" #include "engine/engine_io.h"
#include "engine/engine_util_blas.h" #include "engine/engine_util_blas.h"
#include "engine/engine_util_errmem.h" #include "engine/engine_util_errmem.h"
+1
View File
@@ -18,6 +18,7 @@
#include <string.h> #include <string.h>
#include <mujoco/mjdata.h> #include <mujoco/mjdata.h>
#include <mujoco/mjsan.h> // IWYU pragma: keep
#include <mujoco/mjtnum.h> #include <mujoco/mjtnum.h>
#include "engine/engine_io.h" #include "engine/engine_io.h"
#include "engine/engine_util_blas.h" #include "engine/engine_util_blas.h"
+1
View File
@@ -20,6 +20,7 @@
#include <mujoco/mjdata.h> #include <mujoco/mjdata.h>
#include <mujoco/mjexport.h> #include <mujoco/mjexport.h>
#include <mujoco/mjmodel.h> #include <mujoco/mjmodel.h>
#include <mujoco/mjsan.h> // IWYU pragma: keep
#include <mujoco/mjvisualize.h> #include <mujoco/mjvisualize.h>
#include "engine/engine_core_smooth.h" #include "engine/engine_core_smooth.h"
#include "engine/engine_io.h" #include "engine/engine_io.h"
+1
View File
@@ -20,6 +20,7 @@
#include <mujoco/mjdata.h> #include <mujoco/mjdata.h>
#include <mujoco/mjmacro.h> #include <mujoco/mjmacro.h>
#include <mujoco/mjmodel.h> #include <mujoco/mjmodel.h>
#include <mujoco/mjsan.h> // IWYU pragma: keep
#include <mujoco/mjvisualize.h> #include <mujoco/mjvisualize.h>
#include "engine/engine_array_safety.h" #include "engine/engine_array_safety.h"
#include "engine/engine_io.h" #include "engine/engine_io.h"
+1
View File
@@ -25,6 +25,7 @@
#include <utility> #include <utility>
#include <vector> #include <vector>
#include <mujoco/mjsan.h> // IWYU pragma: keep
#include <mujoco/mjthread.h> #include <mujoco/mjthread.h>
#include <mujoco/mujoco.h> #include <mujoco/mujoco.h>
#include "engine/engine_crossplatform.h" #include "engine/engine_crossplatform.h"
+1
View File
@@ -56,6 +56,7 @@ public const bool THIRD_PARTY_MUJOCO_MJRENDER_H_ = true;
public const int mjNAUX = 10; public const int mjNAUX = 10;
public const int mjMAXTEXTURE = 1000; public const int mjMAXTEXTURE = 1000;
public const int mjMAXMATERIAL = 1000; public const int mjMAXMATERIAL = 1000;
public const bool THIRD_PARTY_MUJOCO_INCLUDE_MJSAN_H_ = true;
public const bool THIRD_PARTY_MUJOCO_INCLUDE_MJSPEC_H_ = true; public const bool THIRD_PARTY_MUJOCO_INCLUDE_MJSPEC_H_ = true;
public const bool THIRD_PARTY_MUJOCO_INCLUDE_MJTHREAD_H_ = true; public const bool THIRD_PARTY_MUJOCO_INCLUDE_MJTHREAD_H_ = true;
public const int mjMAXTHREAD = 128; public const int mjMAXTHREAD = 128;