Skip to content

Commit 4880cbe

Browse files
authored
docs: 添加gvisor测例修复指引 (#1541)
- 新增"测例修复指引"章节,详细说明如何修复gvisor系统调用测试用例 - 包含准备工作、测试执行流程、代码修复流程、白名单管理和黑名单管理等内容 - 提供完整工作流示例和注意事项,帮助开发者快速参与系统调用修复工作 Signed-off-by: longjin <longjin@DragonOS.org>
1 parent 539b82a commit 4880cbe

File tree

1 file changed

+314
-7
lines changed

1 file changed

+314
-7
lines changed

docs/kernel/ktest/gvisor_syscall_test.rst

Lines changed: 314 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,6 @@ gVisor 是 Google 开发的容器运行时沙箱,包含了大量的系统调
2121

2222
执行`make test-syscall`命令。该命令将启动DragonOS并自动执行gvisor syscall测试套件,测试完成后会退出qemu。同时根据测试用例成功率选择是成功返回还是失败返回,成功率不等于100%则失败返回。该命令的执行流程如下:
2323

24-
1. 执行 `toggle_compile_gvisor.sh enable` 注释 `app-blocklist.toml` 中与 gvisor 测试套件相关的屏蔽配置
25-
2. 编译DragonOS
26-
3. 写入镜像
27-
4. 后台qemu无图形模式启动DragonOS,同时设置环境变量`AUTO_TEST`(自动测试选项,目前仅支持syscall测试)和`SYSCALL_TEST_DIR`(测试套所在目录),这两个环境变量会通过命令行参数传递到DragonOS。然后当busybox init进程执行rcS脚本时,该脚本会通过`AUTO_TEST`选项执行对应的测试
28-
5. 执行`monitor_test_results.sh`定时查看qemu串口输出内容,并根据测试结果选择成功返回还是失败返回
29-
6. 执行 `toggle_compile_gvisor.sh disable` 取消 `app-blocklist.toml` 中相关配置的注释,恢复默认屏蔽状态
30-
3124
对应的workflow配置文件为`test-x86.yml`
3225

3326
手动测试
@@ -83,6 +76,320 @@ gVisor 是 Google 开发的容器运行时沙箱,包含了大量的系统调
8376

8477
对于每个测试程序,可以通过 ``blocklists/`` 目录下的文件屏蔽特定的测试用例。这对于跳过暂不支持或不稳定的测试非常有用。
8578

79+
测例修复指引
80+
============
81+
82+
本部分介绍如何修复gvisor测例,帮助开发者快速参与系统调用修复工作。
83+
84+
准备工作
85+
--------
86+
87+
1. **首次安装测例**
88+
89+
在开始修复工作前,需要先执行一次 `make test-syscall` 确保测例已安装到DragonOS系统中:
90+
91+
.. code-block:: bash
92+
93+
make test-syscall
94+
95+
该命令会下载测试套件、编译DragonOS、写入镜像并自动运行测试。首次执行后,测例会安装到DragonOS的 ``/opt/tests/gvisor`` 目录。
96+
97+
2. **克隆测例源代码仓库**
98+
99+
测例的源代码位于gvisor仓库中,需要克隆到本地以便查看和修复:
100+
101+
.. code-block:: bash
102+
103+
git clone https://cnb.cool/DragonOS-Community/gvisor.git
104+
cd gvisor
105+
git checkout dragonos/release-20250616.0
106+
107+
测例代码位于 ``test/syscalls/linux`` 目录下,使用gtest框架编写,每个系统调用对应一个或多个 ``.cc`` 文件。
108+
109+
测试执行流程
110+
------------
111+
112+
1. **进入DragonOS系统**
113+
114+
使用以下命令以无图形模式启动DragonOS:
115+
116+
.. code-block:: bash
117+
118+
make run-nographic
119+
120+
2. **执行测试查看报错**
121+
122+
在DragonOS系统内,切换到测例目录并执行具体的测试程序:
123+
124+
.. code-block:: bash
125+
126+
cd /opt/tests/gvisor
127+
./<test_name>
128+
129+
例如,要测试socket相关的系统调用:
130+
131+
.. code-block:: bash
132+
133+
./socket_test
134+
135+
执行测试后,会看到测试结果。失败的测试用例会显示详细的错误信息,包括:
136+
137+
- 失败的测试用例名称
138+
- 错误原因(如系统调用返回错误码、行为不符合预期等)
139+
140+
如果测例卡住(无响应或长时间不返回),需要查看堆栈跟踪信息来定位问题:
141+
142+
.. code-block:: bash
143+
144+
# 在DragonOS运行的情况下,新开一个终端窗口
145+
# 在DragonOS项目根目录执行
146+
make gdb
147+
148+
在gdb中,首先需要选择对应的vcpu线程,然后查看堆栈跟踪:
149+
150+
.. code-block:: gdb
151+
152+
# 查看所有线程
153+
info threads
154+
155+
# 选择对应的vcpu线程(例如thread 2)
156+
thread 2
157+
158+
# 查看堆栈跟踪
159+
bt
160+
161+
# 或者查看完整的堆栈跟踪(包含局部变量)
162+
bt full
163+
164+
**注意**:DragonOS是多核系统,可能有多个vcpu线程。需要根据实际情况选择正确的线程来查看堆栈跟踪。
165+
166+
3. **记录失败的测试用例**
167+
168+
将失败的测试用例名称、错误信息和堆栈跟踪信息记录下来,这些信息将用于后续的修复工作。
169+
170+
代码修复流程
171+
------------
172+
173+
1. **复制测例源代码**
174+
175+
从克隆的gvisor仓库中,找到对应的测例源代码文件(通常是 ``<test_name>.cc``),复制到DragonOS项目根目录:
176+
177+
.. code-block:: bash
178+
179+
cp /path/to/gvisor/test/syscalls/linux/<test_name>.cc /path/to/DragonOS/
180+
181+
例如,修复socket_test:
182+
183+
.. code-block:: bash
184+
185+
cp gvisor/test/syscalls/linux/socket_test.cc /home/jinlong/code/DragonOS/
186+
187+
2. **使用AI助手进行修复**
188+
189+
将复制的 ``.cc`` 文件提供给AI助手(如Cursor的AI功能),并说明:
190+
191+
- 测试失败的具体错误信息
192+
- 要求AI遵循Linux语义来修复测例
193+
- DragonOS的系统调用实现特点(参考Linux 6.6语义)
194+
195+
AI助手会分析代码,识别问题所在,并提供修复建议或直接修复代码。
196+
197+
一些小建议:
198+
199+
- 如果问题较为复杂,我们建议先使用Plan模式制定修复计划,然后再修复。
200+
- 如果AI助手难以定位问题,可以让他在内核的适当位置添加少量日志辅助定位
201+
- 如果终端日志被截断,可以到serial_opt.txt去查看完整日志,复制给AI助手
202+
- 如果AI助手难以定位问题,那么可以让他在`user/apps/c_unitest`下面写简单的测试程序来修复问题。这些测试程序会被编译安装到DragonOS的bin目录下。
203+
- 时刻注意提醒AI助手寻找是否有可以复用的代码、建立合理且适当的抽象。不然代码会很冗余!
204+
205+
3. **验证修复效果**
206+
207+
修复完成后,需要重新编译DragonOS并测试:
208+
209+
.. code-block:: bash
210+
211+
# 在DragonOS项目根目录
212+
make run-nographic
213+
214+
然后在DragonOS内再次执行测试,确认修复是否成功。
215+
216+
白名单管理
217+
----------
218+
219+
修复完成的测例需要添加到白名单中,才能被测试框架执行。
220+
221+
1. **编辑白名单文件**
222+
223+
打开 ``user/apps/tests/syscall/gvisor/whitelist.txt`` 文件,添加测试程序名称:
224+
225+
.. code-block:: text
226+
227+
# 文件系统相关测试
228+
open_test
229+
stat_test
230+
socket_test # 新添加的测试
231+
232+
2. **白名单格式说明**
233+
234+
- 每行一个测试程序名称(不带路径和扩展名)
235+
- 以 ``#`` 开头的行是注释,会被忽略
236+
- 空行会被忽略
237+
- 可以按功能分类组织,使用注释分组
238+
239+
3. **注意事项**
240+
241+
- 测试程序名称必须与可执行文件名完全一致
242+
- 添加后需要重新`make test-syscall`才能生效
243+
- 建议在添加前先验证测试能够正常运行
244+
245+
黑名单管理
246+
----------
247+
248+
如果某个测试程序中的部分测试用例暂时无法修复或不需要支持,可以创建blocklist文件来屏蔽这些测试用例。
249+
250+
1. **何时需要创建blocklist**
251+
252+
- 测试用例依赖DragonOS暂不支持的功能(如IPv6、某些文件系统特性等)
253+
- 测试用例存在已知的不稳定性或竞争条件
254+
- 测试用例需要特殊权限或环境配置,当前环境无法满足
255+
256+
2. **创建blocklist文件**
257+
258+
在 ``user/apps/tests/syscall/gvisor/blocklists/`` 目录下创建与测试程序同名的文件:
259+
260+
.. code-block:: bash
261+
262+
# 例如,为socket_test创建blocklist
263+
touch user/apps/tests/syscall/gvisor/blocklists/socket_test
264+
265+
3. **blocklist文件格式**
266+
267+
在文件中添加要屏蔽的测试用例名称,每行一个:
268+
269+
.. code-block:: text
270+
271+
# 这是注释行,会被忽略
272+
273+
# 屏蔽IPv6相关测试
274+
SocketTest.IPv6*
275+
SocketTest.IPv6Socket*
276+
277+
# 屏蔽需要特殊权限的测试
278+
SocketTest.PrivilegedSocket
279+
280+
# 屏蔽已知不稳定的测试
281+
SocketTest.UnimplementedFeature
282+
283+
4. **格式说明**
284+
285+
- 支持通配符 ``*`` 匹配任意字符
286+
- 测试用例名称格式通常为 ``TestSuite.TestCase``
287+
- 以 ``#`` 开头的行是注释
288+
- 空行会被忽略
289+
- **重要**:必须在文件中注明屏蔽原因,方便后续维护
290+
291+
5. **示例**
292+
293+
查看现有的blocklist文件作为参考:
294+
295+
- ``user/apps/tests/syscall/gvisor/blocklists/socket_test`` - socket测试的黑名单
296+
- ``user/apps/tests/syscall/gvisor/blocklists/epoll_test`` - epoll测试的黑名单
297+
298+
完整工作流示例
299+
--------------
300+
301+
以下是一个完整的修复流程示例,以修复 ``open_test`` 为例:
302+
303+
1. **准备工作**
304+
305+
.. code-block:: bash
306+
307+
# 首次安装测例(如果还没安装)
308+
make test-syscall
309+
310+
# 克隆测例源代码
311+
git clone https://cnb.cool/DragonOS-Community/gvisor.git
312+
cd gvisor
313+
git checkout dragonos/release-20250616.0
314+
315+
2. **发现问题**
316+
317+
.. code-block:: bash
318+
319+
# 进入DragonOS
320+
make run-nographic
321+
322+
# 在DragonOS内执行测试
323+
cd /opt/tests/gvisor
324+
./open_test
325+
326+
# 发现部分测试用例失败,记录错误信息
327+
328+
3. **修复代码**
329+
330+
.. code-block:: bash
331+
332+
# 复制源代码到DragonOS根目录
333+
cp gvisor/test/syscalls/linux/open_test.cc /home/jinlong/code/DragonOS/
334+
335+
# 使用AI助手修复(在Cursor中打开文件并提供错误信息)
336+
# AI会分析代码并提供修复方案
337+
338+
4. **验证修复**
339+
340+
.. code-block:: bash
341+
342+
# 重新编译
343+
make kernel
344+
make run-nographic
345+
346+
# 再次测试
347+
cd /opt/tests/gvisor
348+
./open_test
349+
350+
# 确认所有测试用例通过
351+
352+
5. **添加到白名单**
353+
354+
.. code-block:: bash
355+
356+
# 编辑白名单文件
357+
vim user/apps/tests/syscall/gvisor/whitelist.txt
358+
359+
# 添加:open_test
360+
361+
6. **处理无法修复的测试用例**
362+
363+
如果某些测试用例暂时无法修复(如依赖未实现的功能),创建blocklist:
364+
365+
.. code-block:: bash
366+
367+
# 创建blocklist文件
368+
vim user/apps/tests/syscall/gvisor/blocklists/open_test
369+
370+
# 添加内容:
371+
# 屏蔽依赖O_TMPFILE的测试(DragonOS暂不支持)
372+
OpenTest.Tmpfile*
373+
# 原因:O_TMPFILE需要特定的文件系统支持,当前未实现
374+
375+
7. **最终验证**
376+
377+
.. code-block:: bash
378+
379+
# 重新编译并运行完整测试套件
380+
make test-syscall
381+
382+
# 确认open_test能够正常运行,失败的用例已被blocklist屏蔽
383+
384+
注意事项
385+
--------
386+
387+
- **符合Linux语义**:修复时要确保系统调用行为符合Linux 6.6的语义,不要使用workaround绕过问题
388+
- **深入分析**:修复前要深入分析问题根源,结合测例代码、DragonOS实现和Linux行为进行对比
389+
- **测试验证**:每次修复后都要重新测试,确保修复有效且没有引入新的问题
390+
- **文档记录**:在blocklist中详细记录屏蔽原因,方便后续维护和重新启用
391+
- **代码质量**:修复后的代码要符合DragonOS的代码规范,运行 ``make fmt`` 进行格式化
392+
86393
更多详细信息
87394
==============
88395

0 commit comments

Comments
 (0)