Tencent/matrix · critical
Out of memory.
Error message
Out of memory.
What it means
In lemon's print_tableaways/type-collection code, stddt is malloc'd to hold the longest symbol datatype before the generator builds a hash table of datatypes for the union members it emits. If the earlier allocation of `types` or this stddt allocation fails, it prints 'Out of memory.' and exits 1.
Solutions
- Increase memory available to the lemon process (limits, container quota)
- Reduce grammar size or number of %type/%token_type declarations
- Rebuild lemon as a 64-bit binary to enlarge address space
- Check for leaks/OOM pressure from concurrent build jobs and serialize the lemon step
Defensive patterns
Strategy: retry
Validate before calling
// bound grammar size and memory before generation
if grammarIsHuge() { splitGrammar(); } // keep %type declarations modest
// ensure runner has >=512MB free before invoking lemon Prevention
- Run lemon with generous memory headroom on CI
- Minimize distinct %token_type/%type datatypes in the grammar
- Use 64-bit lemon binaries
- Retry the generation step on transient OOM after reducing load
When it happens
Trigger: The process runs out of memory while generating the parser's type dispatch table (types array or stddt string buffer sized maxdtlength*2+1) for a grammar with %token_type/%type declarations.
Common situations: Very large grammars exhausting the heap on memory-limited CI containers; memory already consumed by earlier grammar analysis on a 32-bit lemon binary; system OOM conditions under parallel build load.
Related errors
- Unable to allocate memory for a new follow-set propagation…
- Can't allocate space for a filename.
- Matrix is NOT installed or MemoryInfoFactory is not…
- config.delayMillis is empty
- Unable to allocate memory for a new parser action.
AI-assisted analysis of Tencent/matrix@3b8293bd65 (2026-09-08).
Data as JSON: /api/errors/fe8fd7c1f5497138.
Report an issue: GitHub.
Appendix: source
Thrown at matrix/matrix-android/matrix-sqlite-lint/src/lemon/lemon-gen/lemon.c:3319
/* Allocate and initialize types[] and allocate stddt[] */
arraysize = lemp->nsymbol * 2;
types = (char**)malloc( arraysize * sizeof(char*) );
for(i=0; i<arraysize; i++) types[i] = 0;
maxdtlength = 0;
if( lemp->vartype ){
maxdtlength = strlen(lemp->vartype);
}
for(i=0; i<lemp->nsymbol; i++){
int len;
struct symbol *sp = lemp->symbols[i];
if( sp->datatype==0 ) continue;
len = strlen(sp->datatype);
if( len>maxdtlength ) maxdtlength = len;
}
stddt = (char*)malloc( maxdtlength*2 + 1 );
if( types==0 || stddt==0 ){
fprintf(stderr,"Out of memory.\n");
exit(1);
}
/* Build a hash table of datatypes. The ".dtnum" field of each symbol
** is filled in with the hash index plus 1. A ".dtnum" value of 0 is
** used for terminal symbols. If there is no %default_type defined then
** 0 is also used as the .dtnum value for nonterminals which do not specify
** a datatype using the %type directive.
*/
for(i=0; i<lemp->nsymbol; i++){
struct symbol *sp = lemp->symbols[i];
char *cp;
if( sp==lemp->errsym ){
sp->dtnum = arraysize+1;
continue;
}
if( sp->type!=NONTERMINAL || (sp->datatype==0 && lemp->vartype==0) ){
sp->dtnum = 0;View on GitHub (pinned to 3b8293bd65)