personalrobotics / aikido

Artificial Intelligence for Kinematics, Dynamics, and Optimization

Home Page:https://personalrobotics.github.io/aikido/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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:

  1. 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 where update attempts to dereference a frame that no longer exists.
  2. 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 a removeTSRMarker function which takes in the retval of addTSRMarker and removes those markers from mFrameMarkers.

@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.