Tools

Ccache

CLI

安装(ubuntu 20.04 version 3.7.7)
sudo apt install ccache
指定最大缓存量
ccache -M 1G
清除缓存
ccache -C

Install from Source

apt install libhiredis-dev asciidoctor
wget -c https://github.com/ccache/ccache/releases/download/v4.6/ccache-4.6.tar.gz
解压缩和路径跳转
mkdir build
cd build
cmake -DCMAKE_BUILD_TYPE=Release ..

CMake

find_program(CCACHE_FOUND ccache)
 if(CCACHE_FOUND)
 set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ccache)
 set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ccache)
endif(CCACHE_FOUND)

GDB

LLDB的文档不太全,通用性较低,暂时还是倾向于使用GDB

Configuration

echo "set history save on" >> ~/.gdbinit
echo "set print thread-events off" >> ~/.gdbinit
echo "set extended-prompt \w (gdb) " >> ~/.gdbinit
  • 隐藏启动时的提示信息和版权信息,details

方案一(CLI):设置别名
alias gdb="gdb -q"
方案二(配置文档):注意不是gdbinit (from gdb 11)
echo "set startup-quietly on" >> ~/.gdbearlyinit

CLI

命令行

abbreviation / example

作用

python-interactive [command]

pi

进入Python交互模式

python [command]

py [command]

执行Python命令行

break [line]

break 23

打断点

info vtlb

查看虚函数表

print

查看变量

info threads

查看线程信息

info locals [variable_name]

查看函数栈的局部变量

Altering

