如何调试ClickHouse源码

本文介绍ClickHouse源码的编译安装,并介绍了如何通过lldb来调试Clickhouse。
本文调试时的操作系统是:Mac OS。若是linux可以可以基于参考文献自行操作,调试工具可使用gdb。

安装依赖的包和工具

$ brew install cmake ninja libtool gettext

下载源码

源码比较大,可能时间比较长一些。

$ git clone --recursive https://github.com.cnpmjs.org/ClickHouse/ClickHouse.git

# 若是中断可以使用以下命令
$ git fetch  --recurse-submodules
$ git submodule update --init --recursive

#或
$ git submodule update --init --recursive && git pull --recurse-submodule

下载mac os的编译器

我这里使用的是Xcode 的原生 AppleClang 编译器进行构建,所以需要安装llvm。

若想使用其他的编译器可以参考这里的说明:
https://clickhouse.tech/docs/en/development/build-osx/

注意:这一步比较关键,编译时出现的各种问题,很多都是由于这一步没有安装,或则编译器指定不对。

$ brew install llvm

编译Clickhouse源码

注意:这一步需要指定已经安装的编译器来进行编译。

$ mkdir build
$ cd build
$ CC=$(brew --prefix llvm)/bin/clang CXX=$(brew --prefix llvm)/bin/clang++ cmake -DCMAKE_BUILD_TYPE=Debug  ..

若没有任何错误,编译完成后的可执行代码在:ClickHouse/build/programs文件夹中,通过ls命令查看一下:

$ cd ClickHouse/build/programs
$ ls -lt
lrwxr-xr-x  1 user1  g1    10B  8  1 18:07 clickhouse-format -> clickhouse
lrwxr-xr-x  1 user1  g1    10B  8  1 18:07 clickhouse-benchmark -> clickhouse
lrwxr-xr-x  1 user1  g1    10B  8  1 18:07 clickhouse-local -> clickhouse
lrwxr-xr-x  1 user1  g1    10B  8  1 18:07 clickhouse-copier -> clickhouse
lrwxr-xr-x  1 user1  g1    10B  8  1 18:07 clickhouse-extract-from-config -> clickhouse
lrwxr-xr-x  1 user1  g1    10B  8  1 18:07 clickhouse-client -> clickhouse
lrwxr-xr-x  1 user1  g1    10B  8  1 18:07 clickhouse-compressor -> clickhouse
lrwxr-xr-x  1 user1  g1    10B  8  1 18:07 clickhouse-server -> clickhouse
lrwxr-xr-x  1 user1  g1    10B  8  1 18:07 clickhouse-obfuscator -> clickhouse
-rwxr-xr-x  1 user1  g1   906M  8  1 17:57 clickhouse

可以看到clickhouse-server等应用程序都连接到clickhouse这个可执行文件。也就是说clickhouse是所有程序的入口。

为了可以调试代码,我们在编译时添加了 -DCMAKE_BUILD_TYPE=Debug 选项,所以该文件中包含了调信息,导致文件很大。

下面就可以来调试Clickhouse的源码了。

调试Clickhouse

在Mac OS下,我们使用lldb来调试clickhouse。也可以使用gdb来调试,不过gdb需要授权。lldb可以有两种调试方式,一种是在程序启动时进行调试;还有一种是通过attach到正在运行的某个进程id来进行调试。

这里我们采取程序启动进行调试的方式来观察和调试Clickhouse的源码。

先进入我们刚才编译好Clickhouse的可调试的二进制文件,再通过lldb的命令进行调试。操作如下:

$ cd ClickHouse/build/programs
$ lldb ./clickhouse-server
# 打一个断点,在main函数
(lldb) b main
# 运行main函数
(lldb) r --config-file ../../programs/server/config.xml
# 单步执行
(lldb) n
# 查看执行到哪一步了,并打印调用栈
(lldb) bt
# 进入一个函数的内部
(lldb) s

查看其输出

(lldb) b main
Breakpoint 2: 7 locations.

(lldb) r --config-file ./programs/server/config.xml
Process 16763 launched: '/Users/hover/opensrc/ClickHouse/build/programs/clickhouse-server' (x86_64)
Process 16763 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1 2.1
    frame #0: 0x0000000100002039 clickhouse-server`main(argc_=3, argv_=0x00007ffeefbff560) at main.cpp:374:17
   371 	
   372 	int main(int argc_, char ** argv_)
   373 	{
-> 374 	    inside_main = true;
   375 	    SCOPE_EXIT({ inside_main = false; });
   376 	
   377 	    /// Reset new handler to default (that throws std::bad_alloc)
Target 0: (clickhouse-server) stopped.


(lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1 2.1
  * frame #0: 0x0000000100002039 clickhouse-server`main(argc_=3, argv_=0x00007ffeefbff560) at main.cpp:374:17
    frame #1: 0x00007fff6915008d libdyld.dylib`start + 1

这样就可以观察Clickhouse-server的函数调用关系了。

Clickhouse用到了多线程,如何使用lldb来调试多线程,可以自行百度一下。

问题解决

错误1:Cannot find objcopy.

没有找到objcopy命令,请安装objcopy工具。

错误2:
AppleClang is not supported, you should install clang from brew.

在cmake时指定特定的编译工具。

小结

本文讲述了如何在Mac OS下编译和调试Clickhouse源码,通过本文就可以对Clickhouse的代码进行调试。欢迎进入Clickhouse的源码世界。

参考资料