Facing GC infinite loop in Lua 5.1

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Facing GC infinite loop in Lua 5.1

Wagner Fernando Fazio

I’m looping forever when calling luaC_fullgc and can not realize why it is happening. Every call do singlestep() does nothing and sweeplist() keeps trying to mark objects as white in every call.

 

At this moment, my debugger shows deadmask==33(0x21) and all are gch.marked==2.

 

Can someone figure out situations where it may happen?

 

It differs from Makoto Hamanaka on 01 Jul 2008 report where the looping root cause was in LUA_GCSTEP.

 

static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count) {

  GCObject *curr;

  global_State *g = G(L);

  int deadmask = otherwhite(g);

  while ((curr = *p) != NULL && count-- > 0) {

    if (curr->gch.tt == LUA_TTHREAD/* sweep open upvalues of each thread */

      sweepwholelist(L, &gco2th(curr)->openupval);

    if ((curr->gch.marked ^ WHITEBITS) & deadmask) {  /* not dead? */ //only this branch runs every call

      lua_assert(!isdead(g, curr) || testbit(curr->gch.marked, FIXEDBIT));

      makewhite(g, curr);  /* make it white (for next cycle) */

      p = &curr->gch.next;

    }

    else/* must erase `curr' */

      lua_assert(isdead(g, curr) || deadmask == bitmask(SFIXEDBIT));

      *p = curr->gch.next;

      if (curr == g->rootgc)  /* is the first element of the list? */

        g->rootgc = curr->gch.next;  /* adjust first */

      freeobj(L, curr);

    }

  }

  return p;

}

 

static l_mem singlestep (lua_State *L) {

  ...

   case GCSsweep: {

      lu_mem old = g->totalbytes;

      g->sweepgc = sweeplist(L, g->sweepgc, GCSWEEPMAX);

      if (*g->sweepgc == NULL) {  /* nothing more to sweep? */ //this branch is never executed

        checkSizes(L);

        g->gcstate = GCSfinalize/* end sweep phase */

      }

      lua_assert(old >= g->totalbytes);

      g->estimate -= old - g->totalbytes; //here old has the same value as g->totalbytes

      return GCSWEEPMAX*GCSWEEPCOST;

    }

...

}

 

 

void luaC_fullgc (lua_State *L) {

  ...

 /* finish any pending sweep phase */

  while (g->gcstate != GCSfinalize) {

    lua_assert(g->gcstate == GCSsweepstring || g->gcstate == GCSsweep);

    singlestep(L);

  }

...

}

 

Wagner Fernando Fázio 
Meios de Captura

Especialista em Plataforma de Terminais POS

+55 11 2587 2799

[hidden email]
Tag assinatura de e-mail 60
Rede

Av. Eusébio Matoso, 891

Centro Administrativo Pinheiros – 14º andar

05423-010 São Paulo - SP

 

fanáticos por performance

Esse é o Nosso Jeito

 

 

==============================================================================================================================================
Este destinatario e externo a sua organizacao.

Este e-mail e confidencial e pode conter informacoes privilegiadas. Se voce nao for o destinatario desta 
mensagem por favor delete-a e me informe no endereco acima. Nao copie ou reenvie de forma a revelar estas 
informacoes a outras pessoas ou utilize-as para qualquer proposito.

This recipient is external to your organization.
This e-mail is confidential and may also be privileged. If you are not intended recipient, please delete it
and notify me immediately at above address; do not copy, forward or other side disclose the contents of this 
e-mail to any other person or use it for any purpose.
Reply | Threaded
Open this post in threaded view
|

Re: Facing GC infinite loop in Lua 5.1

nerditation
On 2021/1/28 2:15, Wagner Fernando Fazio wrote:

> I’m looping forever when calling luaC_fullgc and can not realize why it is happening. Every call do singlestep() does nothing and sweeplist() keeps trying to mark objects as white in every call.
>
>  
>
> At this moment, my debugger shows deadmask==33(0x21) and all are gch.marked==2.
>
>  
>
> Can someone figure out situations where it may happen?
>
> [...]


do you use a patched Lua or official release version? which exact version of Lua do you use?
or do you have a custom memory allocator?

if the gc got stuck in the sweep phase, I can only imagine there exists a cycle in the `allgc`
list, which should be a singly linked list through the `gch->next` field in every gc object.

so I suspect your allocator might caused a memory corruption and overwritten the `gch->next`
field of some gc objects, which happened to point to some other objects, thus making the `allgc`
list `infinitely` long.
Reply | Threaded
Open this post in threaded view
|

Re: Facing GC infinite loop in Lua 5.1

nerditation
small correction: the `allgc` field was named `rootgc` back in Lua 5.1
Reply | Threaded
Open this post in threaded view
|

RES: Facing GC infinite loop in Lua 5.1

Wagner Fernando Fazio
In reply to this post by nerditation
You are absolutely right!!! There was a memory corruption caused by sprintf misuse.

Thank you a lot for spending your time.

It was  5.1.4 version with some extensions



-----Mensagem original-----
De: nerditation <[hidden email]>
Enviada em: quarta-feira, 3 de fevereiro de 2021 12:51
Para: [hidden email]
Assunto: Re: Facing GC infinite loop in Lua 5.1

On 2021/1/28 2:15, Wagner Fernando Fazio wrote:

> I'm looping forever when calling luaC_fullgc and can not realize why it is happening. Every call do singlestep() does nothing and sweeplist() keeps trying to mark objects as white in every call.
>
>  
>
> At this moment, my debugger shows deadmask==33(0x21) and all are gch.marked==2.
>
>  
>
> Can someone figure out situations where it may happen?
>
> [...]


do you use a patched Lua or official release version? which exact version of Lua do you use?
or do you have a custom memory allocator?

if the gc got stuck in the sweep phase, I can only imagine there exists a cycle in the `allgc` list, which should be a singly linked list through the `gch->next` field in every gc object.

so I suspect your allocator might caused a memory corruption and overwritten the `gch->next` field of some gc objects, which happened to point to some other objects, thus making the `allgc` list `infinitely` long.

==============================================================================================================================================
Este destinatario e externo a sua organizacao.

Este e-mail e confidencial e pode conter informacoes privilegiadas. Se voce nao for o destinatario desta
mensagem por favor delete-a e me informe no endereco acima. Nao copie ou reenvie de forma a revelar estas
informacoes a outras pessoas ou utilize-as para qualquer proposito.

This recipient is external to your organization.
This e-mail is confidential and may also be privileged. If you are not intended recipient, please delete it
and notify me immediately at above address; do not copy, forward or other side disclose the contents of this
e-mail to any other person or use it for any purpose.