{"record":{"id":"4f1ebcb75c9a87b6","repo":"Tencent/matrix","slug":"unable-to-allocate-memory-for-a-new-follow-set-pro","errorCode":null,"errorMessage":"Unable to allocate memory for a new follow-set propagation link.\n","messagePattern":"Unable to allocate memory for a new follow-set propagation link\\.\n","errorType":"console","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"matrix/matrix-android/matrix-sqlite-lint/src/lemon/lemon-gen/lemon.c","lineNumber":2594,"sourceCode":"  gp->errorcnt = ps.errorcnt;\n}\n/*************************** From the file \"plink.c\" *********************/\n/*\n** Routines processing configuration follow-set propagation links\n** in the LEMON parser generator.\n*/\nstatic struct plink *plink_freelist = 0;\n\n/* Allocate a new plink */\nstruct plink *Plink_new(){\n  struct plink *new;\n\n  if( plink_freelist==0 ){\n    int i;\n    int amt = 100;\n    plink_freelist = (struct plink *)malloc( sizeof(struct plink)*amt );\n    if( plink_freelist==0 ){\n      fprintf(stderr,\n      \"Unable to allocate memory for a new follow-set propagation link.\\n\");\n      exit(1);\n    }\n    for(i=0; i<amt-1; i++) plink_freelist[i].next = &plink_freelist[i+1];\n    plink_freelist[amt-1].next = 0;\n  }\n  new = plink_freelist;\n  plink_freelist = plink_freelist->next;\n  return new;\n}\n\n/* Add a plink to a plink list */\nvoid Plink_add(plpp,cfp)\nstruct plink **plpp;\nstruct config *cfp;\n{\n  struct plink *new;\n  new = Plink_new();","sourceCodeStart":2576,"sourceCodeEnd":2612,"githubUrl":"https://github.com/Tencent/matrix/blob/3b8293bd65d47eeea7caf1f32a3a5d4d5eab60e7/matrix/matrix-android/matrix-sqlite-lint/src/lemon/lemon-gen/lemon.c#L2576-L2612","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Increase available memory (raise container/CI memory limits, close other jobs) and re-run lemon","Split the grammar into smaller units or reduce rule count / state explosion (factor common productions)","Rebuild lemon on a 64-bit host if running a memory-limited 32-bit binary","Precompute or reduce %include complexity if the grammar file itself is huge"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// check available memory headroom before running lemon on huge grammars\n#include <stdio.h>\nlong avail = sysconf(_SC_AVPHYS_PAGES) * sysconf(_SC_PAGESIZE);\nif (avail < 64L*1024*1024) { fprintf(stderr, \"not enough memory for lemon\\n\"); return 1; }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Run lemon on 64-bit hosts with adequate RAM","Monitor CI container memory limits for grammar-heavy builds","Factor large grammars to reduce state explosion","Check OOM-killer logs when lemon exits(1) after heavy allocation"],"tags":["memory","lemon","out-of-memory","parser-generator"],"backgroundTag":"out-of-memory","analyzedSha":"3b8293bd65d47eeea7caf1f32a3a5d4d5eab60e7","analyzedAt":"2026-09-08T08:01:39.722Z","contentChangedAt":"2026-09-08T08:01:39.722Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}