{"record":{"id":"fe8fd7c1f5497138","repo":"Tencent/matrix","slug":"out-of-memory-fe8fd7","errorCode":null,"errorMessage":"Out of memory.\n","messagePattern":"Out of memory\\.\n","errorType":"console","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"matrix/matrix-android/matrix-sqlite-lint/src/lemon/lemon-gen/lemon.c","lineNumber":3319,"sourceCode":"\n  /* Allocate and initialize types[] and allocate stddt[] */\n  arraysize = lemp->nsymbol * 2;\n  types = (char**)malloc( arraysize * sizeof(char*) );\n  for(i=0; i<arraysize; i++) types[i] = 0;\n  maxdtlength = 0;\n  if( lemp->vartype ){\n    maxdtlength = strlen(lemp->vartype);\n  }\n  for(i=0; i<lemp->nsymbol; i++){\n    int len;\n    struct symbol *sp = lemp->symbols[i];\n    if( sp->datatype==0 ) continue;\n    len = strlen(sp->datatype);\n    if( len>maxdtlength ) maxdtlength = len;\n  }\n  stddt = (char*)malloc( maxdtlength*2 + 1 );\n  if( types==0 || stddt==0 ){\n    fprintf(stderr,\"Out of memory.\\n\");\n    exit(1);\n  }\n\n  /* Build a hash table of datatypes. The \".dtnum\" field of each symbol\n  ** is filled in with the hash index plus 1.  A \".dtnum\" value of 0 is\n  ** used for terminal symbols.  If there is no %default_type defined then\n  ** 0 is also used as the .dtnum value for nonterminals which do not specify\n  ** a datatype using the %type directive.\n  */\n  for(i=0; i<lemp->nsymbol; i++){\n    struct symbol *sp = lemp->symbols[i];\n    char *cp;\n    if( sp==lemp->errsym ){\n      sp->dtnum = arraysize+1;\n      continue;\n    }\n    if( sp->type!=NONTERMINAL || (sp->datatype==0 && lemp->vartype==0) ){\n      sp->dtnum = 0;","sourceCodeStart":3301,"sourceCodeEnd":3337,"githubUrl":"https://github.com/Tencent/matrix/blob/3b8293bd65d47eeea7caf1f32a3a5d4d5eab60e7/matrix/matrix-android/matrix-sqlite-lint/src/lemon/lemon-gen/lemon.c#L3301-L3337","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// bound grammar size and memory before generation\nif grammarIsHuge() { splitGrammar(); } // keep %type declarations modest\n// ensure runner has >=512MB free before invoking lemon","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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"],"tags":["memory","lemon","out-of-memory","datatype"],"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"}