InteractiveMarkerViewer's addTSRMarker Does Not Properly Deallocate
amalnanavati opened this issue · comments
Currently, the addTSRMarker
function returns a TSRMarker (effectively a list of dart::dynamic::Frame objects). As soon as that TSRMarker falls out of scope, all those frames are deallocated. However, a pointer to those frames is still stored in mFrameMarkers
(code here). Hence, the next time update
is called (code here), it attempts to dereference a frame that has been deleted, leading the code to crash.
An example of where this issue occurs is in ada_feeding
actions where they ask the researcher to check the TSR. After the researcher checks the TSR, they enter a number, and the program is expected to remove the TSR visualization and continue. Instead, the program deallocates the frames but doesn't remove them from the InteractiveMarkerViewer, and thus crashes.
@egordon FYI this was the "Check TSR" issue we were facing
I believe the solution can be two-fold:
- Make the Frame pointer be a shared pointer instead of a raw pointer. That way, even if users don't store a reference to the TSRMarker returned by
addTSRMarker
, the frame itself does not get deallocated. This should prevent the issue whereupdate
attempts to dereference a frame that no longer exists. - However, the downside of the above solution is that the TSRMarker is permanently added to the
InteractiveMarkerViewer
, which might not be desired. Therefore, I propose also adding aremoveTSRMarker
function which takes in the retval ofaddTSRMarker
and removes those markers frommFrameMarkers
.
@brianhou can you weigh in on this proposed solution before I implement it? Anything I'm overlooking, or any suggestions on more elegant fixes?
Great find @amalnanavati ! Thanks!
There is so much wrong here... in order of BAD:
(1) Dereferencing stored raw pointers that you didn't allocate.
(2) Relinquishing control of a unique_ptr to the client while still keeping a reference to it.
(3) Relinquishing that control by putting the unique ptr inside a shared ptr object, so the programmer working on the client has no idea that it is carrying the only reference to that unique_ptr.
My goodness.
I agree, make the Frame pointer a shared ptr. Have addFrameMarker
take a shared_ptr input like every other function in the class. And update TSRMarker to be a vector of shared_ptrs instead of a vector of unique_ptrs (it doesn't matter if multiple classes own the Frame pointer, I think) so the client can use it if it wants.