-
Notifications
You must be signed in to change notification settings - Fork 78
Open
Description
When setting memory_limit_MB to be not -1, we encounter exception:
{"status":"SandboxError","message":"exception on running command python /tmp/tmpmn1cjrq6/tmpzw8a2ydp.py: Exception occurred in preexec_fn. | None","compile_result":null,"run_result":{"status":"Error","execution_time":null,"return_code":null,"stdout":null,"stderr":"exception on running command python /tmp/tmpmn1cjrq6/tmpzw8a2ydp.py: Exception occurred in preexec_fn. | None"},"executor_pod_name":null,"files":{}}%
To determine the root cause, I put a try/except block inside the preexec_fn to catch the error.
We see:
2025-12-11 21:09:52 [debug ] running command python /tmp/tmpvwksj3in/tmpy4x_jjk6.py [sandbox.runners.base]
/root/miniconda3/lib/python3.11/site-packages/structlog/stdlib.py:1087: UserWarning: Remove `format_exc_info` from your processor chain if you want pretty exceptions.
ed = p(logger, meth_name, cast(EventDict, ed))
2025-12-11 21:09:52 [error ] memory_limit_preexec failed [sandbox.runners.base] error=current limit exceeds maximum limit error_type=ValueError
Traceback (most recent call last):
File "/root/sandbox/sandbox/runners/base.py", line 136, in memory_limit_preexec
resource.setrlimit(resource.RLIMIT_STACK, (soft_memory_limit, hard_memory_limit_STACK))
ValueError: current limit exceeds maximum limit
File "/root/sandbox/sandbox/runners/base.py", line 58, in run_command_bare
p = await asyncio.create_subprocess_shell(command,
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/root/miniconda3/lib/python3.11/asyncio/subprocess.py", line 208, in create_subprocess_shell
transport, protocol = await loop.subprocess_shell(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "uvloop/loop.pyx", line 2808, in subprocess_shell
File "uvloop/loop.pyx", line 2778, in __subprocess_run
File "uvloop/handles/process.pyx", line 611, in uvloop.loop.UVProcessTransport.new
File "uvloop/handles/process.pyx", line 172, in uvloop.loop.UVProcess._init
2025-12-11 21:09:52 [warning ] exception on running command python /tmp/tmpvwksj3in/tmpy4x_jjk6.py: Exception occurred in preexec_fn. | None [sandbox.runners.base]
The issue lies here:
SandboxFusion/sandbox/runners/base.py
Lines 126 to 137 in 5e37f71
| if args.memory_limit_MB > 0: | |
| def memory_limit_preexec(): | |
| _, hard_memory_limit_AS = resource.getrlimit(resource.RLIMIT_AS) | |
| _, hard_memory_limit_DATA = resource.getrlimit(resource.RLIMIT_DATA) | |
| soft_memory_limit = args.memory_limit_MB * 1024 * 1024 | |
| resource.setrlimit(resource.RLIMIT_AS, (soft_memory_limit, hard_memory_limit_AS)) | |
| resource.setrlimit(resource.RLIMIT_DATA, (soft_memory_limit, hard_memory_limit_DATA)) | |
| if platform.uname().system != "Darwin": | |
| _, hard_memory_limit_STACK = resource.getrlimit(resource.RLIMIT_STACK) | |
| resource.setrlimit(resource.RLIMIT_STACK, (soft_memory_limit, hard_memory_limit_STACK)) | |
| preexec_steps.insert(0, memory_limit_preexec) | |
| preexec_fn = lambda: [step() for step in preexec_steps] if preexec_steps else None |
It seems SandboxFusion tries to allocated the desired memory in the Address Space, Data, and Stack.
However, the Stack typically has a process-set maximum of much less than 1GB for example.
Therefore, exception is thrown due to an inability to update the Stack memory limit.
To fix this, I replaced:
def memory_limit_preexec():
_, hard_memory_limit_AS = resource.getrlimit(resource.RLIMIT_AS)
_, hard_memory_limit_DATA = resource.getrlimit(resource.RLIMIT_DATA)
soft_memory_limit = args.memory_limit_MB * 1024 * 1024
resource.setrlimit(resource.RLIMIT_AS, (soft_memory_limit, hard_memory_limit_AS))
resource.setrlimit(resource.RLIMIT_DATA, (soft_memory_limit, hard_memory_limit_DATA))
if platform.uname().system != "Darwin":
_, hard_memory_limit_STACK = resource.getrlimit(resource.RLIMIT_STACK)
resource.setrlimit(resource.RLIMIT_STACK, (soft_memory_limit, hard_memory_limit_STACK))
with
def memory_limit_preexec():
try:
_, hard_memory_limit_AS = resource.getrlimit(resource.RLIMIT_AS)
_, hard_memory_limit_DATA = resource.getrlimit(resource.RLIMIT_DATA)
soft_memory_limit = args.memory_limit_MB * 1024 * 1024
resource.setrlimit(resource.RLIMIT_AS, (soft_memory_limit, hard_memory_limit_AS))
resource.setrlimit(resource.RLIMIT_DATA, (soft_memory_limit, hard_memory_limit_DATA))
if platform.uname().system != "Darwin":
_, hard_memory_limit_STACK = resource.getrlimit(resource.RLIMIT_STACK)
soft_stack_limit = min(soft_memory_limit, hard_memory_limit_STACK)
resource.setrlimit(resource.RLIMIT_STACK, (soft_stack_limit, hard_memory_limit_STACK))
except Exception as e:
logger.error(
"memory_limit_preexec failed",
error_type=type(e).__name__,
error=str(e),
exc_info=True,
)
raise
Metadata
Metadata
Assignees
Labels
No labels