viewport: Do not use evas_object_event_callback_del() 29/283929/1
authorSeunghun Lee <shiin.lee@samsung.com>
Mon, 7 Nov 2022 08:18:13 +0000 (17:18 +0900)
committerTizen Window System <tizen.windowsystem@gmail.com>
Mon, 7 Nov 2022 09:19:57 +0000 (18:19 +0900)
commit300de6615c425001d901bc98ba6db2dc5f9afa1f
tree19b39b1c8ebd27d751dc02814305c07eb51a3d92
parent30842bf0ae06db99e7a7579ee9ea6544d0843ca1
viewport: Do not use evas_object_event_callback_del()

For short, the `evas_object_event_callback_del_full()` should be used
instead of `evas_object_event_callback_del()`.

The crash happened as the backtrace shown below, and it seems that the
crash was due to the misuse of `evas_object_event_callback_del()`.
This patch also log more about the viewport just in case the patch may
not fix the crash.

backtrace:
(gdb)bt

  #0  0x000d6e98 in e_object_is_del (obj=0x6) at /usr/src/debug/enlightenment-0.20.0/src/bin/e_object.c:106
  #1  0x00086088 in _e_comp_wl_viewport_cb_parent_show(data=0x1d50c70, e=<optimized out>, obj=<optimized out>, event_info=<optimized out>) at /usr/src/debug/enlightenment-0.20.0/src/bin/e_comp_wl_viewport.c:572
  #2 0xb5d91df6 in _eo_evas_object_cb (data=0x207e4c8, event=<optimized out>) at /usr/src/debug/efl-1.25.1/builddir/../src/lib/evas/canvas/evas_callbacks.c:181
  ...

The evas_object_event_callback_del() is to remove the most recently
added callback from the object. Having used it in `e_comp_wl_viewport.c`
could have caused unintentional removal of another callback depending on
the timing of creation and destruction of several viewports, and this
eventually could result in a crash.

I couldn't find the clear evidence that this really led the crash, but
let me give you an example what situation can make this crash.

1. There are 2 viewports created with the same parent. So, 2 viewports
would add a callback for its own. I will call both viewport as `A` and
`B`, and `A` is created before `B`.

2. The viewport `A` try to delete its callback from the parent evas
object because of the change of subsurface parent by calling
`evas_object_event_callback_del()`.  And this will unintentionally
delete the callback of `B`, not `A` because the callback of `B` is the
most recently added one.

3. Let's say the viewport `A` gets deleted by `tizen_viewport.destroy`,
and it does not call the `evas_object_event_callback_del_full()` because
`viewport->epc` must already be null.  And now, the data for the
callback `A` becomes freed memory, but the callback `A` is still in
callback list of parent object.

4. Event if the viewport `B` gets deleted by `tizen_viewport.destroy`,
it won't be able to remove any callbacks with
`evas_object_event_callback_del_full()` because the callback of `B` has
already been removed by the process 2.

As I mentioned, I'm not sure this really led the crash but I believe and
hope that this will fix the crash.

Change-Id: Ie92900df80d2351bbf9054fd3c4e9e6184b67d57
src/bin/e_comp_wl_viewport.c