This commit is contained in:
prixod
2025-12-01 22:29:25 +04:00
parent 5ed5925a38
commit f5cb2c8e2e
4 changed files with 69 additions and 8 deletions

View File

@@ -14,7 +14,7 @@ public class JavaCompilationServiceIsolate : ICompilationService
private readonly IsolateBoxPool _boxPool; private readonly IsolateBoxPool _boxPool;
private const int CompilationTimeLimitSeconds = 30; private const int CompilationTimeLimitSeconds = 30;
private const int CompilationMemoryLimitMb = 512; private const int CompilationMemoryLimitMb = 1024; // JVM needs more memory
public JavaCompilationServiceIsolate( public JavaCompilationServiceIsolate(
ILogger<JavaCompilationServiceIsolate> logger, ILogger<JavaCompilationServiceIsolate> logger,
@@ -85,6 +85,7 @@ public class JavaCompilationServiceIsolate : ICompilationService
arguments.Add($"/box/{sourceFileName}"); arguments.Add($"/box/{sourceFileName}");
var stderrFilePath = Path.Combine(boxDir, "compile_stderr.txt"); var stderrFilePath = Path.Combine(boxDir, "compile_stderr.txt");
var stdoutFilePath = Path.Combine(boxDir, "compile_stdout.txt");
var isolateResult = await _isolateService.RunAsync(new IsolateRunOptions var isolateResult = await _isolateService.RunAsync(new IsolateRunOptions
{ {
@@ -94,28 +95,57 @@ public class JavaCompilationServiceIsolate : ICompilationService
TimeLimitSeconds = CompilationTimeLimitSeconds, TimeLimitSeconds = CompilationTimeLimitSeconds,
WallTimeLimitSeconds = CompilationTimeLimitSeconds * 2, WallTimeLimitSeconds = CompilationTimeLimitSeconds * 2,
MemoryLimitKb = CompilationMemoryLimitMb * 1024, MemoryLimitKb = CompilationMemoryLimitMb * 1024,
StackLimitKb = 256 * 1024, StackLimitKb = 128 * 1024, // 128MB stack per process
ProcessLimit = 10, // javac may spawn multiple processes ProcessLimit = 64, // JVM needs many threads/processes
EnableNetwork = false, EnableNetwork = false,
StdoutFile = stdoutFilePath,
StderrFile = stderrFilePath, StderrFile = stderrFilePath,
WorkingDirectory = "/box", WorkingDirectory = "/box",
DirectoryBindings = new List<DirectoryBinding> DirectoryBindings = new List<DirectoryBinding>
{ {
new DirectoryBinding { HostPath = "/usr/bin", SandboxPath = "/usr/bin", ReadOnly = true },
new DirectoryBinding { HostPath = "/usr/lib", SandboxPath = "/usr/lib", ReadOnly = true }, new DirectoryBinding { HostPath = "/usr/lib", SandboxPath = "/usr/lib", ReadOnly = true },
new DirectoryBinding { HostPath = "/lib", SandboxPath = "/lib", ReadOnly = true } new DirectoryBinding { HostPath = "/lib", SandboxPath = "/lib", ReadOnly = true },
new DirectoryBinding { HostPath = "/lib64", SandboxPath = "/lib64", ReadOnly = true },
new DirectoryBinding { HostPath = "/etc", SandboxPath = "/etc", ReadOnly = true }
} }
}); });
var compilerOutput = string.Empty; var compilerOutput = string.Empty;
// Read stdout (javac may output errors there)
if (File.Exists(stdoutFilePath))
{
var stdoutContent = await File.ReadAllTextAsync(stdoutFilePath);
if (!string.IsNullOrWhiteSpace(stdoutContent))
{
compilerOutput = stdoutContent;
_logger.LogDebug("Read stdout file: {Length} bytes", stdoutContent.Length);
}
}
// Read stderr
if (File.Exists(stderrFilePath)) if (File.Exists(stderrFilePath))
{ {
compilerOutput = await File.ReadAllTextAsync(stderrFilePath); var stderrContent = await File.ReadAllTextAsync(stderrFilePath);
if (!string.IsNullOrWhiteSpace(stderrContent))
{
compilerOutput = string.IsNullOrEmpty(compilerOutput)
? stderrContent
: $"{compilerOutput}\n{stderrContent}";
_logger.LogDebug("Read stderr file: {Length} bytes", stderrContent.Length);
} }
}
if (!string.IsNullOrEmpty(isolateResult.ErrorOutput)) if (!string.IsNullOrEmpty(isolateResult.ErrorOutput))
{ {
compilerOutput = $"{compilerOutput}\n{isolateResult.ErrorOutput}".Trim(); compilerOutput = string.IsNullOrEmpty(compilerOutput)
? isolateResult.ErrorOutput
: $"{compilerOutput}\n{isolateResult.ErrorOutput}";
} }
_logger.LogDebug("Final compiler output: {Output}", compilerOutput);
if (isolateResult.TimeLimitExceeded) if (isolateResult.TimeLimitExceeded)
{ {
_logger.LogWarning("Java compilation time limit exceeded for box {BoxId}", boxId); _logger.LogWarning("Java compilation time limit exceeded for box {BoxId}", boxId);

View File

@@ -84,7 +84,15 @@ public class JavaExecutionServiceIsolate : IExecutionService
EnableNetwork = false, EnableNetwork = false,
StdinFile = sandboxInputPath, StdinFile = sandboxInputPath,
StdoutFile = outputFilePath, StdoutFile = outputFilePath,
WorkingDirectory = "/box" WorkingDirectory = "/box",
DirectoryBindings = new List<DirectoryBinding>
{
new DirectoryBinding { HostPath = "/usr/bin", SandboxPath = "/usr/bin", ReadOnly = true },
new DirectoryBinding { HostPath = "/usr/lib", SandboxPath = "/usr/lib", ReadOnly = true },
new DirectoryBinding { HostPath = "/lib", SandboxPath = "/lib", ReadOnly = true },
new DirectoryBinding { HostPath = "/lib64", SandboxPath = "/lib64", ReadOnly = true },
new DirectoryBinding { HostPath = "/etc", SandboxPath = "/etc", ReadOnly = true }
}
}); });
stopwatch.Stop(); stopwatch.Stop();

