LLDB调试时Step into命令无法步入函数问题排查咨询
环境信息
- 调试对象:g编译构建的C/CMake项目,使用LLDB作为调试工具
- 运行环境:Ubuntu 20.04操作系统,x86_64架构
问题表现
- 执行Step into命令时无法进入目标函数内部,实际表现为步过效果;但直接在待步入函数内部设置断点时,断点可正常命中
- 更换为GDB调试时,Step into功能运行完全正常
- 复现不依赖IDE:使用VSCode搭配相关调试插件、CLion调试均会触发相同异常,现有公开检索资料未提供有效解决方案
排查方向与解决思路
- 优先排查调试信息格式兼容问题
Ubuntu 20.04软件源内置的g++ 9.3版本默认生成DWARF v5格式的调试信息,而同版本源内置的LLDB 10对DWARF v5的行号表解析存在已知缺陷,无法正确识别函数调用的行边界,最终导致Step into行为异常。
可在CMake配置中追加以下编译选项,关闭优化、禁用内联、强制生成兼容性更好的DWARF v4调试信息后重新编译测试:set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O0 -fno-inline -gdwarf-4") - 检查LLDB默认步过过滤规则
LLDB默认存在target.process.thread.step-avoid-regexp配置项,默认值为^std::,会自动跳过所有命名空间匹配std::前缀的函数。如果待步入函数所在命名空间、函数名意外匹配该正则(比如自定义了std命名空间下的函数、函数名前缀命中匹配规则),就会被直接步过。
调试时可在LLDB交互命令行执行以下命令临时清空过滤规则测试:
若测试验证是该问题导致,可将上述配置写入settings set target.process.thread.step-avoid-regexp ""~/.lldbinit文件实现永久生效。 - 排查桩代码识别异常问题
如果待步入的是虚函数、静态链接库导出函数,g生成的调用入口会先经过PLT桩、thunk跳转段,低版本LLDB会将这类无直接源码映射的桩代码识别为系统函数,直接执行步过逻辑。
临时验证可在待步入的调用行先执行stepi(指令级单步步入)进入实际函数体,后续即可正常进行源码级单步;根源解决可将LLDB升级到12及以上版本,新版本已针对g生成的PLT/thunk段调试信息识别做了适配修复。 - 排查IDE调试配置的规则覆盖
VSCode C++插件、CLion默认会开启「仅调试项目代码」类的配置,自动给LLDB追加步过规则,跳过非项目路径下的函数。可检查IDE调试配置,关闭「Just My Code」「自动跳过第三方/系统库代码」类选项,同时确认待调试源码路径未被加入调试器的源码排除列表。
内容的提问来源于stack exchange,提问作者AMA
相关产品推荐
相关产品推荐

