春季学期第 2 周 (3 月 3 日)
Abcoder 项目
目标
- 使用 Abcoder 对一些复杂项目进行解析,协助改进目前开源的 Abcoder 的功能
- 了解 Abcoder 的原理和使用方式,并能够指导其他人使用
使用方法
项目组给出了两种方法:Coze 和本地部署 ollama。我试了 Coze 并不是很稳定,而且还需要付钱。他们之前生成的 rcore 解析似乎是内部的模型 API 接口跑的,我直接在 Coze 平台上跑的模型能力和稳定性都不太行。所以我找了台服务器跑了 ollama,使用了 deepseek-coder-v2,并且手动将 context windows 调整到了 4k。速度还算过得去,并开始对 rust 项目进行解析。
这里试的时候遇到了一些问题,简单记录一下:
-
本来是使用 llama3.2,但是这个模型不太行,所以换成了 deepseek 32b 模型。但是 deepseek32b 模型本身是一个 chat 模型,会进行所谓深度思考,然后输出的解析结果带了很多无用的思考内容,占用了篇幅的同时还让解析时间变慢。于是最后换成了 deepseek coder v2 模型。
-
使用 ollama 跑 deepseek coder v2 的时候发现很多时候解析中断了, 看 log 发现是传入的 prompt 太长了超过了模型的 context windows。ollama 默认开了似乎是 2048 的 max-token,手动将这个模型改为了 4096 的 max-token,应该就没有太大问题了。
context windows 大小 n 的平方和思考时间成正比,因此开太大也不太好。
具体的环境配置文档暂时不写,因为这些环境都是我临时找的,给其他人复现的可能性也不高。等之后决定给其他人使用的时候再说。
在这里简单贴一下对于 abcoder 生成结果的解析内容。因为 abcoder 是直接调用了模型的输出然后存储在了一个 json 文件里面,需要提取有效信息并且将其转化为可视文件比如 Markdown。
# demo.py
def level_log(log, title):
print('#' * log + ' ' + title )
import json
# 需要将 abcoder 生成的结果存储在同目录下的 data.json 中
with open('data.json', 'r') as f:
data = json.load(f)
for module in data['Modules']:
if data['Modules'][module]["Dir"] == "":
continue
level_log(1, module)
packages = data['Modules'][module]["Packages"]
for package in packages:
level_log(2, package)
print(packages[package]['compress_data'])
funcs = packages[package]['Functions']
level_log(3, "Functions")
for func in funcs:
level_log(4, func)
print(funcs[func]['compress_data'])
level_log(3, "Vars")
vars = packages[package]['Vars']
for var in vars:
# print(var)
level_log(4, var)
print(vars[var]['compress_data'])
运行方式:
$ python3 demo.py > result.md
结果
-
先解析了一个自己写的简单 rust 项目:dependencies-patch。得到的结果详见 dependencies-parse
-
然后最近会尝试开始解析 ArceOS 等内核,今天试了一下似乎有点慢。
OS 比赛支持
内核测例多架构支持
将 2025 初赛测例进行修改,编译为 x86_64/riscv64/aarch64/loongarch64 四个架构的镜像。
- 测例仓库上2025_multiarch目前可以支持同时编译生成 x86_64/riscv64/aarch64/loongarch64 四个架构的 Musl 和 glibc 测例。
- starry-next 仓库已经通过的 riscv64 和 loongarch64 测例也可以通过 x86_64 和 aarch64 的版本。
- 预编译好的镜像发布在 2025年初赛SD卡镜像
并且我提供了一个新的 docker 镜像。该镜像下可以支持编译比赛测例,并且运行 starry-next 内核,输出这些测例的运行信息。Docker 镜像对应的构建仓库详见 https://github.com/Azure-stars/os-contest-2024-image,可以为比赛平台评测机所用镜像和即将到来的 Github CICD 工作作参考。
内核测例 Bug 修复
pre-2025分支为本年度赛事使用的初赛测例所在分支。经过和几位同学的测试,发现测例内存在一些 Bug,并通过 PR 或者直接 commit 的形式进行了修复。共提交了 4 次修复。
初赛测例分析
在编译出 x86_64 的镜像之后,便可以在 Linux 主机上进行系统调用分析。通过解析 strace 生成的 log 可以快速得到测例在 Linux 下所需的 syscall 和相关的行为。
以 musl-busybox 测例为例子,在 sdcard/musl 目录执行如下指令:
strace -f -e trace='!read,write,readv,writev,lseek,dup' -o strace_musl_busybox.log ./busybox sh ./busybox_testcode.sh
即可得到 busybox 调用的 log。
-e trace='!read,write,readv,writev,lseek,dup是为了避免 LOG 中输出过内容导致文件过大。因为 IOZONE 等测例会执行非常多次相关的 syscall 进行 benchmark 测试,因此需要过滤掉这类 syscall。
我们简单对这类 LOG 进行分析:
# Description: Extract syscall list from strace log file
import argparse
argparser = argparse.ArgumentParser()
argparser.add_argument('-s', '--strace_log', type=str, help='strace log file')
args = argparser.parse_args()
STRACE_LOG = args.strace_log
SYSCALL_LIST = []
with open(STRACE_LOG + '.log', 'r') as f:
lines = f.readlines()
for line in lines:
if '(' not in line:
continue
# If using strace -f to trace, the first field of each line is the pid, so we need to remove it
if line[0].isdigit():
line = line.split(' ', 1)[1]
syscall = line.split('(')[0]
# Remove useless information
if syscall.find('<') != -1 or syscall.find('+') != -1:
continue
if syscall not in SYSCALL_LIST:
SYSCALL_LIST.append(syscall)
with open(STRACE_LOG + '_syscall_list.txt', 'w') as f:
for syscall in SYSCALL_LIST:
f.write(syscall + '\n')
即可得到支持 busybox 测例所需要的 syscall 列表 syscall_list。
对所有的测例进行统计,可以得到 musl 测例下所需要的 syscall list。