[ODE] problems with trimesh and capsules
Paul MacKenzie
paul.mackenzie at simlog.com
Fri May 19 18:40:49 MST 2006
Jaroslav Sinecky wrote:
> Memory allocated by dALLOCA16 should be freed automatically when leaving
> the function, see documentation for CRT alloc function. I did this
> change recently so it's not 100% guaranteed to be bug free, but I tried
> to run test_trimesh and test_moving_trimesh with lot of capsules with no
> problem. And revising the code can't see any error neither.
I think this is causing a problem -- gLocalContacts in
collision_trimesh_ccylinder.cpp is a global variable, and is allocated
once inside the dCollideCCTL() function and does not seem to be reallocated.
However, when using the dALLOCA16() function, the stack memory allocated
only survives within the context of that call to dCollideCCTL(), and is
released afterwards. However, since gLocalContacts is global, it
remembers that same memory space for the life of the program. So later
on when ODE tries to allocate new stack space elsewhere, it reuses the
memory previously owned by gLocalContacts, and now we have a stack
integrity problem.
I tried using malloc() instead of dALLOCA16(), and there is no stack
integrity problem. However, this leaks gLocalContacts, and besides, if
I later call dCollide() with a larger maximum number of contacts, there
could be a buffer overrun.
I followed through collision_trimesh_ccylinder.cpp and it looks like the
only place that gLocalContacts is accessed is within the context of
dCollideCCTL() and the functions that it calls. So, at the end of this
function, we can set gLocalContacts to NULL. In this way it will be
reallocated at every call, so that we are sure we have a properly sized
array.
One way to do this would be to use malloc() to allocate the memory, and
call free() at the end of the function followed by a set to NULL.
Alternatively, we can continue to use dALLOCA16() and just set
gLocalContacts to NULL at the end, forgetting about the free(). Both
work for me in my tests. We would have to modify the end of
dCollideCCTL() with a temporary variable because _ProcessLocalContacts()
needs gLocalContacts.
Here's a proposed modification, at the end of dCollideCCTL() in
collision_trimesh_ccylinder.cpp, assuming the continued use of
dALLOCA16() to allocate gLocalContacts if it is NULL:
----------------OLD CODE------------------
return _ProcessLocalContacts();
----------------NEW CODE------------------
int plc = _ProcessLocalContacts();
gLocalContacts = NULL;
return plc;
------------------------------------------
There should be no memory leaked as dALLOCA16() uses alloca() which is
supposed to free up all stack-allocated memory automatically.
I have not submitted a patch for this yet, as I would like someone to
review my logic, in case I missed something and my stack problem
actually goes away for other reasons.
Thanks!
Paul
More information about the ODE
mailing list