修改一个变量的值(CLion中对应的快捷键为F2

(gdb) set var width=47

Breakpoint

给某行打断点
(gdb) break linenum
(gdb) break filename:linenum


(gdb) break filename:function

Disassemble

使用 disassemble 进一步看出现 dump core 出现的汇编位置

img

Frame

Backtrace

查看调用栈
(gdb) backtrace
(gdb) where
(gdb) info stack

Frame

切换到某一帧
(gdb) f <num>
查看该帧的局部变量
(gdb) info locals
查看形参
(gdb) info args

Library

查看链接的动态库
info share
image-20220810232749699

Pretty Printer

查看已有的pretty printer,包括关闭的
(gdb) info pretty-printer
Print the list of installed pretty-printers. This includes disabled pretty-printers, which are marked as such.
关闭pretty printer
(gdb) disable pretty-printer
启动pretty printer
(gdb) enable pretty-printer

Python

gdb python

(gdb) set args <python文件名>
(gdb) run (gdb)

Custom GDB Command

  • 一般会使用regex来判断输入变量的类型是否符合需求

def vec_lookup_function(val):
    lookup_tag = val.type.tag
    if lookup_tag == None:
        return None

    regex = re.compile("^.*vector_base<.*,.*>$")
    if regex.match(lookup_tag):
        return VectorPrinter(val)

    return None

Practice

ROS

追加tag
launch-prefix="gdb -ex run --args"
option:
-ex <command> 执行给定的GDB command

Signal

Practice

诊断rviz段错误

  • ROS rviz增加 cameraimage display时,会出现段错误(segmentation fault)

img

步骤一:执行程序

gdb python
(gdb) run <py_file>.py

步骤二:添加display触发异常

img

步骤三:查看调用栈的情况,可定位到是哪个函数产生段错误(加上full会同时输出局部变量

(gdb) bt full

img

GDB无响应

原因未知,可通过下发相关信号解决

kill -CONT <pid of the process>

Extension

GDBGUI

暂时没感觉新颖的地方

  • Install

pip install gdbgui
gdbgui

Reference

TODO

ClangBuildAnalyzer

Install

安装ClangBuildAnalyzer
git clone https://github.com/aras-p/ClangBuildAnalyzer.git
cd ClangBuildAnalyzer
make -f projects/make/Makefile
cd build
sudo cp ClangBuildAnalyzer /usr/local/bin/
安装 clang
sudo apt install clang-12

Usage

  • cmake导入相关参数

set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ftime-trace")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ftime-trace")
ClangBuildAnalyzer --all <artifacts_folder> <capture_file>

LLDB

CLI

命令行

abbreviation / example

作用

script

script import sys

调用内置的Python解析器并执行(若无参数则进入交互模式)

command

Commands for managing custom LLDB commands

command script

process attach

process attach --pid 123

调试一个正在运行的进程

Python

查看内置Python解析器的位置
lldb -P
sudo mkdir -p /usr/lib/local/lib/python3.10/
ln -s /usr/lib/llvm-14/lib/python3.10/dist-packages/ /usr/lib/local/lib/python3.10/dist-packages
  • 自定义lldb命令(基于Python)

导入外置python模块
(lldb) command script import <...>.py
构建函数别名并导入到lldb中
(lldb) command script add -f <模块名.函数名> 别名
(lldb) 别名
def __lldb_init_module(debugger, internal_dict):
    debugger.HandleCommand('command script add -f ls.ls ls')
    print('The "ls" python command has been installed and is ready for use.')

image-20220325101330845

Variable Formatting

  • 查看当前函数栈帧的变量

(lldb) frame variabel <变量名>
(lldb) v <变量名>
  • 导入type formatter

type summary add -x \"Eigen::Matrix\" -F <module_name.function_name>
-x: type names are treated as regular expressions instead of type names
(lldb) type summary add -x \"Eigen::Matrix\" -F eigen_data_formatter.format_matrix

Breakpoint

(lldb) breakpoint set --file main.c --line 3
等价于
(lldb) br s -f main.c -l 3
给函数名符合正则条件的函数打断点
(lldb) breakpoint set --func-regex print.*

Extension

Reference

FlameGraph

分析CPU使用情况

Install

安装依赖perf
sudo apt install linux-tools-common linux-tools-generic linux-cloud-tools-generic linux-tools-$(uname -r) linux-cloud-tools-$(uname -r)
导入生成火焰图的相关脚本
git clone https://github.com/brendangregg/FlameGraph.git

Generate Flame Graph

image-20210904163304591

步骤一:记录调用栈信息

sudo perf record -F 99 -p <pid> -g -- sleep 60
perf script > out.perf

NOTE

  • capture可用不同的工具,比如perfDTrace

  • perf record options项

img


步骤二:整合(fold)调用栈信息

./stackcollapse-perf.pl out.perf > out.folded

步骤三:生成(render)火焰图

./flamegraph.pl out.folded > out.svg

Reference

Strace

用于跟踪某个程序调用的 sysyemcall 和 触发的signal

Time

  • 查看一个可执行文件的执行时间

time <file_name>

Valgrind

  • 安装

sudo apt-get install valgrind
image-20220226172204902

Macro

dgb

  • 用于替代cout和printf

安装方式:对头文件进行软链接
git clone https://github.com/sharkdp/dbg-macro
sudo ln -s $(readlink -f dbg-macro/dbg.h) /usr/include/dbg.h

Distcc

分布式编译工具

Usage

服务端和客户端均安装distcc
sudo apt install distcc # 服务端配置
客户端配置
export DISTCC_VERBOSE=1 DISTCC_LOG=/tmp/distcc.log  # optional just for debug
CC="distcc gcc" CXX="distcc g++" cmake ..
指定服务端
export DISTCC_HOSTS='ah_chung@10.23.21.110/32 localhost/2'
make -j$(distcc -j)
服务端设置
sudo distccd --daemon --allow 10.23.21.1/24 \
--log-file /var/log/distccd.log --log-level=debug \
--jobs 32 \
--pid-file=/var/run/distccd.pid

备注

服务端/volunteer即接收请求,执行编译,启动distccd后台进程的主机;客户端即有源代码待编译,发布编译请求的主机; allow option指的是允许哪些client与当前server相连; DISTCC_HOSTS 反斜杠后的数字代表指派的进程数

  • 在client端显示调度的信息

在终端显示调度信息
distccmon-text
使用gui显示调度信息
distccmon-gnome`
img

Catkin Build

CC="distcc gcc" CXX="distcc g++" catkin build -j$(distcc -j) -p$(distcc -j)

Scrap

  • 配置文档:/etc/default/distcc(实际使用时基本没用上,直接在命令行指定)

  • exit code

  • pcl使用distcc实现分布式编译(当前问题为在编译到49%时会卡住,出现107错误,过很长一段时间才会恢复正常)

  • 后台进程102错误时,可以尝试restart重启服务

img
  • distcc分布式编译会受限于网络带宽

IWYU

头文件分析工具(LLVM工具组件之一),看头文件是否冗余

Install

使用脚本的方式进行安装,安装最新的稳定版本
sudo bash -c "$(wget -O - https://apt.llvm.org/llvm.sh)"
使用apt进行安装
sudo apt install llvm-14-dev libclang-14-dev clang-14
  • 编译和安装IWYU(以clang的版本号为14.0为例)

git clone https://github.com/include-what-you-use/include-what-you-use.git
cd include-what-you-use
git checkout clang_14.0
mkdir build && cd build
cmake -G "Unix Makefiles" -DCMAKE_PREFIX_PATH=/usr/lib/llvm-14 ..
make
默认安装在/usr/local/bin/include-what-you-use
sudo make install
  • 构建CMakeLists

cmake_minimum_required(VERSION 3.13)
project(iwyu_base_case)

set(CMAKE_CXX_STANDARD 20)

add_executable(iwyu_base_case main.cpp)
主要是添加下面这一句
set_property(TARGET iwyu_base_case PROPERTY CXX_INCLUDE_WHAT_YOU_USE "/usr/local/bin/include-what-you-use")
  • 执行make时则会提供如下信息

image-20210729223215252

Q&A

  • 当发现一个程序CPU占用率高时,如何调错?

从火焰图看占用资源最多的函数