Tencent/matrix · critical

Unable to allocate memory for a new parser action.

Error message

Unable to allocate memory for a new parser action.

What it means

lemon.c is the LALR parser generator used by matrix-sqlite-lint to build its SQL parser tables. Action_new() lazily allocates a freelist pool of 100 parser action structs via malloc; when that malloc returns NULL, the generator prints this message and exits with status 1. It is a hard out-of-memory failure inside a build-time code-generation tool.

Solutions

  1. Re-run the build on a machine/container with more available memory or a higher memory ulimit
  2. Check/raise `ulimit -v` (virtual memory limit) in the build shell
  3. Retry the build after closing memory-hogging processes; transient malloc failures usually succeed on retry
  4. Inspect the CI container memory quota and increase it for native compile steps

Example fix

// before (CI config)
resources: { limits: { memory: "128Mi" } }
// after
resources: { limits: { memory: "2Gi" } }
Defensive patterns

Strategy: retry

Prevention

When it happens

Trigger: Running the lemon parser generator (via Action_add -> Action_new) on a grammar whose action pool allocation of sizeof(struct action)*100 fails because the process cannot obtain memory from the OS.

Common situations: Building matrix-sqlite-lint on a memory-constrained CI container or machine where malloc of even a small block fails; extremely constrained embedded/low-memory build environments; OOM-killer pressure or low ulimit -v during native build.

Related errors


AI-assisted analysis of Tencent/matrix@3b8293bd65 (2026-09-08). Data as JSON: /api/errors/02dbb7844534f94b. Report an issue: GitHub.

Appendix: source

Thrown at matrix/matrix-android/matrix-sqlite-lint/src/lemon/lemon-gen/lemon.c:343

int Configtable_insert(/* struct config * */);
struct config *Configtable_find(/* struct config * */);
void Configtable_clear(/* int(*)(struct config *) */);
/****************** From the file "action.c" *******************************/
/*
** Routines processing parser actions in the LEMON parser generator.
*/

/* Allocate a new parser action */
struct action *Action_new(){
  static struct action *freelist = 0;
  struct action *new;

  if( freelist==0 ){
    int i;
    int amt = 100;
    freelist = (struct action *)malloc( sizeof(struct action)*amt );
    if( freelist==0 ){
      fprintf(stderr,"Unable to allocate memory for a new parser action.");
      exit(1);
    }
    for(i=0; i<amt-1; i++) freelist[i].next = &freelist[i+1];
    freelist[amt-1].next = 0;
  }
  new = freelist;
  freelist = freelist->next;
  return new;
}

/* Compare two actions */
static int actioncmp(ap1,ap2)
struct action *ap1;
struct action *ap2;
{
  int rc;
  rc = ap1->sp->index - ap2->sp->index;
  if( rc==0 ) rc = (int)ap1->type - (int)ap2->type;

View on GitHub (pinned to 3b8293bd65)