部署 Woboq Code Browser 代码浏览器

起因是这样的, 最近不是在学堆嘛, 得翻各种 glibc 源码. 但是 elixir 的索引做得很差, 点一下相当于全文搜索, 那我要你这索引干嘛. 后来找到了 woboq, 官方实例有 glibc, 试了一下还挺方便. 简单搜索了一下, 并没有找到别人搭建好的各种 glibc 版本的代码浏览器, 于是程序员思维: 自己动手!

这里 下载 glibc 源码, 或者直接 clone:

1
git clone https://sourceware.org/git/glibc.git && cd glibc

https://github.com/rizsotto/Bear

用来生成 compile_commands.json 文件, 这玩意 Woboq 要用到.

可以在 这里 下载现有的包, 或者自己编译.

本着懒的原则, 这里就直接下载包安装了.

注意不同版本的用法不一样, 高版本为 bear -- verb, 低版本为 bear verb

https://github.com/KDAB/codebrowser

同样可以下载包或者编译. 这里选择自行编译. 注意 clang 和 llvm 只支持到 12, 使用 14 会报错 (虽然最新的 commit 说明是 Support Clang 14 呵呵呵).

1
2
3
4
cd codebrowser
sudo aptitude install llvm-12 clang-12 libclang-12-dev
cmake . -DCMAKE_BUILD_TYPE=Release
make

编译完后 ./generator/codebrowser_generator 是代码生成器, ./indexgenerator/codebrowser_indexgenerator 是索引生成器.

使用 bear make 编译 glibc 源码, 以生成 compile_commands.json 文件.

首先 checkout 切换到想要的版本, 比如这里我用 2.23 尝试一下.

1
git checkout release/2.23/master

然后执行如下命令:

1
2
3
4
mkdir build
cd build
../configure --prefix=/usr --disable-werror --without-selinux
bear -- make

编译选项主要设置了一个路径. 默认是 /usr/local 不给过, 我们不安装, 所以其实设置成啥问题不大. 然后是取消 werror, 因为编译器版本太老或太新可能导致有警告通不过编译. 最后取消 selinux, 因为编译了一次发现到 selinux 报错了…

可以看到, glibc/build 文件夹下出现了 compile_commands.json.

非常见鬼的是, 我电脑版本 glibc 是 2.35 的, 编译 2.23, 2.27, 2.35 都没问题, 而编译 2.31 出现了奇怪的错误. 然后我起了个 ubuntu 20.04 的 docker 编译出来了.

参考官方示例

1
2
3
4
5
6
# ./generator/codebrowser_generator -b $BUILD_DIRECTORY -a -o $OUTPUT_DIRECTORY -p codebrowser:$SOURCE_DIRECTORY:$VERSION
# ./indexgenerator/codebrowser_indexgenerator $OUTPUT_DIRECTORY
# cp -rv ./data $DATA_DIRECTORY
./generator/codebrowser_generator -b ../glibc/build/ -a -o ~/woboq/glibc/ -p 2.23:../glibc/:2.23
./indexgenerator/codebrowser_indexgenerator ~/woboq/glibc/
cp -rv ./data ~/woboq/data

最后在 ~/woboq/glibc/ 就能看到了.

scp 到服务器 (这玩意可真大, 得打个包, 不然效率太低), 配一下 Nginx 即可. 略.

搞了 2.23, 2.27, 2.31, 2.35 的, 放到了 这里. 界面稍微有点不符合现代审美, 如果可能 (虽然很多时候这么说都是不可能了) 自己搓一个好看的 css.

以及, 由于把一堆版本的放在了一起, 导致索引有点问题. 使用的时候需要注意一下. 2.35 貌似符号索引都有, 而其他版本的老索引到 2.35 的符号上来, 可能是机器的 libc 是 2.35 的, 编译出来符号才没有丢失? 不研究了, 反正比 elixir 方便.

乐, 花了大半天搞这玩意, 本来打算今天继续学 tcache stashing unlink attack 的.