google-deepmind / code_contests

Apache License 2.0
2.04k stars 200 forks source link

SANDBOX VIOLATION #14

Closed AryazE closed 2 years ago

AryazE commented 2 years ago

I have written a file similar to solve_example.cc to run all solutions to problems in a files. However, I get the following output:

1548_C. The Three Little Pigs [global_forkclient.cc : 122] RAW: Starting global forkserver WARNING: Logging before InitGoogleLogging() is written to STDERR E20220420 15:38:49.259812 589011 monitor.cc:842] SANDBOX VIOLATION : PID: 589016, PROG: 'python3.9' : [X86-64] arch_prctl [158](0x3001 [12289], 0x7ffc9bfbd5b0) IP: 0x7f936cdefbe5, STACK: 0x7ffc9bfbd560 I20220420 15:38:49.259986 589011 monitor.cc:386] Stack traces have been disabled Compilation failed

I tried to only run it on one thread, but I still get the same result. Below is my code:

#include <iostream>
#include <tuple>
#include <vector>

#include "absl/strings/string_view.h"
#include "absl/types/span.h"
#include "contest_problem.pb.h"
#include "riegeli/bytes/fd_reader.h"
#include "riegeli/records/record_reader.h"

#include <fcntl.h>

#include <functional>
#include <iostream>
#include <string>
#include <tuple>
#include <vector>

#include "absl/flags/parse.h"
#include "absl/flags/flag.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/string_view.h"
#include "absl/types/span.h"
#include "contest_problem.pb.h"
#include "execution/py_locations.h"
#include "execution/py_tester_sandboxer.h"
#include "execution/status_macros.h"
#include "execution/tester_sandboxer.h"
#include "riegeli/bytes/fd_reader.h"
#include "riegeli/records/record_reader.h"

ABSL_FLAG(std::string, valid_path, "", "Path to validation dataset.");

namespace deepmind::code_contests {
namespace {

std::vector<absl::string_view> GetInputs(const ContestProblem& problem,
                                         int max_size) {
  std::vector<absl::string_view> inputs;
  for (const auto& test : problem.public_tests()) {
    inputs.push_back(test.input());
  }
  for (const auto& test : problem.private_tests()) {
    inputs.push_back(test.input());
  }
  for (const auto& test : problem.generated_tests()) {
    inputs.push_back(test.input());
  }
  inputs.resize(max_size);
  return inputs;
}

std::vector<absl::string_view> GetOutputs(const ContestProblem& problem,
                                          int max_size) {
  std::vector<absl::string_view> outputs;
  for (const auto& test : problem.public_tests()) {
    outputs.push_back(test.output());
  }
  for (const auto& test : problem.private_tests()) {
    outputs.push_back(test.output());
  }
  for (const auto& test : problem.generated_tests()) {
    outputs.push_back(test.output());
  }
  outputs.resize(max_size);
  return outputs;
}

void ReportResults(const MultiTestResult& multi_result) {
  std::cout << "Compilation "
            << (multi_result.compilation_result.program_status ==
                        ProgramStatus::kSuccess
                    ? "succeeded"
                    : "failed")
            << "\n";
  int i = 0;
  for (const auto& test_result : multi_result.test_results) {
    if (!test_result.passed.has_value()) {
      std::cout << "Test " << i << " did not run.\n";
    } else if (*test_result.passed) {
      std::cout << "Test " << i << " passed.\n";
    } else {
      std::cout << "Test " << i << " failed.\n";
    }
    ++i;
  }
}

absl::Status SolveProblem(
    const absl::string_view valid_filename, ContestProblem problem) {
  const std::vector<absl::string_view> inputs =
      GetInputs(problem,
                /*max_size=*/10);
  const std::vector<absl::string_view> outputs =
      GetOutputs(problem,
                 /*max_size=*/10);

  Py3TesterSandboxer tester(Py3InterpreterPath(), Py3LibraryPaths());
  TestOptions options;
  options.num_threads = 4;
  options.stop_on_first_failure = false;

  for (int i = 0; i < problem.incorrect_solutions_size(); i++)
  {
    const absl::string_view code = problem.incorrect_solutions(i).solution();

    ASSIGN_OR_RETURN(MultiTestResult bad_result,
                   tester.Test(code, inputs, options, outputs));
    ReportResults(bad_result);
  }

  for (int i = 0; i < problem.solutions_size(); i++)
  {
    const absl::string_view code = problem.solutions(i).solution();
    ASSIGN_OR_RETURN(MultiTestResult good_result,
                    tester.Test(code, inputs, options, outputs));
    ReportResults(good_result);
  }

  return absl::OkStatus();
}

}  // namespace
}  // namespace deepmind::code_contests

namespace {

using ::deepmind::code_contests::ContestProblem;

void PrintNames(const absl::Span<const absl::string_view> filenames) {
  for (const absl::string_view filename : filenames) {
    riegeli::RecordReader<riegeli::FdReader<>> reader(
        std::forward_as_tuple(filename));
    ContestProblem problem;
    while (reader.ReadRecord(problem)) {
      std::cout << problem.name() << '\n';
      ::deepmind::code_contests::SolveProblem(filename, problem);
    }
    reader.Close();
  }
}

}  // namespace

int main(int argc, char* argv[]) {
  std::vector<absl::string_view> filenames;
  filenames.reserve(argc - 1);
  for (int i = 1; i < argc; ++i) {
    filenames.push_back(argv[i]);
  }
  PrintNames(filenames);
}
davidhchoi commented 2 years ago

It looks like you're running the incorrect and correct solutions attached to the problem itself. Some of these will naturally fail compilation, or will produce sandbox violations, especially if they are incorrect. Even for correct ones, our sandbox does not exactly match the ones used in competitive programming, because each contest provides different libraries and allows different syscalls (that may cause sandbox violations for us).

These shouldn't cause the SolveProblem code itself to crash though, and it seems like it doesn't since it manages to output Compilation failed.