{"record":{"id":"02dbb7844534f94b","repo":"Tencent/matrix","slug":"unable-to-allocate-memory-for-a-new-parser-action","errorCode":null,"errorMessage":"Unable to allocate memory for a new parser action.","messagePattern":"Unable to allocate memory for a new parser action\\.","errorType":"console","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"matrix/matrix-android/matrix-sqlite-lint/src/lemon/lemon-gen/lemon.c","lineNumber":343,"sourceCode":"int Configtable_insert(/* struct config * */);\nstruct config *Configtable_find(/* struct config * */);\nvoid Configtable_clear(/* int(*)(struct config *) */);\n/****************** From the file \"action.c\" *******************************/\n/*\n** Routines processing parser actions in the LEMON parser generator.\n*/\n\n/* Allocate a new parser action */\nstruct action *Action_new(){\n  static struct action *freelist = 0;\n  struct action *new;\n\n  if( freelist==0 ){\n    int i;\n    int amt = 100;\n    freelist = (struct action *)malloc( sizeof(struct action)*amt );\n    if( freelist==0 ){\n      fprintf(stderr,\"Unable to allocate memory for a new parser action.\");\n      exit(1);\n    }\n    for(i=0; i<amt-1; i++) freelist[i].next = &freelist[i+1];\n    freelist[amt-1].next = 0;\n  }\n  new = freelist;\n  freelist = freelist->next;\n  return new;\n}\n\n/* Compare two actions */\nstatic int actioncmp(ap1,ap2)\nstruct action *ap1;\nstruct action *ap2;\n{\n  int rc;\n  rc = ap1->sp->index - ap2->sp->index;\n  if( rc==0 ) rc = (int)ap1->type - (int)ap2->type;","sourceCodeStart":325,"sourceCodeEnd":361,"githubUrl":"https://github.com/Tencent/matrix/blob/3b8293bd65d47eeea7caf1f32a3a5d4d5eab60e7/matrix/matrix-android/matrix-sqlite-lint/src/lemon/lemon-gen/lemon.c#L325-L361","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Re-run the build on a machine/container with more available memory or a higher memory ulimit","Check/raise `ulimit -v` (virtual memory limit) in the build shell","Retry the build after closing memory-hogging processes; transient malloc failures usually succeed on retry","Inspect the CI container memory quota and increase it for native compile steps"],"exampleFix":"// before (CI config)\nresources: { limits: { memory: \"128Mi\" } }\n// after\nresources: { limits: { memory: \"2Gi\" } }","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":["Give native build steps generous memory quotas in CI","Avoid tight `ulimit -v` in build shells","Check malloc return values and fail gracefully rather than exit(1) if you fork this tooling"],"tags":["c","memory","parser-generator","build"],"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"}