From 22ecae32fb0a0a9777cb00599a3b6440adb7bd83 Mon Sep 17 00:00:00 2001 From: Lukas Larsson Date: Wed, 14 Jun 2017 10:47:54 +0200 Subject: erts: Cleanup dropped port tasks correctly Before this fix, the extra data attached to a port task had to be cleaned up by the calling function. This caused problems because the outputv call, co-allocates the extra data with the port task. So in rare circumstances the port task would be free'd before the extra data was free'd which led to segfault when looking at the port task. This has been fixed by the generic PORT_TASK_ABORT behaviour being used even for tasks dropped in the erts_schedule_proc2port_signal API. --- erts/emulator/beam/erl_port_task.c | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) (limited to 'erts/emulator/beam/erl_port_task.c') diff --git a/erts/emulator/beam/erl_port_task.c b/erts/emulator/beam/erl_port_task.c index 3102e44c11..8d78b22228 100644 --- a/erts/emulator/beam/erl_port_task.c +++ b/erts/emulator/beam/erl_port_task.c @@ -852,10 +852,11 @@ schedule_port_task_handle_list_free(ErtsPortTaskHandleList *pthlp) } static ERTS_INLINE void -abort_nosuspend_task(Port *pp, - ErtsPortTaskType type, - ErtsPortTaskTypeData *tdp, - int bpq_data) +abort_signal_task(Port *pp, + int abort_type, + ErtsPortTaskType type, + ErtsPortTaskTypeData *tdp, + int bpq_data) { ASSERT(type == ERTS_PORT_TASK_PROC_SIG); @@ -863,18 +864,28 @@ abort_nosuspend_task(Port *pp, if (!bpq_data) tdp->psig.callback(NULL, ERTS_PORT_SFLG_INVALID, - ERTS_PROC2PORT_SIG_ABORT_NOSUSPEND, + abort_type, &tdp->psig.data); else { ErlDrvSizeT size = erts_proc2port_sig_command_data_size(&tdp->psig.data); tdp->psig.callback(NULL, ERTS_PORT_SFLG_INVALID, - ERTS_PROC2PORT_SIG_ABORT_NOSUSPEND, + abort_type, &tdp->psig.data); aborted_proc2port_data(pp, size); } } + +static ERTS_INLINE void +abort_nosuspend_task(Port *pp, + ErtsPortTaskType type, + ErtsPortTaskTypeData *tdp, + int bpq_data) +{ + abort_signal_task(pp, ERTS_PROC2PORT_SIG_ABORT_NOSUSPEND, type, tdp, bpq_data); +} + static ErtsPortTaskHandleList * get_free_nosuspend_handles(Port *pp) { @@ -1625,6 +1636,9 @@ fail: erts_port_dec_refc(pp); #endif + abort_signal_task(pp, ERTS_PROC2PORT_SIG_ABORT, + ptp->type, &ptp->u.alive.td, 0); + if (ns_pthlp) erts_free(ERTS_ALC_T_PT_HNDL_LIST, ns_pthlp); -- cgit v1.2.3 From 37faaedc1d7aedf66c29130794e8339b96c051d8 Mon Sep 17 00:00:00 2001 From: Lukas Larsson Date: Wed, 14 Jun 2017 17:30:02 +0200 Subject: fixup! erts: Cleanup dropped port tasks correctly --- erts/emulator/beam/erl_port_task.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'erts/emulator/beam/erl_port_task.c') diff --git a/erts/emulator/beam/erl_port_task.c b/erts/emulator/beam/erl_port_task.c index 8d78b22228..2083a43f69 100644 --- a/erts/emulator/beam/erl_port_task.c +++ b/erts/emulator/beam/erl_port_task.c @@ -1624,8 +1624,9 @@ abort_nosuspend: ASSERT(ns_pthlp); erts_free(ERTS_ALC_T_PT_HNDL_LIST, ns_pthlp); - if (ptp) - port_task_free(ptp); + + ASSERT(ptp); + port_task_free(ptp); return 0; @@ -1636,15 +1637,15 @@ fail: erts_port_dec_refc(pp); #endif - abort_signal_task(pp, ERTS_PROC2PORT_SIG_ABORT, - ptp->type, &ptp->u.alive.td, 0); + if (ptp) { + abort_signal_task(pp, ERTS_PROC2PORT_SIG_ABORT, + ptp->type, &ptp->u.alive.td, 0); + port_task_free(ptp); + } if (ns_pthlp) erts_free(ERTS_ALC_T_PT_HNDL_LIST, ns_pthlp); - if (ptp) - port_task_free(ptp); - return -1; } -- cgit v1.2.3