项目演示视频
主要是录一些项目网站的演示视频,防止哪天挂了( 简单编译器项目: 死锁&内存泄漏检测SDK项目: 性能分析agent skill项目: Sandbox SDK项目:
Agent代码执行沙箱SDK开发日志
2026-02-17 2026-02-21 2026-02-23 2026-03-15主要修改了以下: 每个语言一个镜像改为每个模板一个镜像 使用docker镜像构建rootfs,而不是使用apline linux的rootfs挂载,chroot手动构建 增加了web search模板,提供网络搜索接口 虚拟机内置代理改为c++实现,避免python环境依赖
基于qemu的系统调用插桩工具
qemu训练营的项目:https://opencamp.cn/qemu/camp/2025/stage/7?tab=rank 2026-02-14增加了x86_64支持,添加了实时输出功能: 2026-03-15做了以下修改: 使用cr3+FS_BASE作为task的标识符 在arch_prctl(ARCH_SET_FS)和execve适配了标识符迁移,因为他们会导致标识符变化,但是task并不会变化
RAT & SSA
RAT (Register Alias Table) 是 CPU 前端的寄存器别名表。 SSA (Static Single Assignment) 是静态单赋值,一种编译器内部的中间代码表示形式。 今天突然想到这两个东西的一个共同之处,就是它们用类似的方法做到了假依赖消除,区别就是 SSA 是静态的,RAT 是动态的。 具体来说,针对一个变量/寄存器有新的赋值的时候,不改旧值,而是找个新的来装新值(SSA 用新名字接,RAT 用新物理寄存器接,旧的那份都先留着,直到没人用再丢)。 真依赖 & 假依赖在之前的博客中也说过一些通过消除串行依赖来优化性能的相关内容。依赖就比较好理解了,下一条指令的执行依赖于上一条指令的结果。依赖也有真依赖和假依赖: 真依赖:不管外界情况怎么样,不能交换它们的执行顺序。 假依赖:可以通过增加寄存器/变量的数量来破除,达到并行。也就是本质上来说假依赖是名字上的依赖,不是数据依赖。 举例说明: RAW 示例123I1: mov eax, 5 ; 写 eax ; ↓ 数据流(I2 真的需要 I...
Return in Memory & URVO & NRVO
本篇博客代码示例来自:https://sigcpp.github.io/2020/06/08/return-value-optimization#9 函数返回的两种方式GCC 中函数返回值有两种传递方式:寄存器返回和内存返回。 寄存器返回:适用于标量类型(int、double、指针等)以及较小的聚合类型,直接通过寄存器(如 RAX、XMM0)传回。 内存返回:对于较大的聚合类型或非平凡类型,调用方(caller)会在栈上分配空间,并将该地址作为隐藏参数传递给被调方(callee)。被调方直接将返回值构造在这个地址上,同时 ABI 规定函数返回时将该地址存入指定的返回寄存器(如 RAX)。 内存返回的决策条件编译器通过以下两个关键条件决定是否采用内存返回(代码位于 function.cc 和 i386.cc): 1. TREE_ADDRESSABLE(function.cc:2112)当类型被标记为 TREE_ADDRESSABLE 时,强制使用内存返回: 非平凡可复制类型(non-trivially copyable) 带有虚函数的类(需要 vptr) 包含引用成员的结构...
PLT Hook的死锁递归bug排查
这篇博客记录一下开发内存泄露和死锁检测 SDK 过程中遇到的一个 bug。 问题背景SDK 使用的是 PLT Hook,也就是替换要检测模块的 GOT,使其指向 SDK 的函数。 按理来说每个模块的 PLT 都是隔离的,我去 hook 其他模块的 GOT,SDK 自己的模块不会受到任何影响,也就是说不会出现 hook 中比较常见的递归 hook 问题。 在内存泄露模块开发时,没有遇到任何问题。但在开发死锁检测模块时,出现了 SDK 自己的函数被自己 hook 了,导致递归栈溢出的问题。 问题分析这个问题的解决方法也不难,就是加一个防重入标志。但是这个问题是怎么造成的?为什么 malloc 等函数的 hook 就没有出现这个问题? 经过一段时间的调试和拷打ai,得到了以下结论: 根本原因导致无限递归的是 mutex::lock。 被检测模块导出了 mutex::lock 符号,如下: 12345test@test-VMware-Virtual-Platform:~/projects/nv_detector/build/examples$ nm -D /home/test/proje...
内存泄露&死锁检测工具开发日志
最近在写一个内存泄露和死锁检测的检测SDK项目,写下日志简单记录一下。用的方案是 plt hook 和 epbf。 2026-02-04写项目最开始呢就先配了一下 clangd, clang-tidy, clang-format,谷歌的代码风格和规范除个别几条还是挺好用的。 先是实现了一下 hook 模块,然后写了一个例子,测试如下: 2026-02-05添加了分配释放函数的记录模块,不过还有一些遗漏。添加了检测结果的调用栈,行号的命令行和日志输出。添加了测试文件。 测试文件输出: 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120...
2026.1.26 - 2026.2.1 周报
L1 Cache 组相联度探测做了一下 L1 Cache 组相联度探测。使用不同的步长访问内存,制造 L1 Cache 冲突,在特定步长下会大幅下降。 主要原因就是: 特定步长下降是 Cache 冲突,导致 L1 Cache 不够放了,挤到 L2 了。 整体下降是 Data TLB 不够用了,因为到后面步长变大,涉及的页面数变多了。 能用的 Set 数量 = 总 Set 数 / GCD(总 Set 数, stride/64) stride = 256 的时候 set 只能用到 1/4 stride = 4096 的时候,set 只能用到 1/64,所以在这里到达最低点 Softmax 算子的实现及优化找了一些课程学习了一下 CUDA 编程,主要做了 Softmax 算子的实现及优化。 优化过程为: 1. CPU 实现代码层面完全串行,只有在 CPU 后端没有依赖链的时候有单核内部的微指令级别的并行。 2. GPU Kernel 1 实现基本就是原封不动地搬到了 GPU 上,只不过我们给它设置了 N 个线程块,每个线程块一个线程,用 int i = blockIdx....










