コード例 #1
0
ファイル: death_test.cpp プロジェクト: AlexOreshkevich/mongo
void DeathTestImpl::_doTest() {
#ifdef _WIN32
    log() << "Skipping death test on Windows";
    return;
#else
    int pipes[2];
    checkSyscall(pipe(pipes));
    pid_t child;
    checkSyscall(child = fork());
    if (child) {
        checkSyscall(close(pipes[1]));
        char buf[1000];
        std::ostringstream os;
        ssize_t bytesRead;
        while (0 < (bytesRead = read(pipes[0], buf, sizeof(buf)))) {
            os.write(buf, bytesRead);
            invariant(os);
        }
        checkSyscall(bytesRead);
        pid_t pid;
        int stat;
        while (child != (pid = waitpid(child, &stat, 0))) {
            invariant(pid == -1);
            const int err = errno;
            switch (err) {
                case EINTR:
                    continue;
                default:
                    severe() << "Unrecoverable error while waiting for " << child << ": "
                             << errnoWithDescription(err);
                    MONGO_UNREACHABLE;
            }
        }
        if (WIFSIGNALED(stat) || (WIFEXITED(stat) && WEXITSTATUS(stat) != 0)) {
            // Exited with a signal or non-zero code.  Should check the pattern, here,
            // but haven't figured out how, so just return.
            ASSERT_STRING_CONTAINS(os.str(), getPattern());
            return;
        } else {
            invariant(!WIFSTOPPED(stat));
        }
        FAIL("Expected death, found life\n\n") << os.str();
    }

    // This code only executes in the child process.
    checkSyscall(close(pipes[0]));
    checkSyscall(dup2(pipes[1], 1));
    checkSyscall(dup2(1, 2));
    try {
        _test->run();
    } catch (const TestAssertionFailureException& tafe) {
        log() << "Caught test exception while expecting death: " << tafe;
        // To fail the test, we must exit with a successful error code, because the parent process
        // is checking for the child to die with an exit code indicating an error.
        quickExit(EXIT_SUCCESS);
    }
    quickExit(EXIT_SUCCESS);
#endif
}
コード例 #2
0
ファイル: execute.c プロジェクト: arbuztw/judger
int main(int argc, char *argv[])
{
	int tdcount, tlimit, mlimit;
	char exename[1024], inputfile[1024];
	struct rlimit r;

	if (argc < 6)
	{
		printf("Usage: [id] [probid] [input] [time limit] [memory limit]\n");
		exit(RET_SE);
	}

	tlimit = atoi(argv[4]);
	mlimit = atoi(argv[5]);

	sprintf(exename, "./%s", argv[1]);
	strcpy(inputfile, argv[3]);


	if ((pid = fork()) == 0)
	{
		freopen("input.txt", "r", stdin);
		chdir("sandbox");
		chroot(".");
		freopen("output.txt", "w", stdout);
		setregid(99, 99);
		setreuid(99, 99);
		ptrace(PTRACE_TRACEME, 0, NULL, NULL);
		execl(exename, exename, NULL);
		exit(0);
	}
	
	signal(SIGALRM, timer);
	alarm(1);

	int stat, tmpmem, sig;
	for (;;)
	{
		wait4(pid, &stat, 0, &rinfo);
		if (WIFEXITED(stat))
		{
			puts("exited!\n");
			break;
		}
		else if (WIFSTOPPED(stat))
		{
			sig = WSTOPSIG(stat);
			if (sig == SIGTRAP)
			{
					if (checkSyscall() == RET_RF)
					{
						ptrace(PTRACE_KILL, pid, NULL, NULL);
						final_result(RET_RF);
					}
			}
			else if (sig == SIGUSR1)
			{
			}
			else
				printf("Stopped due to signal: %d\n", sig);
		}
		else if (WIFSIGNALED(stat))
		{
			//Runtime Error
			printf("Runtime Error. Received signal: %d\n", WTERMSIG(stat));
			final_result(RET_RE);
			break;
		}
		tmpmem = getMemory();
		if (tmpmem > maxmem) maxmem = tmpmem;

		if (maxmem > mlimit)
			final_result(RET_MLE);
		if (getRuntime() > tlimit)
		{
			ptrace(PTRACE_KILL, pid, NULL, NULL);
			final_result(RET_TLE);
		}
		ptrace(PTRACE_SYSCALL, pid, NULL, NULL);
	}
	final_result(RET_AC);
	
	return 0;
}