1. 系统查找动态库路径的配置:

  •  1. 临时环境变量设置: export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:库路径,但是切换终端即失效
  •  2. 单独用户级设置: 写入用户配置文件 ~/.bashrc, 然后 source ~/.bashrc
echo 'export PATH=$PATH:/opt/zeek/bin' >> ~/.bashrc

source ~/.bashrc
  • 3. 所有用户级设置: 写入 /etc/profile
echo 'export PATH=$PATH:/opt/zeek/bin' | sudo tee -a /etc/profile

source /etc/profile
  •  4. 系统级设置: 写入 /etc/ld.so.conf 加入库的绝对路径, 然后更新: sudo ldconfig -v
  •  5. 创建符号链接到系统库目录 /lib 或 /usr/lib: sudo ln -s /自己的/库/路径/libxxx.so /lib/libxxx.so

2. GDB 配置与使用流程

2.1 检查核心转储设置,启用核心转储:

ulimit -c           # 检查核心转储设置

ulimit -c unlimited # 允许无限大小的 core 文件

2.2 配置核心转储文件生成路径:

ulimit -c unlimited                     #步骤1:允许无限大小的 core 文件

sudo mkdir -p /coredumps                #步骤2:创建专门存放 core 文件的目录

sudo chmod 777 /coredumps               #步骤3:设置目录权限(程序崩溃时应显示: Segmentation fault(core dumped), 若没有core dumped, 可能是文件夹权限问题)

echo "/coredumps/core.%e.%p" | sudo tee /proc/sys/kernel/core_pattern #步骤4:设置 core_pattern 到新目录

cat /proc/sys/kernel/core_pattern       #步骤5:确认 core_pattern 已设置成功,查看核心文件生成的位置

./home/yy/SecKey/scripts/run.sh         #步骤6:运行测试程序触发段错误

cd /coredumps/                          #步骤7:检查 core 文件是否生成

2.3 加载核心转储文件到 GDB:

gdb //home/yy/SecKey/server /coredumps/core.server.11939

2.4 GDB命令:

    bt                    # 查看堆栈跟踪,输出崩溃时的函数调用栈

    frame <frame_number>  # 切换到指定的堆栈帧,查看崩溃点的代码

    list                  # 查看代码上下文,显示崩溃点附近的代码

    print <variable_name> # 打印变量的值,查看崩溃时的变量状态

    quit                  # 退出GDB

3. CMakeLists.txt 模板

# ===========================
# 1.基本配置
# ===========================
cmake_minimum_required(VERSION 3.5.1)           # 设置最低 CMake 版本要求
project(FAULT_DIAG VERSION 1.0 LANGUAGES CXX)   # 定义项目名称和版本
 
# ===========================
# 2.用户可选参数: 架构
# 参数:
#   ARCH:变量名
#   ${ARCH}:初始值为用户传递参数
#   CACHE:表示这是一个缓存变量(即可以在命令行通过 -DARCH=x86_64 传入)
#   STRING:变量类型为字符串
#   "Target architecture ...": 帮助信息,显示在 GUI 工具(如 ccmake 或 cmake-gui)中
#   FORCE:覆盖之前的设置
# ===========================
set(ARCH ${ARCH} CACHE STRING "Target architecture (required: x86_64 or aarch64)" FORCE)
set_property(CACHE ARCH PROPERTY STRINGS "x86_64" "aarch64")   # 限制 ARCH 只能为 x86_64 或 aarch64
if(NOT ARCH)                                                   # 检查 ARCH 是否为空
    message(FATAL_ERROR "You must specify -DARCH=x86_64 or -DARCH=aarch64") 
endif()
if(NOT ARCH STREQUAL "x86_64" AND NOT ARCH STREQUAL "aarch64") # 检查 ARCH 是否为 x86_64 或 aarch64
    message(FATAL_ERROR "Invalid ARCH specified. Must be 'x86_64' or 'aarch64'.")
endif()
 
# ===========================
# 根据架构添加宏定义,用于在代码中区分不同的架构,目前未使用可省略
# 示例调用:
#   #ifdef TARGET_AARCH64
#       // aarch64 特定的代码
#   #else
#        // 其他架构的代码
#   #endif
# ===========================
# if(ARCH STREQUAL "aarch64")
#     add_definitions(-DTARGET_AARCH64)
# elseif(ARCH STREQUAL "x86_64")
#     add_definitions(-DTARGET_X86_64)
# endif()
 
# ===========================
# 3.全局编译选项
# ===========================
set(CMAKE_CXX_STANDARD 20)                           # 使用 C++20 标准
set(CMAKE_CXX_STANDARD_REQUIRED ON)                  # 强制使用指定的标准
set(CMAKE_CXX_EXTENSIONS OFF)                        # 关闭编译器特定扩展
 
# ===========================
# 4.根据构建类型设置编译选项
# ===========================
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
    target_compile_options(${PROJECT_NAME} PRIVATE -Wall -O0 -fPIC -rdynamic -Wno-unused-variable -Wno-deprecated-declarations -DWITH_INCLUDE_XLOCALE_H)
elseif(CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo")
    target_compile_options(${PROJECT_NAME} PRIVATE -Wall -O2 -fPIC -rdynamic -Wno-unused-variable -Wno-deprecated-declarations -DWITH_INCLUDE_XLOCALE_H -g)
else()
    target_compile_options(${PROJECT_NAME} PRIVATE -Wall -O2 -fPIC -rdynamic -Wno-unused-variable -Wno-deprecated-declarations -DWITH_INCLUDE_XLOCALE_H)
endif()
 
# ===========================
# 5.收集源文件
# ===========================
aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/src MAIN_SRC)          # 主函数源文件
aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/src/common COMMON_SRC) # 通用源文件
# ......
 
# ===========================
# 6.定义可执行文件
# ===========================
add_executable(
    ${PROJECT_NAME} 
    ${MAIN_SRC}
    # ......
)
 
# ===========================
# 7.添加头文件搜索路径
# ===========================
target_include_directories(
    ${PROJECT_NAME} PRIVATE                # 私有头文件路径,只在本模块中可见并使用, 这里不必要, 因为只有一个构建目标
    ${CMAKE_CURRENT_SOURCE_DIR}/src/common # common 的头文件路径
    # ......
)
 
# =================================================================================
# 8.指定库文件路径替代 link_directories, 通过指定的是动态库或静态库进行动态或静态链接
# =================================================================================
set(SQLITE_SO "${CMAKE_CURRENT_SOURCE_DIR}/lib/sqlite/${ARCH}/lib/libsqlite3.so") 
 
# ===========================
# 9.链接库
# ===========================
target_link_libraries(${PROJECT_NAME}
    pthread
    ${SQLITE_SO}
)

4. build.sh 编译脚本模板

#!/bin/bash
 
# 获取脚本所在目录的绝对路径
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
 
# 项目根目录(scripts 的上级目录)
PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
 
# 默认值
BUILD_TYPE="Debug"
ARCH="x86_64"
COMPILER="/usr/bin/g++"
 
# 解析命令行参数
while [[ $# -gt 0 ]]; do
    case $1 in
        -t|--type)
            BUILD_TYPE="$2"
            shift 2
            ;;
        -a|--arch)
            ARCH="$2"
            shift 2
            ;;
        -c|--compiler)
            COMPILER="$2"
            shift 2
            ;;
        *)
            echo "Unknown option: $1"
            echo "Usage: $0 [-t build_type] [-a arch] [-c compiler]"
            echo "  build_type: Debug, Release, RelWithDebInfo (default: Debug)"
            echo "  arch: x86_64, aarch64 (default: x86_64)"
            echo "  compiler: path to compiler (default: /usr/bin/g++)"
            exit 1
            ;;
    esac
done
 
# 验证参数
if [ "$ARCH" != "x86_64" ] && [ "$ARCH" != "aarch64" ]; then
    echo "Error: ARCH must be 'x86_64' or 'aarch64'"
    exit 1
fi
 
BUILD_DIR="$PROJECT_DIR/build/"
# 清理旧的构建目录
if [ -d "$BUILD_DIR" ]; then
    echo "Cleaning old build directory..."
    rm -rf "$BUILD_DIR"
fi
 
# 创建新的构建目录并进入
echo "Creating new build directory..."
mkdir "$BUILD_DIR"
cd "$BUILD_DIR" || { echo "Failed to enter build directory"; exit 1; }
 
# 配置 CMake 项目
echo "Configuring CMake project with:"
echo "  Build type: $BUILD_TYPE"
echo "  Target architecture: $ARCH"
echo "  Compiler: $COMPILER"
cmake \
    -DCMAKE_BUILD_TYPE="$BUILD_TYPE" \
    -DARCH="$ARCH" \
    -DCMAKE_CXX_COMPILER="$COMPILER"
    "$PROJECT_DIR"
    
# 构建项目,.表示当前目录
echo "Building the FAULT_DIAG project..."
cmake --build .
 
# 检查构建是否成功
if [ $? -eq 0 ]; then
    echo "FAULT_DIAG build completed successfully!"
else
    echo "FAULT_DIAG build failed!"
    exit 1
fi

5. docker 安装与配置

5.1 安装 docker

    # 1. 更新系统并安装依赖
    sudo apt-get update
    sudo apt-get install -y ca-certificates curl gnupg

    # 2. 添加 Docker 官方 GPG 密钥
    sudo install -m 0755 -d /etc/apt/keyrings
    curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
    sudo chmod a+r /etc/apt/keyrings/docker.gpg

    # 3. 添加仓库
    echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
    $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

    # 4. 安装 Docker
    sudo apt-get update
    sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

    # 5. 添加当前用户到 docker 组
    sudo usermod -aG docker yy

    # 6. 配置镜像
    sudo vim /etc/docker/daemon.json
    # 输入:
    # {
    #     "registry-mirrors": [
    #         "https://docker.1ms.run",
    #         "https://docker.m.daocloud.io"
    #     ]
    # }

    # 7. 查看镜像源
    docker info | grep "Registry Mirrors" -A 3

    # 8. 测试
    docker version
    sudo systemctl daemon-reload
    sudo systemctl restart docker
    docker run hello-world

