From 4ed09642de7ced5ad304dc91d85ce357bbdc095b Mon Sep 17 00:00:00 2001 From: springhack Date: Fri, 25 Nov 2016 14:06:09 +0800 Subject: [PATCH] zoj memory --- Makefile | 2 +- src/config.h | 6 +++--- src/limit.c | 12 ++++++++---- src/proc.c | 28 +++++++++++++++++++++++++++- src/run.c | 41 +++++++++++++++++++++++++++-------------- 5 files changed, 66 insertions(+), 23 deletions(-) diff --git a/Makefile b/Makefile index ac039df..360a625 100755 --- a/Makefile +++ b/Makefile @@ -1,2 +1,2 @@ all: - gcc src/main.c src/cjson/cJSON.c -lm -o runner + gcc src/main.c src/cjson/cJSON.c -lm -static -o runner diff --git a/src/config.h b/src/config.h index 95c1b69..0545d8d 100755 --- a/src/config.h +++ b/src/config.h @@ -6,6 +6,8 @@ int SYS_CALLS[256] = {0, 1, 2, 3, 4, 5, 8, 9, 10, 11, 12, 21, 59, 63, 89, 158, 201, 205, 231, 240, 252, 0}; #endif +u_char calls[256]; + #define BUFF_SIZE 1024 #define CALLS_MAX 400 @@ -23,8 +25,6 @@ #define REG_ARG_2(x) ((x)->ecx) #endif -u_char calls[400]; - enum JUDGE_RESULT { AC = 0, //0 Accepted PE, //1 Presentation Error @@ -54,7 +54,7 @@ void initcall() { printf(" %d", SYS_CALLS[i]); calls[SYS_CALLS[i]] = 1; - i++; + i++; } printf("\n"); } diff --git a/src/limit.c b/src/limit.c index ec37c0d..eaf8283 100755 --- a/src/limit.c +++ b/src/limit.c @@ -9,23 +9,27 @@ int setResLimit(int time_limit, int memory_limit, int java) if (time_limit % 1000 > 800) rl.rlim_cur += 1; rl.rlim_max = rl.rlim_cur + 1; - setrlimit(RLIMIT_CPU, &rl); + if (setrlimit(RLIMIT_CPU, &rl)) + return -1; rl.rlim_cur = memory_limit * 1024; rl.rlim_max = rl.rlim_cur + 1024; - setrlimit(RLIMIT_DATA, &rl); + if (setrlimit(RLIMIT_DATA, &rl)) + return -1; //Support java if (java == 0) { rl.rlim_cur = memory_limit * 1024 * 2; rl.rlim_max = rl.rlim_cur + 1024; - setrlimit(RLIMIT_AS, &rl); + if (setrlimit(RLIMIT_AS, &rl)) + return -1; } rl.rlim_cur = 256 * 1024 * 1024; rl.rlim_max = rl.rlim_cur + 1024; - setrlimit(RLIMIT_STACK, &rl); + if (setrlimit(RLIMIT_STACK, &rl)) + return -1; return 0; } diff --git a/src/proc.c b/src/proc.c index fd7a8ad..aa97e86 100755 --- a/src/proc.c +++ b/src/proc.c @@ -23,7 +23,6 @@ int get_proc_status(int pid, const char * mark) { pf = fopen(fn, "re"); int m = strlen(mark); while (pf && fgets(buf, BUFFER_SIZE - 1, pf)) { - buf[strlen(buf) - 1] = 0; if (strncmp(buf, mark, m) == 0) { sscanf(buf + m + 1, "%d", &ret); @@ -39,3 +38,30 @@ int get_page_fault_mem(struct rusage ruse, pid_t pidApp) { m_minflt = ruse.ru_minflt * getpagesize(); return (m_minflt >> 10); } + +int ReadMemoryConsumption(pid_t pid) { + char buffer[64]; + sprintf(buffer, "/proc/%d/status", pid); + FILE* fp = fopen(buffer, "r"); + if (fp == NULL) { + return -1; + } + int vmPeak = 0, vmSize = 0, vmExe = 0, vmLib = 0, vmStack = 0; + while (fgets(buffer, 32, fp)) { + if (!strncmp(buffer, "VmPeak:", 7)) { + sscanf(buffer + 7, "%d", &vmPeak); + } else if (!strncmp(buffer, "VmSize:", 7)) { + sscanf(buffer + 7, "%d", &vmSize); + } else if (!strncmp(buffer, "VmExe:", 6)) { + sscanf(buffer + 6, "%d", &vmExe); + } else if (!strncmp(buffer, "VmLib:", 6)) { + sscanf(buffer + 6, "%d", &vmLib); + } else if (!strncmp(buffer, "VmStk:", 6)) { + sscanf(buffer + 6, "%d", &vmStack); + } + } + fclose(fp); + if (vmPeak) + vmSize = vmPeak; + return vmSize - vmExe - vmLib - vmStack; +} diff --git a/src/run.c b/src/run.c index e3a86bf..99b50bf 100755 --- a/src/run.c +++ b/src/run.c @@ -14,10 +14,9 @@ #include "access.c" #include "limit.c" -void error(const char *err) -{ - //TODO -} +char *err_str = NULL; + +#define ERROR(X) { err_str = (X); break; } int traceLoop(int java, int time_limit, int memory_limit, pid_t pid, struct Result *rst) { @@ -26,20 +25,21 @@ int traceLoop(int java, int time_limit, int memory_limit, pid_t pid, struct Resu struct rusage ru; struct user_regs_struct regs; - rst->memory_used = get_proc_status(pid, "VmRSS:"); + rst->memory_used = ReadMemoryConsumption(pid);//get_proc_status(pid, "VmRSS:"); rst->judge_result = AC; while (1) { if (wait4(pid, &status, 0, &ru) == -1) - error("wait4 [WSTOPPED] failure"); + ERROR("wait4 [WSTOPPED] failure"); //Get memory if (java) + //Is OK? I don't know memory = get_page_fault_mem(ru, pid); else - memory = get_proc_status(pid, "VmPeak:"); + memory = ReadMemoryConsumption(pid);//get_proc_status(pid, "VmPeak:"); if (memory > rst->memory_used) rst->memory_used = memory; @@ -114,7 +114,7 @@ int traceLoop(int java, int time_limit, int memory_limit, pid_t pid, struct Resu } if (ptrace(PTRACE_GETREGS, pid, NULL, ®s) == -1) - error("PTRACE_GETREGS failure"); + ERROR("PTRACE_GETREGS failure"); if (incall && !java) { int ret = checkAccess(pid, ®s); @@ -154,7 +154,8 @@ int run(const char * argv[], const char* fd_in, const char* fd_out, const char* pid_t pid = fork(); if (pid < 0) { - error("Fork error"); + while (1) + ERROR("Fork error"); return 1; } @@ -163,9 +164,12 @@ int run(const char * argv[], const char* fd_in, const char* fd_out, const char* freopen(fd_in, "r", stdin); freopen(fd_out, "w", stdout); freopen(fd_err, "w", stderr); - setResLimit(time, memory, java); - ptrace(PTRACE_TRACEME, 0, NULL, NULL); + if (setResLimit(time, memory, java) == -1) + exit(1); + if (ptrace(PTRACE_TRACEME, 0, NULL, NULL) == -1) + exit(1); execvp(argv[0], (char * const *)argv); + exit(1); } else { int t = nice(19); t = traceLoop(java, time, memory, pid, rst); @@ -193,12 +197,21 @@ char* runit(const char* json) struct Result rst; + err_str = NULL; + int ret = run((const char **)argv, fd_in, fd_out, fd_err, java, time, memory, &rst); cJSON *fmt = cJSON_CreateObject(); - cJSON_AddNumberToObject(fmt, "timeused", rst.time_used); - cJSON_AddNumberToObject(fmt, "memoryused", rst.memory_used); - cJSON_AddNumberToObject(fmt, "result", rst.judge_result); + if (err_str != NULL) + { + cJSON_AddNumberToObject(fmt, "timeused", 0); + cJSON_AddNumberToObject(fmt, "memoryused", 0); + cJSON_AddNumberToObject(fmt, "result", SE); + } else { + cJSON_AddNumberToObject(fmt, "timeused", rst.time_used); + cJSON_AddNumberToObject(fmt, "memoryused", rst.memory_used); + cJSON_AddNumberToObject(fmt, "result", rst.judge_result); + } char * r = cJSON_Print(fmt);