Skip to content

LiveCodeBench evaluation has no memory limit: unbounded allocations end PR evaluations with exit code 143 #238

Closed

Description

@wmlba

Problem

PR evaluations can end with Process completed with exit code 143 before any results are posted. This happened on all three evaluation runs of our submission (#236 twice, #237 once), at 9,205/9,209, 9,160/9,209 and 1,220/8,400 entries.

unsafe_lcb_runTests in llm_evaluation/livecodebench_util.py runs each LiveCodeBench completion in a forked process and limits only wall-clock time, (timeout + 1) * len(test_cases) + 5 seconds. There is no memory limit:

  • reliability_guard() is called with maximum_memory_bytes=None;
  • the guard then hides the resource module.

Generated code that allocates without bound keeps growing until that timeout. On the 16 GB ubuntu-latest runner, the system's memory-pressure handling terminates the job first (SIGTERM, exit code 143), so the run fails and no comment is posted.

Reproduction (synthetic, no dataset)

A three-test stdin problem, evaluated through check_correctness, with the run held to a 24 GiB cgroup:

PROBLEM = {"test": [{"input": "2 3\n", "output": "5", "testtype": "stdin"}] * 3, "is_stdin": True}
CORRECT = "a, b = map(int, input().split())\nprint(a + b)\n"
RUNAWAY = "blocks = []\nwhile True:\n    blocks.append(bytearray(64 * 1024 * 1024))\n"
lcb.check_correctness(problem=PROBLEM, completion=RUNAWAY, timeout=6, is_extracted=False)
Evaluator CORRECT RUNAWAY
main score 1, 0.3 s, 0.04 GiB score 0, reached the 24 GiB cgroup cap in 11.7 s (OOM kill)
with the proposed limit score 1, 0.3 s, 0.04 GiB score 0 in 1.2 s, 1.6 GiB peak

On real submissions

We measured only memory and exit status, and deleted the scored outputs without reading them.

Proposed fix

See the linked PR. It caps each test process's address space at the size it inherits from the evaluator plus 2 GiB, configurable via ROUTERARENA_LCB_MEMORY_HEADROOM_BYTES; 0 disables the limit. Oversized solutions raise MemoryError and fail that test like any other error. 2 GiB is above common judge limits (AtCoder 1 GiB, Codeforces 256 MiB).

Validation of the fix:

  • Both of our files ran through the official llm_evaluation/run.py ... full --force (Python 3.11, uv sync --locked) inside a 16 GiB cgroup with no swap and 4 CPUs.
  • We also evaluated the 385 LiveCodeBench rows of three merged routers with and without the fix:
    • KT-ModelRouter: 0 scores changed, and both runs match the published scores.
    • cruq-router and nadir-cascade-v2: 3 and 2 rows changed.
      • The 0→1 changes match OOM kills that occurred only without the fix.
      • The two 1→0 changes were the same problem (LiveCodeBench_386). Re-run alone three times, it passes 3/3 with and without the fix, so those flips were timeouts under load.

Possible follow-up (not in the PR)

Forked test processes also grow by copying the evaluator's inherited memory, which an address-space limit does not bound. This only became large when many LiveCodeBench rows ran concurrently. Calling gc.freeze() before forking is a common mitigation, but we have not tested it here.

Activity

  1. added a commit that references this issue on Oct 29, 2026
    1945253
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions