{"record":{"id":"067b3e14c10b36c3","repo":"Tencent/matrix","slug":"out-of-memory-aborting","errorCode":null,"errorMessage":"Out of memory.  Aborting...\n","messagePattern":"Out of memory\\.  Aborting\\.\\.\\.\n","errorType":"console","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"matrix/matrix-android/matrix-sqlite-lint/src/lemon/lemon-gen/lemon.c","lineNumber":1359,"sourceCode":"  base = 0;\n  while( errmsg[base]!=0 ){\n    end = restart = findbreak(&errmsg[base],0,availablewidth);\n    restart += base;\n    while( errmsg[restart]==' ' ) restart++;\n    fprintf(stdout,\"%s%.*s\\n\",prefix,end,&errmsg[base]);\n    base = restart;\n  }\n}\n/**************** From the file \"main.c\" ************************************/\n/*\n** Main program file for the LEMON parser generator.\n*/\n\n/* Report an out-of-memory condition and abort.  This function\n** is used mostly by the \"MemoryCheck\" macro in struct.h\n*/\nvoid memory_error(){\n  fprintf(stderr,\"Out of memory.  Aborting...\\n\");\n  exit(1);\n}\n\nstatic int nDefine = 0;      /* Number of -D options on the command line */\nstatic char **azDefine = 0;  /* Name of the -D macros */\n\n/* This routine is called with the argument to each -D command-line option.\n** Add the macro defined to the azDefine array.\n*/\nstatic void handle_D_option(char *z){\n  char **paz;\n  nDefine++;\n  azDefine = realloc(azDefine, sizeof(azDefine[0])*nDefine);\n  if( azDefine==0 ){\n    fprintf(stderr,\"out of memory\\n\");\n    exit(1);\n  }\n  paz = &azDefine[nDefine-1];","sourceCodeStart":1341,"sourceCodeEnd":1377,"githubUrl":"https://github.com/Tencent/matrix/blob/3b8293bd65d47eeea7caf1f32a3a5d4d5eab60e7/matrix/matrix-android/matrix-sqlite-lint/src/lemon/lemon-gen/lemon.c#L1341-L1377","documentation":"memory_error() is lemon's single shared OOM handler: it prints 'Out of memory.  Aborting...' to stderr and exits with status 1. It is invoked mostly via the MemoryCheck macro after allocation helpers like memory check macros in structdef, so any internal table/string allocation that fails routes here. It means the parser-generation step has exhausted process memory and cannot continue.","triggerScenarios":"Any MemoryCheck(...) or direct call to memory_error() after x = malloc(...) / realloc(...) returns NULL inside lemon (e.g. set/hashtable/string-pool growth) while parsing a grammar, usually driven by large or pathological .y inputs.","commonSituations":"Generating parsers from very large grammars; memory-limited CI containers; systems under memory pressure; accidentally passing a huge or binary file to lemon that blows up symbol tables.","solutions":["Increase available memory (ulimit, container limits, swap) and rerun.","Inspect the grammar size / generated symbol counts; split an oversized grammar or remove generated duplication.","Run with a memory profiler (valgrind massif) to see if a lemon bug leaks memory before the failure.","Upgrade to a newer lemon.c that may have allocation-efficiency fixes.","Pre-check input file size and reject absurdly large inputs before invoking lemon."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"# shell pre-check before invoking lemon\nfree_kb=$(awk '/MemAvailable/{print $2}' /proc/meminfo)\n[ \"$free_kb\" -lt 65536 ] && { echo \"insufficient memory for lemon\"; exit 1; }","typeGuard":null,"tryCatchPattern":"retry with backoff around the lemon process, since OOM is often transient:\nfor i in 1 2 3; do lemon grammar.y && break; sleep $((i*i)); done","preventionTips":["Guarantee headroom in CI containers (raise memory cgroup limits)","Check /proc/meminfo or cgroup memory.before invoking codegen","Watch for grammar features that explode state/config counts","Keep lemon.c updated for allocation efficiency fixes"],"tags":["c","memory-allocation","parser-generator","out-of-memory"],"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"}