MSAN: Don't clear mjData.sensordata in mj_resetData

This is strictly an out array and should not be read before it is written to. This change improves MSAN coverage of engine code.

PiperOrigin-RevId: 819767673
Change-Id: I57500c8147f4774d326cf87ea3bac5420e4dd54d
This commit is contained in:
Yuval Tassa
2025-10-15 08:29:50 -07:00
committed by Copybara-Service
parent 99d93124f0
commit 5715cebbb9
3 changed files with 12 additions and 7 deletions
+4 -5
View File
@@ -1334,11 +1334,11 @@ static void _resetData(const mjModel* m, mjData* d, unsigned char debug_value) {
#endif
#ifdef MEMORY_SANITIZER
// Tell msan to treat the entire buffer as uninitialized
// under MSAN, mark the entire buffer as uninitialized
__msan_allocated_memory(d->buffer, d->nbuffer);
#endif
// zero out arrays that are not affected by mj_forward
// zero out user-settable state and input arrays (MSAN: mark as initialized)
mju_zero(d->qpos, m->nq);
mju_zero(d->qvel, m->nv);
mju_zero(d->act, m->na);
@@ -1346,11 +1346,10 @@ static void _resetData(const mjModel* m, mjData* d, unsigned char debug_value) {
for (int i=0; i < m->neq; i++) d->eq_active[i] = m->eq_active0[i];
mju_zero(d->qfrc_applied, m->nv);
mju_zero(d->xfrc_applied, 6*m->nbody);
mju_zero(d->qacc, m->nv);
mju_zero(d->qacc, m->nv); // input to inverse dynamics
mju_zero(d->qacc_warmstart, m->nv);
mju_zero(d->act_dot, m->na);
mju_zero(d->userdata, m->nuserdata);
mju_zero(d->sensordata, m->nsensordata);
mju_zero(d->mocap_pos, 3*m->nmocap);
mju_zero(d->mocap_quat, 4*m->nmocap);
@@ -1359,7 +1358,7 @@ static void _resetData(const mjModel* m, mjData* d, unsigned char debug_value) {
// copy qpos0 from model
if (m->qpos0) {
memcpy(d->qpos, m->qpos0, m->nq*sizeof(mjtNum));
mju_copy(d->qpos, m->qpos0, m->nq);
}
// set mocap_pos/quat = body_pos/quat for mocap bodies
+6
View File
@@ -647,6 +647,8 @@ void mj_sensorPos(const mjModel* m, mjData* d) {
break;
case mjSENS_USER: // user
// clear result, compute later
mju_zero(d->sensordata + adr, m->sensor_dim[i]);
nusersensor++;
break;
@@ -822,6 +824,8 @@ void mj_sensorVel(const mjModel* m, mjData* d) {
break;
case mjSENS_USER: // user
// clear result, compute later
mju_zero(d->sensordata + adr, m->sensor_dim[i]);
nusersensor++;
break;
@@ -1346,6 +1350,8 @@ void mj_sensorAcc(const mjModel* m, mjData* d) {
break;
case mjSENS_USER: // user
// clear result, compute later
mju_zero(d->sensordata + adr, m->sensor_dim[i]);
nusersensor++;
break;
+2 -2
View File
@@ -69,7 +69,6 @@ using SensorTest = MujocoTest;
// --------------------- test sensor disableflag ------------------------------
// hand-picked positions and orientations for simple expected values
TEST_F(SensorTest, DisableSensors) {
constexpr char xml[] = R"(
<mujoco>
@@ -83,7 +82,8 @@ TEST_F(SensorTest, DisableSensors) {
ASSERT_THAT(model, NotNull()) << error;
mjData* data = mj_makeData(model);
// before calling anything, check that sensors are initialised to 0
// call mj_forward, expect clock to report 0
mj_forward(model, data);
EXPECT_EQ(data->sensordata[0], 0.0);
// call mj_step, mj_step1, expect clock to be incremented by timestep