Tencent/matrix · critical

Unable to allocate memory for a new follow-set propagation…

Error message

Unable to allocate memory for a new follow-set propagation link.

What it means

Lemon allocates follow-set propagation links (struct plink) in batches of 100 from a freelist. When malloc fails to supply the next batch, it prints this message and exits immediately (exit(1)), as the generator cannot continue without memory for the LALR construction.

Solutions

  1. Increase available memory (raise container/CI memory limits, close other jobs) and re-run lemon
  2. Split the grammar into smaller units or reduce rule count / state explosion (factor common productions)
  3. Rebuild lemon on a 64-bit host if running a memory-limited 32-bit binary
  4. Precompute or reduce %include complexity if the grammar file itself is huge
Defensive patterns

Strategy: try-catch

Validate before calling

// check available memory headroom before running lemon on huge grammars
#include <stdio.h>
long avail = sysconf(_SC_AVPHYS_PAGES) * sysconf(_SC_PAGESIZE);
if (avail < 64L*1024*1024) { fprintf(stderr, "not enough memory for lemon\n"); return 1; }

Prevention

When it happens

Trigger: The lemon process hits an out-of-memory condition while building the parser state machine for a grammar with many states/rules, so malloc(sizeof(struct plink)*100) returns NULL.

Common situations: Generating a parser for a very large grammar on a memory-constrained container or CI runner with low memory limits; 32-bit builds with limited address space; system-wide memory exhaustion from other concurrent jobs.

Related errors


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

Appendix: source

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

  gp->errorcnt = ps.errorcnt;
}
/*************************** From the file "plink.c" *********************/
/*
** Routines processing configuration follow-set propagation links
** in the LEMON parser generator.
*/
static struct plink *plink_freelist = 0;

/* Allocate a new plink */
struct plink *Plink_new(){
  struct plink *new;

  if( plink_freelist==0 ){
    int i;
    int amt = 100;
    plink_freelist = (struct plink *)malloc( sizeof(struct plink)*amt );
    if( plink_freelist==0 ){
      fprintf(stderr,
      "Unable to allocate memory for a new follow-set propagation link.\n");
      exit(1);
    }
    for(i=0; i<amt-1; i++) plink_freelist[i].next = &plink_freelist[i+1];
    plink_freelist[amt-1].next = 0;
  }
  new = plink_freelist;
  plink_freelist = plink_freelist->next;
  return new;
}

/* Add a plink to a plink list */
void Plink_add(plpp,cfp)
struct plink **plpp;
struct config *cfp;
{
  struct plink *new;
  new = Plink_new();

View on GitHub (pinned to 3b8293bd65)