[crash] : Audio Output module / input_thread_Events crash
In this ticket I'll try to explain the issues described in #56 (closed) and #53 (closed).
branch : https://code.videolan.org/b1ue/vlc/-/tree/vlcjs/wip/playercrash
Here is the crash trace :
experimental.worker.js:178 Uncaught RuntimeError: memory access out of bounds
at input_thread_Events (http://localhost:6931/experimental.wasm:wasm-function[13457]:0x9b0293)
at EsOutVaPrivControlLocked (http://localhost:6931/experimental.wasm:wasm-function[13269]:0x99cb03)
at EsOutPrivControl (http://localhost:6931/experimental.wasm:wasm-function[13268]:0x99c26d)
at es_out_PrivControl (http://localhost:6931/experimental.wasm:wasm-function[13307]:0x9a2b43)
at CmdExecutePrivControl (http://localhost:6931/experimental.wasm:wasm-function[13309]:0x9a2dce)
at PrivControl (http://localhost:6931/experimental.wasm:wasm-function[13306]:0x9a2a35)
at es_out_PrivControl.1 (http://localhost:6931/experimental.wasm:wasm-function[13341]:0x9a70e7)
at MainLoop (http://localhost:6931/experimental.wasm:wasm-function[13329]:0x9a6384)
at Run.5 (http://localhost:6931/experimental.wasm:wasm-function[13327]:0x9a3f94)
at dynCall_ii (http://localhost:6931/experimental.wasm:wasm-function[16795]:0xa263ea)
Observations:
- It starts in audio_output module. When I change the size of the ring buffer the crash is delayed.
#define STORAGE_SIZE 4096 * 4096 //instead of 1024 * 1024
// in modules/src/audio_output/emscripten.cpp
-
Commenting out MainLoopStatistics() in src/input/input.c => MainLoop() removes the crash
-
growing linear memory, or using printf in some places and probably other random lines of code (that I cannot reproduce, because it was random) seems to remove the crash too.
On one hand there is this function :
static void MainLoopStatistics( input_thread_t *p_input )
{
input_thread_private_t *priv = input_priv(p_input);
double f_position = 0.0;
vlc_tick_t i_time;
vlc_tick_t i_length;
/* update input status variables */
if( demux_Control( priv->master->p_demux,
DEMUX_GET_POSITION, &f_position ) )
f_position = 0.0;
if( demux_Control( priv->master->p_demux, DEMUX_GET_TIME, &i_time ) )
i_time = VLC_TICK_INVALID;
if( demux_Control( priv->master->p_demux, DEMUX_GET_LENGTH, &i_length ) )
i_length = VLC_TICK_INVALID;
/* In case of failure (not implemented or in case of seek), use the last
* normal_time value (that is VLC_TICK_0 by default). */
demux_Control( priv->master->p_demux, DEMUX_GET_NORMAL_TIME, &priv->normal_time );
es_out_SetTimes( priv->p_es_out, f_position, i_time, priv->normal_time,
i_length );
struct input_stats_t new_stats;
if( priv->stats != NULL )
input_stats_Compute( priv->stats, &new_stats );
vlc_mutex_lock( &priv->p_item->lock );
if( priv->stats != NULL )
*priv->p_item->p_stats = new_stats;
vlc_mutex_unlock( &priv->p_item->lock );
input_SendEventStatistics( p_input, &new_stats );
}
on the other hand, there is one specific call to input_SendEvent(.., on_position_changed, ...) in (src/player/input.c), that causes the crash.
Observation:
- putting a debug log (without printf) in vlc_player_SendEvent():
#define vlc_player_SendEvent(player, event, ...) do { \
vlc_player_listener_id *listener; \
vlc_list_foreach(listener, &player->listeners, node) \
{ \
if (listener->cbs->event) \
listener->cbs->event(player, ##__VA_ARGS__, listener->cbs_data); \
} \
} while(0)
shows that sometimes, listener->cbs->event will be null, it won't crash on the first time this happens but after some logs.