启动调试
gdb ./待调试的程序
#不带参数
(gdb) run
#带参数
gdb --args ./your_program arg1 arg2 arg3
(gdb) run arg1 arg2 arg3
#图形化代码界面
(gdb) layout src
基础调试命令
命令 | 缩写 | 作用 |
---|---|---|
run [args] | r | 运行程序(可带命令行参数) |
break <location> | b | 在函数/行号处设置断点(如 b crypto_aead_init_x ) |
next | n | 执行下一行(不进入函数) |
step | s | 执行下一行(进入函数) |
continue | c | 继续运行直到下一个断点 |
print <expr> | p | 打印变量/表达式(如 p key[0] ) |
backtrace | bt | 查看调用栈 |
quit | q | 退出 GDB |
调试加密函数的实战示例
(1) 设置断点
# 在关键函数和行号设断点
(gdb) b crypto_aead_init_x
(gdb) b main:15 # 假设第15行调用加密函数
(2) 运行并检查参数
(gdb) run
# 程序会在断点处暂停# 查看传入的 key 和 nonce
(gdb) p *key@32 # 打印key的32字节
(gdb) p *nonce@24 # 打印nonce的24字节# 检查OpenSSL上下文是否创建成功
(gdb) p ctx->evp_ctx
(3) 单步跟踪
(gdb) s # 进入EVP_EncryptInit_ex
(gdb) n # 跳过库函数内部
(4) 捕获错误
如果函数返回错误:
(gdb) p ERR_get_error() # 打印OpenSSL错误码
(gdb) p (char*)ERR_reason_error_string(ERR_get_error()) # 错误描述
高级调试技巧
(1) 条件断点
# 仅当key的第一个字节为0时触发断点
(gdb) b crypto_aead_init_x if key[0] == 0
(2) 观察点(Watchpoint)
# 监控key是否被意外修改
(gdb) watch *(uint8_t(*)[32])key
(3) 内存检查
# 检查EVP_CIPHER_CTX内存
(gdb) x/32xb ctx->evp_ctx
(4) 调用栈分析
# 崩溃时查看调用栈
(gdb) bt full
加密场景专用命令
(1) 检查密钥随机性
# 在生成key/nonce后暂停
(gdb) p /x *key@32 # 16进制格式输出
(2) 跟踪加密过程
# 在加密前检查明文
(gdb) p *plain_text@text_size# 加密后检查密文
(gdb) p *cipher_text@text_size
(3) 验证MAC计算
# 比较生成的MAC
(gdb) p /x *mac@16
GDB 图形化界面(可选)
启用 TUI 模式:
gdb -tui ./aead_demo
# 或运行时按 Ctrl+X+A