Skip to content

Commit d0277bd

Browse files
committed
Better handling of compilation memory limit exceeded errors
1 parent 9cf7674 commit d0277bd

File tree

4 files changed

+37
-9
lines changed

4 files changed

+37
-9
lines changed

cms/grading/Sandbox.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -414,11 +414,15 @@ def get_exit_status(self) -> str:
414414
return self.EXIT_TIMEOUT_WALL
415415
else:
416416
return self.EXIT_TIMEOUT
417+
elif 'cg-oom-killed' in self.log:
418+
# OOM killer was activated in the sandbox. It killed either the
419+
# main process (in which case the exit status is SG) or a
420+
# subprocess (in which case the main process gets to decide how to
421+
# handle it, but probably RE). In both cases, we want to
422+
# "root-cause" the verdict as "memory limit exceeded".
423+
return self.EXIT_MEM_LIMIT
417424
elif "SG" in status_list:
418-
if "cg-oom-killed" in self.meta:
419-
return self.EXIT_MEM_LIMIT
420-
else:
421-
return self.EXIT_SIGNAL
425+
return self.EXIT_SIGNAL
422426
elif "RE" in status_list:
423427
return self.EXIT_NONZERO_RETURN
424428
# OK status is not reported in the meta file, it's implicit.

cms/grading/steps/compilation.py

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -55,13 +55,16 @@ def N_(message: str):
5555
N_("Your submission exceeded the time limit while compiling. "
5656
"This might be caused by an excessive use of C++ "
5757
"templates, for example.")),
58+
HumanMessage("memorylimit",
59+
N_("Compilation memory limit exceeded"),
60+
N_("Your submission exceeded the memory limit while compiling. "
61+
"This might be caused by an excessive use of C++ "
62+
"templates, or too large global variables, for example.")),
5863
HumanMessage("signal",
59-
N_("Compilation killed with signal %s (could be triggered "
60-
"by violating memory limits)"),
64+
N_("Compilation killed with signal %s"),
6165
N_("Your submission was killed with the specified signal. "
62-
"Among other things, this might be caused by exceeding "
63-
"the memory limit for the compilation, and in turn by an "
64-
"excessive use of C++ templates, for example.")),
66+
"This might be caused by a bug in the compiler, "
67+
"for example.")),
6568
])
6669

6770

@@ -136,6 +139,13 @@ def compilation_step(
136139
text = [COMPILATION_MESSAGES.get("timeout").message]
137140
return True, False, text, stats
138141

142+
elif exit_status == Sandbox.EXIT_MEM_LIMIT:
143+
# Memory limit: we assume it is the user's fault, and we return the
144+
# error to them.
145+
logger.debug("Compilation memory limit exceeded.")
146+
text = [COMPILATION_MESSAGES.get("memorylimit").message]
147+
return True, False, text, stats
148+
139149
elif exit_status == Sandbox.EXIT_SIGNAL:
140150
# Terminated by signal: we assume again it is the user's fault, and
141151
# we return the error to them.

cmstestsuite/Tests.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,11 @@
196196
languages=(LANG_CPP,),
197197
checks=[CheckCompilationFail()]),
198198

199+
Test('compile-memory-limit',
200+
task=batch_fileio, filenames=['compile-memory-limit.%l'],
201+
languages=(LANG_CPP,),
202+
checks=[CheckCompilationFail()]),
203+
199204
# Various timeout conditions.
200205

201206
Test('timeout-cputime',
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#ifdef EVAL // this file can accidentally OOM editors/language servers...
2+
#define a "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
3+
#define b a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a
4+
#define c b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b
5+
#define d c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c
6+
#define e d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d
7+
const char* x = e e;
8+
#endif
9+
int main() { return 0; }

0 commit comments

Comments
 (0)