macOS下使用lldb调试共享对象时断点无法触发
macOS下使用lldb调试共享对象时断点无法触发
最近我在macOS上调试一个包含共享对象的C++项目时,遇到了一个头疼的问题:明明能找到共享对象里的函数,也成功设置了断点,但程序运行时完全不会在断点处停下。不过好在最后解决了,这里把整个过程分享给大家。
项目情况
我准备了一个最小复现示例(MWE),包含三个文件:
test_lib.h:声明一个简单的加法函数test_lib.cc:实现加法函数main.cc:调用这个加法函数并输出结果
代码详情
test_lib.h
int add(int a, int b);
test_lib.cc
#include "test_lib.h" int add(int a, int b) { return a + b; }
main.cc
#include <iostream> #include "test_lib.h" int main(int argc, char** argv) { int a = 42; int b = 23; int result = add(a, b); std::cout << "42 + 23 = " << result << std::endl; }
编译命令
我用clang++进行编译,命令如下:
clang++ -std=c++17 -g -isysroot $(xcrun -show-sdk-path) -c main.cc -o main.o clang++ -std=c++17 -g -isysroot $(xcrun -show-sdk-path) -c test_lib.cc -o test_lib.o clang++ -std=c++17 -g -isysroot $(xcrun -show-sdk-path) -shared -fPIC test_lib.o -o test_lib.so clang++ -isysroot $(xcrun -show-sdk-path) -o main main.o test_lib.so
遇到的问题
编译完成后,我用lldb启动调试,执行了以下步骤:
- 启动lldb并加载可执行文件
main - 用
image lookup -vn add查找add函数,能看到test_lib.so里的目标函数 - 用
breakpoint set --shlib test_lib.so --name add给目标函数设置断点 - 运行程序
结果程序直接输出结果后退出,完全没有触发断点。更奇怪的是,同样的代码和调试流程在Ubuntu上是正常工作的。
完整lldb会话记录
(lldb) target create "main" Current executable set to '/Users/konze/lldb_test/main' (arm64). (lldb) image lookup -vn add 1 match found in /usr/lib/dyld: Address: dyld[0x00000001800afdac] (dyld.__TEXT.__text + 52652) Summary: dyld`dyld4::RuntimeState::add(dyld4::Loader const*) Module: file = "/usr/lib/dyld", arch = "arm64e" Symbol: id = {0x00000150}, range = [0x00000001800afdac-0x00000001800afef4), name="dyld4::RuntimeState::add(dyld4::Loader const*)", mangled="_ZN5dyld412RuntimeState3addEPKNS_6LoaderE" 1 match found in test_lib.so: Address: test_lib.so[0x0000000000003f98] (test_lib.so.__TEXT.__text + 0) Summary: test_lib.so`add(int, int) at test_lib.cc:3 Module: file = "test_lib.so", arch = "arm64" CompileUnit: id = {0x00000000}, file = "/Users/konze/lldb_test/test_lib.cc", language = "<not loaded>" Function: id = {0x100000032}, name = "add(int, int)", mangled = "_Z3addii", range = [0x0000000000003f98-0x0000000000003fb8) FuncType: id = {0x100000032}, byte-size = 0, decl = test_lib.cc:3, compiler_type = "int (int, int)" Blocks: id = {0x100000032}, range = [0x00003f98-0x00003fb8) LineEntry: [0x0000000000003f98-0x0000000000003fa4): /Users/konze/lldb_test/test_lib.cc:3 Symbol: id = {0x00000005}, range = [0x0000000000003f98-0x0000000000003fb8), name="add(int, int)", mangled="_Z3addii" Variable: id = {0x10000004f}, name = "a", type = "int", location = DW_OP_fbreg +12, decl = test_lib.cc:3 Variable: id = {0x10000005d}, name = "b", type = "int", location = DW_OP_fbreg +8, decl = test_lib.cc:3 1 match found in /usr/lib/system/libunwind.dylib: Address: libunwind.dylib[0x000000018bd54d38] (libunwind.dylib.__TEXT.__text + 8192) Summary: libunwind.dylib`libunwind::DwarfFDECache<libunwind::LocalAddressSpace>::add(unsigned long, unsigned long, unsigned long, unsigned long) Module: file = "/usr/lib/system/libunwind.dylib", arch = "arm64e" Symbol: id = {0x0000000a}, range = [0x000000018bd54d38-0x000000018bd54e60), name="libunwind::DwarfFDECache<libunwind::LocalAddressSpace>::add(unsigned long, unsigned long, unsigned long, unsigned long)", mangled="_ZN9libunwind13DwarfFDECacheINS_17LocalAddressSpaceEE3addEmmmm" 2 matches found in /usr/lib/libobjc.A.dylib: Address: libobjc.A.dylib[0x00000001800604cc] (libobjc.A.dylib.__TEXT.__text + 9420) Summary: libobjc.A.dylib`objc::SafeRanges::add(unsigned long, unsigned long) Module: file = "/usr/lib/libobjc.A.dylib", arch = "arm64e" Symbol: id = {0x00000002}, range = [0x00000001800604cc-0x0000000180060584), name="objc::SafeRanges::add(unsigned long, unsigned long)", mangled="_ZN4objc10SafeRanges3addEmm" Address: libobjc.A.dylib[0x000000018008fb90] (libobjc.A.dylib.__TEXT.__text + 203664) Summary: libobjc.A.dylib`AutoreleasePoolPage::add(objc_object*) Module: file = "/usr/lib/libobjc.A.dylib", arch = "arm64e" Symbol: id = {0x000001ce}, range = [0x000000018008fb90-0x000000018008fc9c), name="AutoreleasePoolPage::add(objc_object*)", mangled="_ZN19AutoreleasePoolPage3addEP11objc_object" (lldb) breakpoint set --shlib test_lib.so --name add Breakpoint 1: where = test_lib.so`add(int, int) + 12 at test_lib.cc:4:12, address = 0x0000000000003fa4 (lldb) r Process 22598 launched: '/Users/konze/lldb_test/main' (arm64) 42 + 23 = 65 Process 22598 exited with status = 0 (0x00000000)
解决方法
折腾了半天,最后发现是clang/llvm版本的问题!我之前用的是14.0.6版本,断点就是不触发;后来安装了clang+llvm 16.0.5版本,重新编译项目后再用lldb调试,断点就正常工作了。
备注:内容来源于stack exchange,提问作者konze
相关产品推荐
相关产品推荐

