criyle / go-judge Goto Github PK
View Code? Open in Web Editor NEWSandbox Server in REST / gRPC API. Based on Linux container technologies.
License: MIT License
Sandbox Server in REST / gRPC API. Based on Linux container technologies.
License: MIT License
在执行
docker run -it --rm --privileged --shm-size=256m -p 5050:5050 criyle/executorserver
的过程中,我遇到了问题,已经执行了centos7的配置文件命令
下面是日志
[root@host-59-74-224-30 ~]# echo user.max_user_namespaces=10000 >> /etc/sysctl.d/98-userns.conf
[root@host-59-74-224-30 ~]# sysctl -p
net.ipv4.ip_forward = 1
[root@host-59-74-224-30 ~]# echo user.max_user_namespaces=10000 >> /etc/sysctl.d/98-userns.conf
[root@host-59-74-224-30 ~]# docker run -it --rm --privileged --shm-size=256m -p 5050:5050 criyle/executorserver
{"level":"info","ts":1667879810.046213,"caller":"executorserver/main.go:62","msg":"config loaded: &{ContainerInitPath: PreFork:1 TmpFsParam:size=128m,nr_inodes=4k NetShare:false MountConf:mount.yaml SeccompConf:seccomp.yaml Parallelism:16 CgroupPrefix:executor_server ContainerCredStart:0 SrcPrefix: Dir: TimeLimitCheckerInterval:100ms ExtraMemoryLimit:16.0 KiB OutputLimit:256.0 MiB CopyOutLimit:64.0 MiB OpenFileLimit:256 Cpuset: EnableCPURate:false CPUCfsPeriod:100ms FileTimeout:0s HTTPAddr::5050 EnableGRPC:false GRPCAddr::5051 MonitorAddr::5052 AuthToken: EnableDebug:false EnableMetrics:false Release:true Silent:false ForceGCTarget:20.0 MiB ForceGCInterval:5s Version:false}"}
{"level":"info","ts":1667879810.0463336,"caller":"executorserver/main.go:273","msg":"random seed: 2408806125596027837"}
{"level":"info","ts":1667879810.0476985,"caller":"env/env_linux.go:59","msg":"Created container mount at:Mounts: bind[/bin:bin:ro], bind[/lib:lib:ro], bind[/lib64:lib64:ro], bind[/usr:usr:ro], bind[/etc/ld.so.cache:etc/ld.so.cache:ro], bind[/etc/alternatives:etc/alternatives:ro], bind[/dev/null:dev/null:rw], bind[/dev/urandom:dev/urandom:rw], bind[/dev/random:dev/random:rw], bind[/dev/zero:dev/zero:rw], bind[/dev/full:dev/full:rw], tmpfs[w], tmpfs[tmp], proc[ro]"}
{"level":"info","ts":1667879810.0477355,"caller":"env/env_linux.go:76","msg":"Kernel version (3.10) < 4.6, don't unshare cgroup"}
{"level":"info","ts":1667879810.0477455,"caller":"env/env_linux.go:97","msg":"Creating container builder: hostName=executor_server, domainName=executor_server, workDir=/w"}
{"level":"info","ts":1667879810.0478673,"caller":"env/env_linux.go:129","msg":"Test created cgroup builder with: cgroup builder(v1): [cpuset, cpuacct, memory, pids]"}
{"level":"info","ts":1667879810.0675452,"caller":"executorserver/main.go:281","msg":"create 1 prefork containers"}
2022/11/08 03:56:50 prefork environment failed container: failed to start container fork/exec /proc/self/exe: invalid argument
以docker容器运行4天之后,突然对所有请求(包括以前正常的请求)都返回File Error,error
字段内容:
write /dev/shm/executorserver796031983/JWUUBQBH: no space left on device
重启容器之后恢复正常。
看起来是内存不足,但错误发生时记了一下内存信息,挺充足的:
total used free shared buff/cache available
Mem: 62Gi 8.2Gi 3.9Gi 30Mi 50Gi 53Gi
Swap: 15Gi 0.0Ki 15Gi
由于重启后恢复正常,没有记录下更多信息。请大佬帮忙看下可能是什么问题导致?
在使用除 gRPC 外其他传输层时(HTTP / WebSocket / FFI 等)时,数据都是以 JSON 方式传递的,然而 struct CmdFile 里的 Content 被声明称了 *string
类型:
go-judge/cmd/executorserver/model/model.go
Lines 14 to 22 in e5c7b81
也就是说,似乎是没办法把一个二进制文件作为调用 /run
时的 copyIn 直接扔到沙盒里去.我尝试了下面几种方法:
json: cannot unmarshal object into Go struct field CmdFile.cmd.files.content of type string
.buffer.toString('binary')
,这样倒是可以传进沙盒,但是沙盒里面的文件会变,比如一个值(十进制)为 如果仅是这样那么问题还不是很大,至少可以通过 file post 先把文件传入沙盒,再用 fileId 来在 cmd 中使用文件.但是 FFI 传输层中的 FileAdd
仍然是接受 JSON 字符串作为参数.也就是说,在使用 FFI 时,这个问题目前无解.
顺便提个建议,由于存在二进制文件,且 JSON 里没有对应 byte 的类型,JSON 不太适合作为这个项目的信息传输格式.在假设把 CmdFile 里的 Content 重构成 []byte
类型后,一个 byte 在 JSON 中会占用四个 byte 的空间(包含三个十进制数位和一个逗号),因此建议采用一些更加适合的格式.需要注意的是,BSON 由于其 16 MB 的最大文档大小,同样也不是一个适合的格式.或许 MessagePack 是一个较优的选择.
请问这个上传文件的api /file POST 在上传一个文件时报错
ERROR [email protected]/zap.go:62 http: no such file github.com/gin-contrib/zap.GinzapWithConfig.func1 /home/runner/go/pkg/mod/github.com/gin-contrib/[email protected]/zap.go:62 github.com/gin-gonic/gin.(*Context).Next /home/runner/go/pkg/mod/github.com/gin-gonic/[email protected]/context.go:168 github.com/gin-gonic/gin.(*Engine).handleHTTPRequest /home/runner/go/pkg/mod/github.com/gin-gonic/[email protected]/gin.go:555 github.com/gin-gonic/gin.(*Engine).ServeHTTP /home/runner/go/pkg/mod/github.com/gin-gonic/[email protected]/gin.go:511 net/http.serverHandler.ServeHTTP /opt/hostedtoolcache/go/1.17.7/x64/src/net/http/server.go:2879 net/http.(*conn).serve /opt/hostedtoolcache/go/1.17.7/x64/src/net/http/server.go:1930
这个应该怎么解决。或者说可以提供一个关于文件上传的demo吗,谢谢!
如果代码中有使用了多个类,例如内部类,new一个类,那么编译后会形成多个class文件,例如Main.class, Main$sc.class....,这样的多个文件, copyOutCached很难明确指明每个class的名称,编译后只能返回Main.class的FileId,再次发送Main.class的FileId进行java Main运行的请求,就会出现ClassNotFound的报错,可能新的请求已经不在原来编译的文件夹进行运行了,所以代码中那些类的class文件已经丢失或不在新的请求创建的文件夹里面,那该如何解决这个问题呢?
我在window上运行测试环境,在cmd中启动沙盒,启动参数参数为executorserver_1.6.8_windows_amd64.exe -dir ./test
由于copyOutDir
使用相对定位转存文件,同时在windows中的临时目录不容易定位,所以使用了-dir 设置为本地缓存(也测试不使用-dir 参数启动,但转存的文件同样是空(文件大小为0KB))
为了避免可能是因为windows权限的问题,在使用-dir ./test 测试时,已经提前将test文件夹的权限设置为了任何用户都可以读写
也测试过以管理员方式启动cmd,然后启动沙盒,但是发现同样转存的文件为空(文件大小为0KB)
下面提交的参数
{
"cmd": [
{
"args": [
"D:/JudgeEnvs/Cpp/mingw64/bin/g++",
"-std=c++14",
"main.cpp",
"-o",
"main.exe"
],
"env": [
"LANG=en_US.UTF-8",
"LC_ALL=en_US.UTF-8",
"LANGUAGE=en_US:en",
"PATH=D:/JudgeEnvs/Cpp/mingw64/bin"
],
"files": [
{
"content": ""
},
{
"name": "stdout",
"max": 33554432
},
{
"name": "stderr",
"max": 33554432
}
],
"cpuLimit": 10000000000,
"clockLimit": 10000000000,
"memoryLimit": 536870912,
"procLimit": 128,
"stackLimit": 268435456,
"copyIn": {
"main.cpp": {
"content": "#include<iostream>\nusing namespace std;\n\nint main() {\n string s;\n cin>>s;\n cout<<s<<endl;\n \n return 0;\n}"
}
},
"copyOut": [
"stdout",
"stderr"
],
"copyOutCached": [
],
"copyOutDir": "123456"
}
]
}
返回的参数
[
{
"status": "Accepted",
"exitStatus": 0,
"time": 359375000,
"memory": 53260288,
"runTime": 0,
"files": {
"stderr": "",
"stdout": ""
}
}
]
首先,感谢您提供的优质开源Code,下面是我的问题:
系统:CentOS 8.2 64位
安装方式:docker run -it --rm --privileged --shm-size=256m -p 5050:5050 criyle/executorserver
执行压力测试通过,使用压力测试的post也能accept
但使用postman测试示例中的单文件编译运行时出错,已安装g++
提交内容:
{
"cmd": [{
"args": ["/usr/bin/g++", "a.cc", "-o", "a"],
"env": ["PATH=/usr/bin:/bin"],
"files": [{
"content": ""
}, {
"name": "stdout",
"max": 10240
}, {
"name": "stderr",
"max": 10240
}],
"cpuLimit": 10000000000,
"memoryLimit": 104857600,
"procLimit": 50,
"copyIn": {
"a.cc": {
"content": "#include \nusing namespace std;\nint main() {\nint a, b;\ncin >> a >> b;\ncout << a + b << endl;\n}"
}
},
"copyOut": ["stdout", "stderr"],
"copyOutCached": ["a.cc", "a"],
"copyOutDir": "1"
}]
}
返回结果:
[
{
"status": "Internal Error",
"exitStatus": 0,
"error": "execve: start: execve: no such file or directory",
"time": 319510,
"memory": 0,
"runTime": 0,
"files": {
"stderr": "",
"stdout": ""
},
"fileIds": {
"a.cc": "C4IBYMMQ"
},
"fileError": [
{
"name": "a",
"type": "CopyOutOpen",
"message": "open a: no such file or directory"
}
]
}
]
使用file接口查询发现没有生成a文件,请问是什么原因或有什么解决方案,劳烦解答,感激不尽!
目前的 FileGet 函数在调用时,如果出现与服务器断开连接和或者是文件不存在,均会返回一个 error。我现在有一份代码,需要将这两种错误区分,所以建议在这里 error return 的时候用 status.Error
包装一下,给它加上一个 codes.NotFound
或者什么的,以便调用时区分是哪一种错误。
go-judge/cmd/executorserver/grpc_executor/grpc.go
Lines 78 to 83 in 414efbf
以及,这个地方由于是删了不存在的文件造成的错误,建议 error code 改成 codes.NotFound
。
go-judge/cmd/executorserver/grpc_executor/grpc.go
Lines 117 to 123 in 414efbf
/run接口支持非阻塞吗?比如有个任务需要允许很长时间,服务端并不需要等待它执行结束,而是立即返回。而运行结果,可以在服务端开一个接口在后台监听,或者开一个轮询进程查询结果。请问一下,现在能实现这种方式吗?
on a websocket connection, run operation returns a taskId, and allow kill the specific task with id immediately (even when time limit isn't reached)
你好,当我在编译运行以下这段代码本地都是返回0但是沙箱却不是返回0
//========--------- From Origami404, under GPLv3 ---------========//
//========--------- This file is generated automatically to avoid copying/pasting the code ---------========//
#ifndef HEADER_UTILS_H__
#define HEADER_UTILS_H__
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
/**
* @brief 检查 OOM 的 malloc 版本, 一旦 OOM 则退出程序
*
* @param s 待分配字节数
* @return void* 指向分配好的内存区域的指针, 保证非空
*/
static inline void* checked_malloc(size_t s) {
void *p = malloc(s);
if (!p) {
fprintf(stderr, "Out of memory.");
exit(EXIT_FAILURE);
}
return p;
}
static inline void impl__assert_with_message(char const expr[static 1], char const message[static 1], const char file[static 1], unsigned long line) {
fprintf(stderr, "%s:%ld Assert fail: %s (%s)\n", file, line, message, expr);
fflush(stderr);
exit(EXIT_FAILURE);
}
#define assertm(expr, message) \
do { if ((expr)); else impl__assert_with_message(#expr, message, __FILE__, __LINE__); } while (0)
#define assert_not_null(p) \
assertm((p), "Except a non-null pointer")
#endif // HEADER_UTILS_H__
typedef int Element;
#define STACK_SIZE 40
typedef struct Stack {
Element data[STACK_SIZE];
int top;
} Stack;
Stack*
createStack(void) {
Stack *p = checked_malloc(sizeof *p);
p->top = 0;
return p;
}
bool
StackEmpty(
Stack stack[static 1]
) {
assert_not_null(stack);
return stack->top == 0;
}
bool
Push(
Stack stack[static 1],
Element element[static 1]
) {
assert_not_null(stack);
// assertm(stack->top != STACK_SIZE, "push on a full stack");
if (stack->top == STACK_SIZE) {
return false;
}
stack->data[stack->top++] = *element;
return true;
}
Element*
Pop(
Stack stack[static 1]
) {
assert_not_null(stack);
if (StackEmpty(stack)) {
return 0;
}
stack->top -= 1;
return stack->data + stack->top;
}
Element*
GetTop(
Stack stack[static 1]
) {
assert_not_null(stack);
if (StackEmpty(stack)) {
return 0;
}
return stack->data + stack->top - 1;
}
void
DestoryStack(
Stack *stack
) {
return free(stack);
}
void
testStack(
Stack *stack
) {
printf("Stack:");
for (int i = 0; i < stack->top; i++) {
printf("%d ", stack->data[i]);
}
printf("\n");
}
typedef struct Queue {
Stack *sequence;
Stack *reverse;
} Queue;
Queue*
createQueue(void) {
Queue *p = checked_malloc(sizeof *p);
p->sequence = createStack();
p->reverse = createStack();
return p;
}
bool
QueueEmpty(
Queue queue[static 1]
) {
return StackEmpty(queue->sequence)
&& StackEmpty(queue->reverse);
}
bool
InSeqMode(
Queue queue[static 1]
) {
return StackEmpty(queue->reverse);
}
void
SwitchMode(
Queue queue[static 1]
) {
Stack *src = 0, *dst = 0;
if (InSeqMode(queue)) {
src = queue->sequence;
dst = queue->reverse;
} else {
src = queue->reverse;
dst = queue->sequence;
}
for (Element *e = 0; (e = Pop(src)); Push(dst, e))
/* nothing */;
}
bool
EnQueue(
Queue queue[static 1],
Element *element
) {
if (!InSeqMode(queue)) {
SwitchMode(queue);
}
return Push(queue->sequence, element);
}
Element*
DeQueue(
Queue queue[static 1]
) {
if (InSeqMode(queue)) {
SwitchMode(queue);
}
return Pop(queue->reverse);
}
Element*
GetHead(
Queue queue[static 1]
) {
if (InSeqMode(queue)) {
SwitchMode(queue);
}
return GetTop(queue->reverse);
}
void
DestoryQueue(
Queue *queue
) {
if (queue) {
DestoryStack(queue->sequence);
DestoryStack(queue->reverse);
free(queue);
}
}
void
testQueue(
Queue queue[static 1]
) {
printf("Queue:");
if (InSeqMode(queue)) {
for (int i = 0; i < queue->sequence->top; i++) {
printf("%d ", queue->sequence->data[i]);
}
} else {
for (int i = queue->reverse->top - 1; i >= 0; i--) {
printf("%d ", queue->reverse->data[i]);
}
}
printf("\n");
}
enum {
MODE_EN = 4,
MODE_DE = 5,
MODE_GH = 6,
MODE_QE = 7,
};
int main() {
int mode = -1;
Queue *queue = createQueue();
while (scanf("%d", &mode) != EOF && mode != -1) {
switch (mode) {
case MODE_EN: {
int num; scanf("%d", &num);
while (num --> 0) {
int value; scanf("%d", &value);
if (EnQueue(queue, &value)) {
printf("EnQueue:%d\n", value);
} else {
puts("EnQueue failed");
}
testQueue(queue);
}
} break;
case MODE_DE: {
int num; scanf("%d", &num);
while (num --> 0) {
int *value = DeQueue(queue);
if (value) {
printf("DeQueue:%d\n", *value);
} else {
puts("DeQueue failed");
}
testQueue(queue);
}
} break;
case MODE_GH: {
int *value = GetHead(queue);
if (value) {
printf("GetHead:%d\n", *value);
} else {
puts("GetHead failed");
}
testQueue(queue);
} break;
case MODE_QE: {
printf("The Queue is%s Empty\n", QueueEmpty(queue) ? "" : " not");
testQueue(queue);
} break;
default: assertm(false, "Unknown mode");
}
}
DestoryQueue(queue);
return 0;
}
stdin的输入为下
4 6 9 8 7 6 5 4
5 20
6
7
你好作者,我在沙盒中运行matplotlib时,遇到了如下问题:
`
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
data1 = pd.read_csv(r'https://dp.xinchanjiao.com/data/test1.csv')
data2 = pd.read_csv(r'https://dp.xinchanjiao.com/data/test2.csv')
data3 = data1.merge(data2,on='地区',how='left')
print('合并后数据行列数分别为:{}行,{}列。'.format(data3.shape[0],data3.shape[1]))
data3.head(5)#查看合并后数据的前5行
nan_num = data3.isna().sum().sum()
row_duplicated = data3.duplicated().sum()
print(f'重复行总数为:{row_duplicated}')
barh_data = barh_data = data3.groupby('省/自治区').agg({'利润':'sum','销售额':'sum'}).sort_values('利润',ascending=True)
barh_data.head()#查看数据前5行
barh = barh_data.plot(kind='barh',figsize=(16,12),width=0.8)
plt.title('各省市销售额&利润条形图',fontdict={'fontsize':20})
plt.xlabel('金额(元)')
plt.ylabel('省/自治区')
plt.grid()
plt.legend()
plt.show()
tem_data = pd.pivot_table(data=data3,values=['销售额'],index=['地区经理'],columns=['类别'],aggfunc='sum')#使用透视函数筛选数据
tem_data.head()#查看数据前5行
for i in range(tem_data.shape[0]):
tem_data.iloc[i].plot(marker='o',ls='--',figsize=(16,7))
plt.title('地区经理&商品类别销售额折线图',fontsize=20)
plt.xlabel('类别')
plt.ylabel('金额(元)')
plt.legend()
plt.grid()
plt.show()
data4 = data3[(data3['销售额']>1000) & (data3['利润']<0)]
`
{"cmd":[{"args":["/usr/bin/python3","1.py"],"cpuLimit":1000000000,"files":[{"content":""},{"max":9999999,"name":"stdout"},{"max":9999999,"name":"stderr"}],"realCpuLimit":2000000000,"memoryLimit":104857600,"copyIn":{"1.py":{"content":"import numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\ndata1 = pd.read_csv(r'0.csv') \ndata2 = pd.read_csv(r'1.csv') \ndata3 = data1.merge(data2,on='地区',how='left')\ndata3.head(5)#查看合并后数据的前5行\nnan_num = data3.isna().sum().sum()\nrow_duplicated = data3.duplicated().sum()\nbarh_data = barh_data = data3.groupby('省/自治区').agg({'利润':'sum','销售额':'sum'}).sort_values('利润',ascending=True)\nbarh_data.head()#查看数据前5行\nbarh = barh_data.plot(kind='barh',figsize=(16,12),width=0.8)\nplt.title('各省市销售额&利润条形图',fontdict={'fontsize':20})\nplt.xlabel('金额(元)')\nplt.ylabel('省/自治区')\nplt.grid()\nplt.legend()\nplt.show()\ntem_data = pd.pivot_table(data=data3,values=['销售额'],index=['地区经理'],columns=['类别'],aggfunc='sum')#使用透视函数筛选数据\ntem_data.head()#查看数据前5行\nfor i in range(tem_data.shape[0]):\n tem_data.iloc[i].plot(marker='o',ls='--',figsize=(16,7))\nplt.title('地区经理&商品类别销售额折线图',fontsize=20)\nplt.xlabel('类别')\nplt.ylabel('金额(元)')\nplt.legend()\nplt.grid()\nplt.show()\ndata4 = data3[(data3['销售额']>1000) & (data3['利润']<0)]\n\nprint(data1.shape[0])"},"1.csv":{"content":" #############################内容太长,超出了输入框限制,具体内容在1.py中涉及到的csv文件中################ "}},"env":["PATH=/usr/bin:/bin"],"procLimit":50}]}
[{"status":"Nonzero Exit Status","exitStatus":1,"time":773798045,"memory":47820800,"runTime":458349828,"files":{"stderr":"Traceback (most recent call last):\n File \"/w/1.py\", line 3, in \u003cmodule\u003e\n import matplotlib.pyplot as plt\n File \"/usr/local/lib/python3.10/dist-packages/matplotlib/__init__.py\", line 892, in \u003cmodule\u003e\n dict.update(rcParams, _rc_params_in_file(matplotlib_fname()))\n File \"/usr/local/lib/python3.10/dist-packages/matplotlib/__init__.py\", line 569, in matplotlib_fname\n for fname in gen_candidates():\n File \"/usr/local/lib/python3.10/dist-packages/matplotlib/__init__.py\", line 566, in gen_candidates\n yield os.path.join(get_configdir(), 'matplotlibrc')\n File \"/usr/local/lib/python3.10/dist-packages/matplotlib/__init__.py\", line 275, in wrapper\n ret = func(**kwargs)\n File \"/usr/local/lib/python3.10/dist-packages/matplotlib/__init__.py\", line 512, in get_configdir\n return _get_config_or_cache_dir(_get_xdg_config_dir)\n File \"/usr/local/lib/python3.10/dist-packages/matplotlib/__init__.py\", line 471, in _get_config_or_cache_dir\n configdir = Path(xdg_base_getter(), \"matplotlib\")\n File \"/usr/local/lib/python3.10/dist-packages/matplotlib/__init__.py\", line 452, in _get_xdg_config_dir\n return os.environ.get('XDG_CONFIG_HOME') or str(Path.home() / \".config\")\n File \"/usr/lib/python3.10/pathlib.py\", line 998, in home\n return cls(\"~\").expanduser()\n File \"/usr/lib/python3.10/pathlib.py\", line 1438, in expanduser\n raise RuntimeError(\"Could not determine home directory.\")\nRuntimeError: Could not determine home directory.\n","stdout":""}}]
感觉是matplotlib问题,根据提示,百度了一下,配置过如下:
import os os.environ['MPLCONFIGDIR'] = os.getcwd() + "/configs/"
结果返回的是:
[{"status":"Time Limit Exceeded","exitStatus":9,"time":1100516463,"memory":57921536,"runTime":1004221715,"files":{"stderr":"Fontconfig error: Cannot load default config file\n","stdout":""}}]
请问作者及各位使用该沙盒的朋友有没有遇到这种问题,是怎么解决的呢?
大佬你好,
我们学校的oj使用了大佬开发的go-judge,目前遇到一个问题,想请教一下。这个问题只发生在服务器上,很难复现,遇到的概率可能不到10%。
网页端发送的编译请求如下:
{
"cmd": [
{
"args": [
"/bin/bash",
"-c",
"/usr/bin/g++ Main.cpp -std=c++20 -O2 -DONLINE_JUDGE -w -fmax-errors=1 -lm -o Main"
],
"env": [
"PATH=/usr/bin:/bin"
],
"files": [
{
"content": ""
},
{
"name": "stdout",
"max": 10240
},
{
"name": "stderr",
"max": 10240
}
],
"cpuLimit": 10000000000,
"clockLimit": 20000000000,
"memoryLimit": 536870912,
"procLimit": 128,
"copyIn": {
"Main.cpp": {
"content": "#include<bits/stdc++.h>\nusing namespace std;\nint main()\n{\n\tint a,b;\n\tcin>>a>>b;\n\tcout<<a+b<<endl;\n}"
}
},
"copyOut": [
"stdout",
"stderr"
],
"copyOutCached": [
"Main"
]
}
]
}
给定的编译时间是10秒,有很小的概率会返回编译超时,瞬间返回结果,显然并没有达到10秒。
感谢大佬百忙之中予以指教!
如何扩展多语言和sql呀?
示例中只看到了通过content传递代码的方式。直接使用
"copyIn": {
"main.go": {
"content": "PQIDQKQ4"
}
}
无效。
在运行第一个示例(g++示例)的时候,需要创建或者上传额外的文件吗?
我请求的地址是:http://***********:5050/run
得到了这样的响应信息
[
{
"status": "Internal Error",
"exitStatus": 0,
"error": "execve: start: execve: no such file or directory",
"time": 255185,
"memory": 0,
"runTime": 0,
"files": {
"stderr": "",
"stdout": ""
},
"fileIds": {
"a.cc": "3TIW2DYO"
},
"fileError": [
{
"name": "a",
"type": "CopyOutOpen",
"message": "open a: no such file or directory"
}
]
}
]
请问如何用/run restful接口来编译和运行java代码
当要求选手使用文件IO,但选手未创建文件时会返回File Error,且message无法判断是选手文件丢失还是其他文件丢失(同时返回错误文件名)?
希望允许optional选项,在文件不存在时返回空串或采用其他可辨识方案。
调用 /run 时,files 里添加的 Pipe stdout 和 stderr,在即便没有添加 copyOut 和 copyOutCached 参数,也会被 copyOut 出来.并且能在请求 /file 时看到两个没有名字的文件,内容为 stdout 和 stderr.
请问一下这是故意这样设计的还是一个 bug?
测试代码:
#!/usr/bin/env node
var WebSocketClient = require('websocket').client;
var client = new WebSocketClient();
client.on('connectFailed', function(error) {
console.log('Connect Error: ' + error.toString());
});
client.on('connect', function(connection) {
console.log('WebSocket Client Connected');
connection.on('error', function(error) {
console.log("Connection Error: " + error.toString());
});
connection.on('close', function() {
console.log('echo-protocol Connection Closed');
});
connection.on('message', function(message) {
if (message.type === 'utf8') {
console.log("Received: '" + message.utf8Data + "'");
connection.close();
}
});
function test() {
if (connection.connected) {
connection.sendUTF(
String.raw`{
"requestId":"hello",
"cmd": [{
"args": ["/usr/bin/g++", "a.cc", "-o", "a"],
"env": ["PATH=/usr/bin:/bin"],
"files": [{
"content": ""
}, {
"name": "stdout",
"max": 10240
}, {
"name": "stderr",
"max": 10240
}],
"cpuLimit": 10000000000,
"memoryLimit": 104857600,
"procLimit": 50,
"copyIn": {
"a.cc": {
"content": "COMPILE_ERROR!!!;\n}"
}
},
"copyOut": [],
"copyOutCached": []
}]
}`
);
}
}
test();
});
client.connect('ws://localhost:5050/ws');
输出:
WebSocket Client Connected
Received: '{"requestId":"hello","results":[{"status":"Nonzero Exit Status","exitStatus":1,"time":11284000,"memory":11886592,"runTime":53288945,"files":{"stderr":"a.cc:1:1: error: 'COMPILE_ERROR' does not name a type\n 1 | COMPILE_ERROR!!!;\n | ^~~~~~~~~~~~~\na.cc:2:1: error: expected declaration before '}' to ken\n 2 | }\n | ^\n","stdout":""}}]}'
echo-protocol Connection Closed
请求 /file
的回复:
{"BVS4UU5F":"","MQURLSZU":""}
I installed Docker on my machine and then called your /run API, but I got this result, why did it fail?
[
-{
"status": "Internal Error",
"exitStatus": 0,
"error": "failed to get environment container: failed to start container operation not permitted",
"time": 0,
"memory": 0
}
]
您好作者,可不可以在 cmd/executorserver/model/model.go
中添加一个 Status.UnmarshalJSON 方法,来把字符串再转回枚举?
我在用 go 对 executorserver 提供的 REST API 包装时遇到的问题:没有办法将 API 返回的 json 数据转回 Result。具体原因是无法将 Marshal 出来的 string 重新变成枚举。
你可能会问的问题:
model.Result
结构体重写了,我的包装不就出 bug 了吗?我想使我的包装一直兼容这个项目的最新 Release。根据 #41,既然都用 ffi 了,为什么不直接 char8_t *FileAdd(uint8_t *content, size_t len, char8_t *file_name = NULL)
呢?
用go1.19,编译时执行go build ./cmd/exectorserver
命令会出现下面的错误:
# github.com/criyle/go-judge/cmd/executorserver
github.com/criyle/go-sandbox/pkg/forkexec.forkAndExecInChild1: nosplit stack over 792 byte limit
github.com/criyle/go-sandbox/pkg/forkexec.forkAndExecInChild1<1>
grows 744 bytes, calls syscall.RawSyscall<1>
grows 72 bytes, calls syscall.RawSyscall6<1>
grows 72 bytes, calls runtime/internal/syscall.Syscall6<1>
96 bytes over limit
grows 744 bytes, calls syscall.RawSyscall<1>
grows 72 bytes, calls syscall.RawSyscall6<1>
grows 72 bytes, calls runtime/internal/syscall.Syscall6<1>
96 bytes over limit
grows 744 bytes, calls syscall.RawSyscall<1>
grows 72 bytes, calls syscall.RawSyscall6<1>
grows 72 bytes, calls runtime/internal/syscall.Syscall6<1>
96 bytes over limit
grows 744 bytes, calls syscall.RawSyscall<1>
grows 72 bytes, calls syscall.RawSyscall6<1>
grows 72 bytes, calls runtime/internal/syscall.Syscall6<1>
96 bytes over limit
grows 744 bytes, calls syscall.RawSyscall<1>
grows 72 bytes, calls syscall.RawSyscall6<1>
grows 72 bytes, calls runtime/internal/syscall.Syscall6<1>
96 bytes over limit
grows 744 bytes, calls syscall.RawSyscall<1>
grows 72 bytes, calls syscall.RawSyscall6<1>
grows 72 bytes, calls runtime/internal/syscall.Syscall6<1>
96 bytes over limit
grows 744 bytes, calls syscall.RawSyscall<1>
grows 72 bytes, calls syscall.RawSyscall6<1>
grows 72 bytes, calls runtime/internal/syscall.Syscall6<1>
96 bytes over limit
grows 744 bytes, calls syscall.RawSyscall<1>
grows 72 bytes, calls syscall.RawSyscall6<1>
grows 72 bytes, calls runtime/internal/syscall.Syscall6<1>
96 bytes over limit
grows 744 bytes, calls syscall.RawSyscall<1>
grows 72 bytes, calls syscall.RawSyscall6<1>
grows 72 bytes, calls runtime/internal/syscall.Syscall6<1>
96 bytes over limit
grows 744 bytes, calls syscall.RawSyscall<1>
grows 72 bytes, calls syscall.RawSyscall6<1>
grows 72 bytes, calls runtime/internal/syscall.Syscall6<1>
96 bytes over limit
grows 744 bytes, calls syscall.RawSyscall<1>
grows 72 bytes, calls syscall.RawSyscall6<1>
grows 72 bytes, calls runtime/internal/syscall.Syscall6<1>
96 bytes over limit
grows 744 bytes, calls syscall.RawSyscall<1>
grows 72 bytes, calls syscall.RawSyscall6<1>
grows 72 bytes, calls runtime/internal/syscall.Syscall6<1>
96 bytes over limit
grows 744 bytes, calls syscall.RawSyscall<1>
grows 72 bytes, calls syscall.RawSyscall6<1>
grows 72 bytes, calls runtime/internal/syscall.Syscall6<1>
96 bytes over limit
grows 744 bytes, calls syscall.RawSyscall6<1>
grows 72 bytes, calls runtime/internal/syscall.Syscall6<1>
24 bytes over limit
grows 744 bytes, calls syscall.RawSyscall6<1>
grows 72 bytes, calls runtime/internal/syscall.Syscall6<1>
24 bytes over limit
grows 744 bytes, calls syscall.RawSyscall<1>
grows 72 bytes, calls syscall.RawSyscall6<1>
grows 72 bytes, calls runtime/internal/syscall.Syscall6<1>
96 bytes over limit
grows 744 bytes, calls syscall.RawSyscall<1>
grows 72 bytes, calls syscall.RawSyscall6<1>
grows 72 bytes, calls runtime/internal/syscall.Syscall6<1>
96 bytes over limit
grows 744 bytes, calls syscall.RawSyscall<1>
grows 72 bytes, calls syscall.RawSyscall6<1>
grows 72 bytes, calls runtime/internal/syscall.Syscall6<1>
96 bytes over limit
grows 744 bytes, calls syscall.RawSyscall<1>
grows 72 bytes, calls syscall.RawSyscall6<1>
grows 72 bytes, calls runtime/internal/syscall.Syscall6<1>
96 bytes over limit
grows 744 bytes, calls syscall.RawSyscall<1>
grows 72 bytes, calls syscall.RawSyscall6<1>
grows 72 bytes, calls runtime/internal/syscall.Syscall6<1>
96 bytes over limit
grows 744 bytes, calls syscall.RawSyscall6<1>
grows 72 bytes, calls runtime/internal/syscall.Syscall6<1>
24 bytes over limit
grows 744 bytes, calls syscall.RawSyscall<1>
grows 72 bytes, calls syscall.RawSyscall6<1>
grows 72 bytes, calls runtime/internal/syscall.Syscall6<1>
96 bytes over limit
grows 744 bytes, calls syscall.RawSyscall<1>
grows 72 bytes, calls syscall.RawSyscall6<1>
grows 72 bytes, calls runtime/internal/syscall.Syscall6<1>
96 bytes over limit
grows 744 bytes, calls syscall.RawSyscall<1>
grows 72 bytes, calls syscall.RawSyscall6<1>
grows 72 bytes, calls runtime/internal/syscall.Syscall6<1>
96 bytes over limit
grows 744 bytes, calls syscall.RawSyscall6<1>
grows 72 bytes, calls runtime/internal/syscall.Syscall6<1>
24 bytes over limit
grows 744 bytes, calls syscall.RawSyscall6<1>
grows 72 bytes, calls runtime/internal/syscall.Syscall6<1>
24 bytes over limit
grows 744 bytes, calls syscall.RawSyscall<1>
grows 72 bytes, calls syscall.RawSyscall6<1>
grows 72 bytes, calls runtime/internal/syscall.Syscall6<1>
96 bytes over limit
grows 744 bytes, calls syscall.RawSyscall<1>
grows 72 bytes, calls syscall.RawSyscall6<1>
grows 72 bytes, calls runtime/internal/syscall.Syscall6<1>
96 bytes over limit
grows 744 bytes, calls syscall.RawSyscall<1>
grows 72 bytes, calls syscall.RawSyscall6<1>
grows 72 bytes, calls runtime/internal/syscall.Syscall6<1>
96 bytes over limit
grows 744 bytes, calls syscall.RawSyscall<1>
grows 72 bytes, calls syscall.RawSyscall6<1>
grows 72 bytes, calls runtime/internal/syscall.Syscall6<1>
96 bytes over limit
grows 744 bytes, calls syscall.RawSyscall<1>
grows 72 bytes, calls syscall.RawSyscall6<1>
grows 72 bytes, calls runtime/internal/syscall.Syscall6<1>
96 bytes over limit
grows 744 bytes, calls syscall.RawSyscall<1>
grows 72 bytes, calls syscall.RawSyscall6<1>
grows 72 bytes, calls runtime/internal/syscall.Syscall6<1>
96 bytes over limit
grows 744 bytes, calls syscall.RawSyscall<1>
grows 72 bytes, calls syscall.RawSyscall6<1>
grows 72 bytes, calls runtime/internal/syscall.Syscall6<1>
96 bytes over limit
grows 744 bytes, calls syscall.RawSyscall<1>
grows 72 bytes, calls syscall.RawSyscall6<1>
grows 72 bytes, calls runtime/internal/syscall.Syscall6<1>
96 bytes over limit
grows 744 bytes, calls syscall.RawSyscall<1>
grows 72 bytes, calls syscall.RawSyscall6<1>
grows 72 bytes, calls runtime/internal/syscall.Syscall6<1>
96 bytes over limit
grows 744 bytes, calls syscall.RawSyscall<1>
grows 72 bytes, calls syscall.RawSyscall6<1>
grows 72 bytes, calls runtime/internal/syscall.Syscall6<1>
96 bytes over limit
grows 744 bytes, calls syscall.RawSyscall<1>
grows 72 bytes, calls syscall.RawSyscall6<1>
grows 72 bytes, calls runtime/internal/syscall.Syscall6<1>
96 bytes over limit
grows 744 bytes, calls syscall.RawSyscall<1>
grows 72 bytes, calls syscall.RawSyscall6<1>
grows 72 bytes, calls runtime/internal/syscall.Syscall6<1>
96 bytes over limit
grows 744 bytes, calls syscall.RawSyscall<1>
grows 72 bytes, calls syscall.RawSyscall6<1>
grows 72 bytes, calls runtime/internal/syscall.Syscall6<1>
96 bytes over limit
grows 744 bytes, calls syscall.RawSyscall<1>
grows 72 bytes, calls syscall.RawSyscall6<1>
grows 72 bytes, calls runtime/internal/syscall.Syscall6<1>
96 bytes over limit
grows 744 bytes, calls syscall.RawSyscall<1>
grows 72 bytes, calls syscall.RawSyscall6<1>
grows 72 bytes, calls runtime/internal/syscall.Syscall6<1>
96 bytes over limit
grows 744 bytes, calls syscall.RawSyscall<1>
grows 72 bytes, calls syscall.RawSyscall6<1>
grows 72 bytes, calls runtime/internal/syscall.Syscall6<1>
96 bytes over limit
grows 744 bytes, calls syscall.RawSyscall<1>
grows 72 bytes, calls syscall.RawSyscall6<1>
grows 72 bytes, calls runtime/internal/syscall.Syscall6<1>
96 bytes over limit
grows 744 bytes, calls syscall.RawSyscall<1>
grows 72 bytes, calls syscall.RawSyscall6<1>
grows 72 bytes, calls runtime/internal/syscall.Syscall6<1>
96 bytes over limit
grows 744 bytes, calls syscall.RawSyscall6<1>
grows 72 bytes, calls runtime/internal/syscall.Syscall6<1>
24 bytes over limit
grows 744 bytes, calls syscall.RawSyscall<1>
grows 72 bytes, calls syscall.RawSyscall6<1>
grows 72 bytes, calls runtime/internal/syscall.Syscall6<1>
96 bytes over limit
grows 744 bytes, calls syscall.RawSyscall<1>
grows 72 bytes, calls syscall.RawSyscall6<1>
grows 72 bytes, calls runtime/internal/syscall.Syscall6<1>
96 bytes over limit
grows 744 bytes, calls syscall.RawSyscall6<1>
grows 72 bytes, calls runtime/internal/syscall.Syscall6<1>
24 bytes over limit
grows 744 bytes, calls syscall.RawSyscall<1>
grows 72 bytes, calls syscall.RawSyscall6<1>
grows 72 bytes, calls runtime/internal/syscall.Syscall6<1>
96 bytes over limit
grows 744 bytes, calls syscall.RawSyscall<1>
grows 72 bytes, calls syscall.RawSyscall6<1>
grows 72 bytes, calls runtime/internal/syscall.Syscall6<1>
96 bytes over limit
grows 744 bytes, calls syscall.RawSyscall6<1>
grows 72 bytes, calls runtime/internal/syscall.Syscall6<1>
24 bytes over limit
grows 744 bytes, calls syscall.RawSyscall6<1>
grows 72 bytes, calls runtime/internal/syscall.Syscall6<1>
24 bytes over limit
grows 744 bytes, calls syscall.RawSyscall<1>
grows 72 bytes, calls syscall.RawSyscall6<1>
grows 72 bytes, calls runtime/internal/syscall.Syscall6<1>
96 bytes over limit
grows 744 bytes, calls syscall.RawSyscall<1>
grows 72 bytes, calls syscall.RawSyscall6<1>
grows 72 bytes, calls runtime/internal/syscall.Syscall6<1>
96 bytes over limit
grows 744 bytes, calls syscall.RawSyscall<1>
grows 72 bytes, calls syscall.RawSyscall6<1>
grows 72 bytes, calls runtime/internal/syscall.Syscall6<1>
96 bytes over limit
Currently, when there's a FileError
, it is hard to know which file causes the error and the details about the error.
This proposal is to add more detailed file error information to the response with file name and error type with array field fileError
.
interface FileError {
name: string;
errorType: FileErrorType
}
enum FileErrorType {
CopyInNotExists,
CopyOutNotExists,
CopyOutLimitExists,
CopyOutNotRegularFile,
...
}
apt install golang
build cache is required, but could not be located: GOCACHE is not defined and neither $XDG_CACHE_HOME nor $HOME are defined\n
{
"cmd": [
{
"args": [
"/usr/bin/go",
"build",
"-o",
"solution",
"solution.go"
],
"env": [
"PATH=/usr/bin:/bin,GOPATH=/w,GOCACHE=/tmp"
],
"files": [
{
"content": ""
},
{
"name": "stdout",
"max": 33554432
},
{
"name": "stderr",
"max": 33554432
}
],
"cpuLimit": 2000000000000000,
"clockLimit": 2000000000000000,
"memoryLimit": 2000000000,
"procLimit": 128,
"copyIn": {
"solution.go": {
"content": "package main\nimport \"fmt\"\nfunc main() {\n\tfmt.Printf(\"Hello, World!\")\n}"
}
},
"copyOut": [
"stdout",
"stderr"
],
"copyOutCached": [
"solution"
]
}
]
}
[
{
"status": "Nonzero Exit Status",
"exitStatus": 1,
"time": 84176000,
"memory": 17809408,
"runTime": 57885751,
"files": {
"stderr": "build cache is required, but could not be located: GOCACHE is not defined and neither $XDG_CACHE_HOME nor $HOME are defined\n",
"stdout": ""
},
"fileError": [
{
"name": "solution",
"type": "CopyOutOpen",
"message": "open solution: no such file or directory"
}
]
}
]
添加windows平台,linux_arm等
我想问一下,这个样例我不是很懂耶。
我觉得应该是输入,代码,输出。三个命令
Currently, for pipeCollector
, a pipe will be created and the write end will be duplicated into the container process. On the read end, a goroutine will be created to copy the output into a memory buffer. After the proposal #20, the memory buffer will be replaced by a temporary file, but a goroutine is still needed in order to copy the output content.
This proposal is to implement output collector via files in container. A new boolean field pipe
will be added to pipeCollector
.
interface Collector {
name: string; // file name in copyOut
max: number; // maximum bytes to collect
pipe: boolean; // collect via pipe (the default value is undetermined now)
}
When pipe
is false, a file will be created inside container file system (e.g. /tmp/:tempfilename) and open in write-only mode. The file decriptor will be duplicated to the process and the file will be copied out after execution.
With this change, the container default tmpfs
size will be increased (e.g. from 16M -> 128M or 256M) to fit the need. Also, a field outputMax
will be added to Cmd
to override posix rlimit for output provided by cli arguments.
On the other platform, these field will be ignored.
以下是我发送和接受的数据,按照 https://goj.ac/submissions 中的命令写的发送数据,但是不知道什么原因发生了错误。
在c/c++中,可以正常使用。
{
'headers': {
'Content-type': 'application/json'
},
'json': {
'cmd': [{
'args': ['/usr/bin/python3', '-c', '"import py_compile; py_compile.compile(\'solution.py\', \'solution.pyc\', doraise=True)"'],
'env': ['PATH=/usr/bin:/bin'],
'files': [{
'content': ''
}, {
'name': 'stdout',
'max': 10240
}, {
'name': 'stderr',
'max': 10240
}],
'cpuLimit': 3000000000,
'memoryLimit': 268435456,
'procLimit': 50,
'copyIn': {
'solution.py': {
'content': 'a, b = map(int, input().split())\r\nprint(a + b)'
}
},
'copyOut': ['stdout', 'stderr'],
'copyOutCached': ['solution.py'],
'copyOutDir': '1'
}]
}
}
{
'status': 'Accepted',
'exitStatus': 0,
'time': 18214425,
'memory': 3575808,
'runTime': 27775827,
'files': {
'stderr': '',
'stdout': ''
},
'fileIds': {
'solution.py': '43IVBW5NICQAAAHX'
}
}
{
'headers': {
'Content-type': 'application/json'
},
'json': {
'cmd': [{
'args': ['python3', 'solution.py'],
'env': ['PATH=/usr/bin:/bin'],
'files': [{
'content': ''
}, {
'name': 'stdout',
'max': 10240
}, {
'name': 'stderr',
'max': 10240
}],
'cpuLimit': 3000000000,
'memoryLimit': 268435456,
'procLimit': 50,
'strictMemoryLimit': False,
'copyIn': {
'solution.py': {
'fileId': '43IVBW5NICQAAAHX'
}
}
}]
}
}
{
'status': 'Internal Error',
'exitStatus': 0,
'error': 'execve: start: execve: no such file or directory',
'time': 217028,
'memory': 131072,
'runTime': 0,
'files': {
'stderr': '',
'stdout': ''
}
}
`
Do you have Discord? I'm planning to make a online judge platform and need some help with go-sandbox, can you give me your Discord? Thanks in advance.
Currently, the default file store is based on a map of byte array in memory.
This purposal is to implement a new file store to using tmpfs
location (/dev/shm
). After this change, in memory file store will be deprecated so that there will alway be a path for file store.
After this change, a new boolean field absPath
will be added to Cmd
. When absPath
is set to true
, copyOutCached
fileId
will prefixed with the file store location (e.g. /dev/shm/go-judge/fileId
).
On other platforms, a temporary forlder will be used as file store.
This proposal is aimed to reduce the memory consumption and provides ability to access file in file srore easier for clients.
在m1 mac上运行正常,但是调用/run接口异常
I installed Docker on my machine and then called your /run API, but I got this result, why did it fail?
[
-{
"status": "Internal Error",
"exitStatus": 0,
"error": "failed to get environment container: failed to start container operation not permitted",
"time": 0,
"memory": 0
}
]
centos7 kernel:3.10.0-1160.11.1.el7.x86_64
./executorserver-amd64
prefork environment failed container: failed to start container fork/exec /proc/self/exe: invalid argument
我使用命令行gojudge,开启了grpc,在前端成功向/run post了一段代码,可以在/file下查看到,但是我前端拿不到他的返回Json,前端报错是跨域问题。
1、你好,请问下沙箱中能有访问外部网络的开关或者配置吗?我们现在有一个评测场景,通过Python使用pandas读取表格,然后利用评测机验证获取到的数组的值进行正确性验证,而pands读取到的表格在外网上,需要使用pandas的read_excel函数获取,但是现在使用评测机时会报URLError错误,因此想问下能否有办法打开沙盒的外网访问权限。
2、另外想问一下,能否放一下Python评测的示例,现在文档中有c++的示例代码,python的没有,恕我愚钝,没有参透,一直用着go-judge-demo的/api/submit去提交评测,现在想把评测的CPU和内存限制个性化设置,如您能发几个Python的示例,万分感谢!
如题。连接 ws://localhost:5050/ws
并发送一条执行请求,可以正常收到结果。但是当请求结束,客户端退出时,无论是显式调用 connection.close()
关闭连接还是直接 exit
退出程序,均会在服务端(executorserver)产生格式如同下面的 warning:
// 直接退出
{"level":"warn","ts":1663066810.5931816,"caller":"ws_executor/websocket.go:146","msg":"ws read error:websocket: close 1006 (abnormal closure): unexpected EOF"}
// 显式调用 close
{"level":"warn","ts":1663066699.9190106,"caller":"ws_executor/websocket.go:146","msg":"ws read error:websocket: close 1000 (normal): Normal connection closure"}
测试代码:
#!/usr/bin/env node
var WebSocketClient = require('websocket').client;
var client = new WebSocketClient();
client.on('connectFailed', function(error) {
console.log('Connect Error: ' + error.toString());
});
client.on('connect', function(connection) {
console.log('WebSocket Client Connected');
connection.on('error', function(error) {
console.log("Connection Error: " + error.toString());
});
connection.on('close', function() {
console.log('echo-protocol Connection Closed');
});
connection.on('message', function(message) {
if (message.type === 'utf8') {
console.log("Received: '" + message.utf8Data + "'");
connection.close();
}
});
function test() {
if (connection.connected) {
connection.sendUTF(
String.raw`{
"requestId":"hello",
"cmd": [{
"args": ["/usr/bin/g++", "a.cc", "-o", "a"],
"env": ["PATH=/usr/bin:/bin"],
"files": [{
"content": ""
}, {
"name": "stdout",
"max": 10240
}, {
"name": "stderr",
"max": 10240
}],
"cpuLimit": 10000000000,
"memoryLimit": 104857600,
"procLimit": 50,
"copyIn": {
"a.cc": {
"content": "#include <iostream>\nusing namespace std;\nint main() {\nint a, b;\ncin >> a >> b;\ncout << a + b << endl;\n}"
}
},
"copyOut": ["stdout", "stderr"],
"copyOutCached": ["a.cc", "a"],
"copyOutDir": "1"
}]
}`
);
}
}
test();
});
client.connect('ws://localhost:5050/ws');
在windows上使用示例进行编译时,指定了文件的本地存储路径,-dir local_path
请求参数:
{
"cmd":[{"cpuLimit":10000000000,
"copyOutDir":"1",
"env":["G:/mingw64/mingw64/bin"],
"copyOut":["stdout","stderr"],
"args":["G:/mingw64/mingw64/bin/g++.exe","a.cc","-o","a"],
"copyOutCached":["a.cc","a"],
"files":[{"content":""},{"max":10240,"name":"stdout"},{"max":10240,"name":"stderr"}],
"memoryLimit":104857600,
"copyIn":{"a.cc":{"content":"#include <iostream>\nusing namespace std;\nint main() {\nint a, b;\ncin >> a >> b;\ncout << a + b << endl;\n}"}},
"procLimit":50}]
}
但是最后的json编译的返回结果提示如下:
[{
"memory":0,"error":"The parameter is incorrect.",
"fileIds":{"a.cc":"6MPFYYGC"},
"fileError":[{"type":"CopyOutOpen","message":"open C:\\Users\\zzzyc\\AppData\\Local\\Temp\\es1880656414/a: The system cannot find the file specified.","name":"a"}],
"files":{"stdout":"","stderr":""},
"time":0,
"runTime":0,
"exitStatus":0,
"status":"Internal Error"
}]
请问该如何修改message
中提示的错误,使得可以编译成功呢?
这里在进行编译的env
和args
均已经修改为本地的g++
路径
除了用于oj评测,比如是否可用于faas运行时?
Hi, I'm trying to compile and execute submited solution on Windows 10. I can compile the solution by sending this to /run
{
"cmd": [
{
"args": [
"g:\\cygwin64\\bin\\g++.exe",
"-Wall",
"-std=c++98",
"-o",
"code.exe",
"foo.cc",
"-lm"
],
"env": [
"PATH=d:\\\\Download\\\\ThemisSFX_4\\\\FPC\\\\bin\\\\i386-win32;g:\\\\hydro;g:\\\\cygwin64\\\\bin;\r",
"HOME=g:\\\\hydro\r",
""
],
"files": [
{
"content": ""
},
{
"name": "stdout",
"max": 33554432
},
{
"name": "stderr",
"max": 33554432
}
],
"cpuLimit": 16000000000,
"realCpuLimit": 48000000000,
"memoryLimit": 536870912,
"strictMemoryLimit": false,
"procLimit": 32,
"copyIn": {
"foo.cc": {
"content": "#include <bits/stdc++.h>\r\nusing namespace std;\r\nint a,b;\r\nint main() {\r\n freopen(\"a+b.in\", \"r\", stdin);\r\n freopen(\"a+b.out\", \"w\", stdout);\r\n \r\n ios::sync_with_stdio(0);\r\n cin.tie(0);\r\n cout.tie(0);\r\n cin >> a;\r\n cin >> b;\r\n cout << (a+b);\r\n return 0;\r\n}"
}
},
"copyOut": [],
"copyOutCached": [
"code.exe"
]
}
]
}
On Linux, I can pass /w/code
to args
field to execute the compiled solution. But on Windows I don't know how. I tried setting the output path to something like g:\run\code.exe
for code.exe
but i get error like below (I run executorserver-amd64.exe
as adminstrator and also change permission to Eveyrone
for g:\run
with Full control
)
[{'status':'Nonzero Exit Status','exitStatus':1,'time':1046875000,'memory':75116544,'runTime':0,'files':{'stderr':'/usr/lib/gcc/x86_64-pc-cygwin/11/../../../../x86_64-pc-cygwin/bin/ld: cannot open output file g:\\code.exe: Permission denied\ncollect2: error: ld returned 1 exit status\n','stdout':''},'fileError':[{'name':'code.exe','type':'CopyOutOpen','message':'open C:\\Users\\ADMINI~1\\AppData\\Local\\Temp\\es4154887469/code.exe: The system cannot find the file specified.'}]}]
Please help me.
Thank a lot.
Regard.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.