View File

@@ -1,3 +1,4 @@
using System.Collections.Generic;
using LiquidCode.Tester.Worker.Services.Isolate; using LiquidCode.Tester.Worker.Services.Isolate;
using LiquidCode.Tester.Worker.Models; using LiquidCode.Tester.Worker.Models;
@@ -106,7 +107,15 @@ public class KotlinCompilationServiceIsolate : ICompilationService
{ {
new DirectoryBinding { HostPath = "/usr/lib", SandboxPath = "/usr/lib", ReadOnly = true }, new DirectoryBinding { HostPath = "/usr/lib", SandboxPath = "/usr/lib", ReadOnly = true },
new DirectoryBinding { HostPath = "/lib", SandboxPath = "/lib", ReadOnly = true }, new DirectoryBinding { HostPath = "/lib", SandboxPath = "/lib", ReadOnly = true },
new DirectoryBinding { HostPath = "/lib64", SandboxPath = "/lib64", ReadOnly = true },
new DirectoryBinding { HostPath = "/usr/bin", SandboxPath = "/usr/bin", ReadOnly = true },
new DirectoryBinding { HostPath = "/bin", SandboxPath = "/bin", ReadOnly = true },
new DirectoryBinding { HostPath = "/etc", SandboxPath = "/etc", ReadOnly = true },
new DirectoryBinding { HostPath = "/opt/kotlinc", SandboxPath = "/opt/kotlinc", ReadOnly = true } new DirectoryBinding { HostPath = "/opt/kotlinc", SandboxPath = "/opt/kotlinc", ReadOnly = true }
},
EnvironmentVariables = new Dictionary<string, string>
{
["PATH"] = "/usr/local/bin:/usr/bin:/bin"
} }
}); });

View File

@@ -1,4 +1,5 @@
using System.Diagnostics; using System.Diagnostics;
using System.Collections.Generic;
using LiquidCode.Tester.Worker.Services.Isolate; using LiquidCode.Tester.Worker.Services.Isolate;
namespace LiquidCode.Tester.Worker.Services; namespace LiquidCode.Tester.Worker.Services;
@@ -78,7 +79,20 @@ public class KotlinExecutionServiceIsolate : IExecutionService
EnableNetwork = false, EnableNetwork = false,
StdinFile = sandboxInputPath, StdinFile = sandboxInputPath,
StdoutFile = outputFilePath, StdoutFile = outputFilePath,
WorkingDirectory = "/box" WorkingDirectory = "/box",
DirectoryBindings = new List<DirectoryBinding>
{
new DirectoryBinding { HostPath = "/usr/lib", SandboxPath = "/usr/lib", ReadOnly = true },
new DirectoryBinding { HostPath = "/lib", SandboxPath = "/lib", ReadOnly = true },
new DirectoryBinding { HostPath = "/lib64", SandboxPath = "/lib64", ReadOnly = true },
new DirectoryBinding { HostPath = "/usr/bin", SandboxPath = "/usr/bin", ReadOnly = true },
new DirectoryBinding { HostPath = "/bin", SandboxPath = "/bin", ReadOnly = true },
new DirectoryBinding { HostPath = "/etc", SandboxPath = "/etc", ReadOnly = true }
},
EnvironmentVariables = new Dictionary<string, string>
{
["PATH"] = "/usr/local/bin:/usr/bin:/bin"
}
}); });
stopwatch.Stop(); stopwatch.Stop();