5.2 拉取镜像

    # 1. 从 dockerhub 拉取镜像
    docker pull ubuntu:latest
    # 2. 查看当前所有的镜像
    docker images
    # 3. 运行容器
    # -it: 交互式终端, -d: 后台运行, --rm: 退出容器后自动删除容器, -p 8080:80: 宿主机的 8080 端口映射到容器的 80 端口
    # -v /home/user:/app/data: 把宿主机的 /home/user 目录挂载到容器的 /app/data 目录
    docker run -it --rm ubuntu /bin/bash
    # 4. 退出容器
    exit    # 交互式
    docker stop <container_id> # 守护进程
    # 5. 查看容器
    docker ps -a
    # 6. 启动容器
    docker start <container_id>
    # 7. 停止容器
    docker stop <container_id>
    # 8. 删除容器
    docker rm <container_id>
    # 9. 删除所有容器
    docker rm 'docker ps -a -q'
    # 10. 删除镜像
    docker rmi <image_id>

5.3 推送镜像

    # 1. 登陆,按照提示输入github的用户名密码
    docker login
    # 2. 将本地镜像重命名成规范名称才可推送
    docker tag ubuntu yy/ubuntu:v1.0
    # 3. 推送自己的镜像
    docker push yy/ubuntu:v1.0

5.4 手动构建镜像

    # 1. 进入容器
    docker run -it ubuntu /bin/bash
    # 2. 配置环境
    # 3. 退出容器
    exit
    # 4. 查看容器
    docker ps -a
    # 5. 提交容器为新的镜像
    docker commit <container_id> yy/newUbuntu:v1.1
    # 6. 查看新的镜像
    docker images

5.5 Dockerfile 构建镜像

  • 编写Dockerfile:
    # 确定基础镜像
    # 安装所需环境
    # 定义执行点(即 docker run 的默认命令)

    FROM ubuntu
    RUN apt-get update
    RUN apt-get install -y gcc
    ENTRYPOINT ["./project"]
  • 构建镜像:

    # 1. 编写 Dockerfile
    # 2. 构建镜像(-t: 镜像名称)
    docker build -t yy/ubuntu:v1.2
    # 3. 查看镜像
    docker images

5.6 离线分发

    # 1. 导出镜像
    docker save -o ubuntu.tar yy/ubuntu:v1.2
    # 2. 导入镜像
    docker load -i ubuntu.tar
    # 3. 查看镜像
    docker images
    # 只包含容器中的文件系统, 无执行点, 暴露端口, 构建历史等

5.7 构建适配于程序的容器

    # 1. 查看程序运行时依赖的动态库
    ldd ./project 

    # 2. 在容器中编译库易失败, 故静态编译
    # 2.1. 完全静态编译
    gcc -static -o project project.c      # Makefile
    set(CMAKE_EXE_LINKER_FLAGS "-static") # cmake
    # 2.2. 静态编译第三方库

6. git 基础命令

  1. 远程仓库设置:
    • 查看已有的远程仓库: git remote -v
    • 删除远程仓库origin: git remote rm origin
    • 新建远程仓库gitee01: git remote add gitee01 https://gitee.com/xxxx.git
    • 更新gitee01指向的项目地址: git remote set-url gitee01 https://gitee.com/xxxx.git
    • 获取gitee01仓库的所有分支和提交记录, 用于被本地分支跟踪: git fetch gitee01
  2. 查看、删除远程分支:
    • git branch -r
    • git push gitee01 --delete main
  3. 本地分支操作:
    • 查看当前分支: git branch, * 号表示当前分支
    • 查看跟踪的远程分支: git branch -vv
    • 设置跟踪分支: git branch -u gitee01/master
    • 切换分支: git checkout master
    • 删除分支: git branch -d main
    • 新建master分支并跟踪到gitee01的master分支: git checkout -b master gitee01/master
  4. 设置本地分支与远程分支的关联关系,远程仓库的内容会被拉取到你现有的文件夹中,而不会创建额外的子文件夹:
    • git branch --set-upstream-to=gitee01/master
  5. 拉取远程分支的最新代码:
    • git pull gitee01 master --allow-unrelated-histories
  6. 提交本地修改:
    • git status
    • git add .
    • git commit -m "01"
  7. 推送到远程仓库gitee01的master分支:
    • git push gitee01 master
    • git push gitee01 master --force(强制推送,会覆盖当前分支远程仓库的修改和内容)
  8. 从跟踪移除文件:
    • 检查该目录下的文件是否被跟踪:git ls-files | grep 'lib/sqlite/x86_64/'
    • 从跟踪移除文件:git rm --cached -r lib/
Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