r15b03-1 SEGV in erts_port_task_schedule()

Mikael Pettersson <[email protected]>
Newsgroups gmane.comp.lang.erlang.bugs
Message-ID <[email protected]>
This is a followup to my previous report in
<http://erlang.org/pipermail/erlang-bugs/2014-June/004451.html>,
but it's for a different function in erl_port_task.c.

We've gotten a new SEGV with r15b03-1.  This time we managed to
capture a truncated core dump (just threads list and registers,
no thread stacks or heap memory):

Program terminated with signal 11, Segmentation fault.
#0  enqueue_task (ptp=<optimized out>, 
    ptqp=<error reading variable: Cannot access memory at address 0x7f8f02a95d08>)
    at beam/erl_port_task.c:327
327         ptp->prev = ptqp->last;
(gdb) bt
#0  enqueue_task (ptp=<optimized out>, 
    ptqp=<error reading variable: Cannot access memory at address 0x7f8f02a95d08>)
    at beam/erl_port_task.c:327
#1  erts_port_task_schedule (id=<optimized out>, 
    id@entry=<error reading variable: Cannot access memory at address 0x7f8efdeb8318>, 
    pthp=<error reading variable: Cannot access memory at address 0x7f8efdeb82c0>, 
    type=<error reading variable: Cannot access memory at address 0x7f8efdeb82cc>, 
    event=<error reading variable: Cannot access memory at address 0x7f8efdeb82d0>, 
    event_data=<error reading variable: Cannot access memory at address 0x7f8efdeb82d8>)
    at beam/erl_port_task.c:615
(gdb) 

The code that faulted is

   0x00000000004b8203 <+419>:   mov    0x10(%r15),%rax
   0x00000000004b8207 <+423>:   mov    0x10(%rsp),%rbx
   0x00000000004b820c <+428>:   movq   $0x0,0x8(%rbx)
=> 0x00000000004b8214 <+436>:   mov    0x8(%rax),%rcx
   0x00000000004b8218 <+440>:   mov    %rax,0x10(%rbx)
   0x00000000004b821c <+444>:   mov    %rcx,(%rbx)

which is enqueue_task() [line 327] as inlined in erts_port_task_schedule()
[line 615].  At this point, %rax is zero according to gdb's registers dump.

The relevant part of erts_port_task_schedule() is:

==snip==
    if (!pp->sched.taskq)
	pp->sched.taskq = port_taskq_init(port_taskq_alloc(), pp);

    ASSERT(ptp);

    ptp->type = type;
    ptp->event = event;
    ptp->event_data = event_data;

    set_handle(ptp, pthp);

    switch (type) {
    case ERTS_PORT_TASK_FREE:
	erl_exit(ERTS_ABORT_EXIT,
		 "erts_port_task_schedule(): Cannot schedule free task\n");
	break;
    case ERTS_PORT_TASK_INPUT:
    case ERTS_PORT_TASK_OUTPUT:
    case ERTS_PORT_TASK_EVENT:
	erts_smp_atomic_inc_relb(&erts_port_task_outstanding_io_tasks);
	/* Fall through... */
    default:
	enqueue_task(pp->sched.taskq, ptp);
	break;
    }
==snip==

The SEGV implies that pp->sched.taskq is NULL at the call to enqueue_task().

The erts_smp_atomic_inc_relb() and set_handle() calls do not affect *pp,
and I don't see any aliasing between *ptp and *pp, so the assignments to
*ptp do not affect *pp either.

So for pp->sched.taskq to be NULL at the bottom it would have to be NULL
after the call to port_taskq_init(), which implies that port_taskq_alloc()
returned NULL.

port_taskq_alloc() is generated via ERTS_SCHED_PREF_QUICK_ALLOC_IMPL;
if one expands that it becomes:

void erts_alloc_n_enomem(ErtsAlcType_t,Uint)
     __attribute__((noreturn));

static __inline__
void *erts_alloc(ErtsAlcType_t type, Uint size)
{
    void *res;
    res = (*erts_allctrs[(((type) >> (0)) & (15))].alloc)(
	(((type) >> (7)) & (255)),
	erts_allctrs[(((type) >> (0)) & (15))].extra,
	size);
    if (!res)
	erts_alloc_n_enomem((((type) >> (7)) & (255)), size);
    return res;
}

static __inline__ ErtsPortTaskQueue * port_taskq_alloc(void)
{
    ErtsPortTaskQueue *res = port_taskq_pre_alloc();
    if (!res)
	res = erts_alloc((4564), sizeof(ErtsPortTaskQueue));
    return res;
}

But given this code, I don't see how erts_alloc() or port_taskq_alloc()
could ever return NULL.

Which leads me to suspect that there's a concurrency bug that's
causing *pp to be clobbered behind our backs.

Ideas?

/Mikael
_______________________________________________
erlang-bugs mailing list
[email protected]
http://erlang.org/mailman/listinfo/erlang-bugs
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.