{"record":{"id":"43e5bd514eea7703","repo":"Tencent/matrix","slug":"out-of-memory","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":1374,"sourceCode":"** 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];\n  *paz = malloc( strlen(z)+1 );\n  if( *paz==0 ){\n    fprintf(stderr,\"out of memory\\n\");\n    exit(1);\n  }\n  strcpy(*paz, z);\n  for(z=*paz; *z && *z!='='; z++){}\n  *z = 0;\n}\n\n\n/* The main program.  Parse the command line and do it... */\nint main(argc,argv)\nint argc;\nchar **argv;","sourceCodeStart":1356,"sourceCodeEnd":1392,"githubUrl":"https://github.com/Tencent/matrix/blob/3b8293bd65d47eeea7caf1f32a3a5d4d5eab60e7/matrix/matrix-android/matrix-sqlite-lint/src/lemon/lemon-gen/lemon.c#L1356-L1392","documentation":"handle_D_option() processes -D command-line defines for lemon. It reallocs the global azDefine array to grow by one entry, and if realloc returns NULL it prints 'out of memory' and exits(1). This is a fatal allocation failure while registering a -D macro name.","triggerScenarios":"realloc(azDefine, sizeof(char*)*nDefine) returns NULL at lemon.c:1374 when processing a -D option on the lemon command line, because the heap is exhausted (or in edge cases realloc fails on an oversized/zero-size request).","commonSituations":"Passing many -D flags on a constrained system; memory-capped CI containers; general system OOM at the moment lemon starts; broken builds invoking lemon with an enormous generated -D list.","solutions":["Free memory / raise limits (ulimit -v, container memory) and rerun lemon.","Reduce the number of -D defines passed to lemon.","Verify the build script isn't expanding variables into thousands of duplicate -D flags.","Replace the realloc pattern to use a temporary pointer and report the requested size for diagnosability.","Run lemon under valgrind to rule out prior heap corruption causing realloc failure."],"exampleFix":"// before\nazDefine = realloc(azDefine, sizeof(azDefine[0])*nDefine);\nif( azDefine==0 ){\n  fprintf(stderr,\"out of memory\\n\");\n  exit(1);\n}\n// after\nchar **pazNew = realloc(azDefine, sizeof(azDefine[0])*nDefine);\nif( pazNew==0 ){\n  fprintf(stderr,\"out of memory growing azDefine to %d entries\\n\", nDefine);\n  exit(1);\n}\nazDefine = pazNew;","handlingStrategy":"validation","validationCode":"# validate memory headroom and the -D list size before invoking lemon\n[ ${#DEFINES[@]} -lt 1000 ] || { echo \"too many -D defines\"; exit 1; }\nfree_kb=$(awk '/MemAvailable/{print $2}' /proc/meminfo); [ \"$free_kb\" -ge 65536 ] || exit 1","typeGuard":null,"tryCatchPattern":"// library exits(1); guard at process level\nif (system(\"lemon -DFOO grammar.y\") != 0) { /* raise limits and retry */ }","preventionTips":["Avoid passing long lists of -D defines; consolidate them in the grammar","Raise ulimit/container memory before builds","Ensure the build script is not duplicating flags via unquoted expansion"],"tags":["c","memory-allocation","cli","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"}