You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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启动调试,执行了以下步骤:

  1. 启动lldb并加载可执行文件main
  2. 用image lookup -vn add查找add函数,能看到test_lib.so里的目标函数
  3. 用breakpoint set --shlib test_lib.so --name add给目标函数设置断点
  4. 运行程序

结果程序直接输出结果后退出,完全没有触发断点。更奇怪的是,同样的代码和调试流程在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.22 12:24:55