在 iOS 模拟器上的动态加载程序中设置断点

Setting breakpoint in dynamic loader on iOS simulator

我 运行 遇到动态加载程序在 dyld_sim`memcmp 中崩溃的问题。我正在尝试确定当时正在加载哪个库,但堆栈似乎已损坏(至少,参数寄存器不可用)。

所以我试图在加载程序中设置一个断点(在堆栈的更上方),但动态加载程序中的断点似乎没有保留。我也尝试设置符号断点,但那些不会触发。不知道是不是我拼错了(比如 "dyld::load" 没用)

有什么我可以尝试的想法吗?

dyld_sim`memcmp:
    0x107154afd <+0>:  pushq  %rbp
    0x107154afe <+1>:  movq   %rsp, %rbp
    0x107154b01 <+4>:  testq  %rdx, %rdx
    0x107154b04 <+7>:  je     0x107154b1e               ; <+33>
    0x107154b06 <+9>:  xorl   %ecx, %ecx
->  0x107154b08 <+11>: movzbl (%rdi,%rcx), %eax         ; Thread 1: EXC_BAD_ACCESS (code=50, address=0x1090fa000)
    0x107154b0c <+15>: movzbl (%rsi,%rcx), %r8d
    0x107154b11 <+20>: cmpb   %r8b, %al
    0x107154b14 <+23>: jne    0x107154b22               ; <+37>
    0x107154b16 <+25>: incq   %rcx
    0x107154b19 <+28>: cmpq   %rcx, %rdx
    0x107154b1c <+31>: jne    0x107154b08               ; <+11>
    0x107154b1e <+33>: xorl   %eax, %eax
    0x107154b20 <+35>: jmp    0x107154b25               ; <+40>
    0x107154b22 <+37>: subl   %r8d, %eax
    0x107154b25 <+40>: popq   %rbp
    0x107154b26 <+41>: retq   
#0  0x0000000107154b08 in memcmp ()
#1  0x0000000107144051 in ImageLoaderMachO::validateFirstPages(linkedit_data_command const*, int, unsigned char const*, unsigned long, long long, ImageLoader::LinkContext const&) ()
#2  0x0000000107147266 in ImageLoaderMachOCompressed::instantiateFromFile(char const*, int, unsigned char const*, unsigned long, unsigned long long, unsigned long long, stat const&, unsigned int, unsigned int, linkedit_data_command const*, encryption_info_command const*, ImageLoader::LinkContext const&) ()
#3  0x000000010714316f in ImageLoaderMachO::instantiateFromFile(char const*, int, unsigned char const*, unsigned long, unsigned long long, unsigned long long, stat const&, ImageLoader::LinkContext const&) ()
#4  0x00000001071356e1 in dyld::loadPhase6(int, stat const&, char const*, dyld::LoadContext const&) ()
#5  0x0000000107139ffd in dyld::loadPhase5(char const*, char const*, dyld::LoadContext const&, unsigned int&, std::__1::vector<char const*, std::__1::allocator<char const*> >*) ()
#6  0x0000000107139bbd in dyld::loadPhase4(char const*, char const*, dyld::LoadContext const&, unsigned int&, std::__1::vector<char const*, std::__1::allocator<char const*> >*) ()
#7  0x000000010713926a in dyld::loadPhase2(char const*, char const*, dyld::LoadContext const&, char const* const*, char const* const*, unsigned int&, std::__1::vector<char const*, std::__1::allocator<char const*> >*) ()
#8  0x000000010713912a in dyld::loadPhase1(char const*, char const*, dyld::LoadContext const&, unsigned int&, std::__1::vector<char const*, std::__1::allocator<char const*> >*) ()
#9  0x000000010713541c in dyld::loadPhase0(char const*, char const*, dyld::LoadContext const&, unsigned int&, std::__1::vector<char const*, std::__1::allocator<char const*> >*) ()
#10 0x00000001071350e6 in dyld::load(char const*, dyld::LoadContext const&, unsigned int&) ()
#11 0x000000010713a4ef in dyld::libraryLocator(char const*, bool, char const*, ImageLoader::RPathChain const*, bool, unsigned int&) ()
#12 0x0000000107140a2e in ImageLoader::recursiveLoadLibraries(ImageLoader::LinkContext const&, bool, ImageLoader::RPathChain const&, char const*) ()
#13 0x000000010713fc8a in ImageLoader::link(ImageLoader::LinkContext const&, bool, bool, bool, ImageLoader::RPathChain const&, char const*) ()
#14 0x0000000107136cc8 in dyld::link(ImageLoader*, bool, bool, ImageLoader::RPathChain const&, unsigned int) ()
#15 0x0000000107138123 in dyld::_main(macho_header const*, unsigned long, int, char const**, char const**, char const**, unsigned long*) ()
#16 0x0000000107133630 in start_sim ()
#17 0x00000001107168cc in dyld::useSimulatorDyld(int, macho_header const*, char const*, int, char const**, char const**, char const**, unsigned long*, unsigned long*) ()
#18 0x0000000110714575 in dyld::_main(macho_header const*, unsigned long, int, char const**, char const**, char const**, unsigned long*) ()
#19 0x000000011070f227 in dyldbootstrap::start(dyld3::MachOLoaded const*, int, char const**, dyld3::MachOLoaded const*, unsigned long*) ()
#20 0x000000011070f025 in _dyld_start ()

dyld 在 C 标准库中有一堆函数的副本(因为它必须在加载标准库之前完成工作。)如果我们在这些 dyld 版本上放置断点,你会在启动期间频繁地命中它们,在大多数情况下这不是您想要的。所以 lldb 保留了一个库列表,在解析按名称断点时要避免,而 dyld 在 Darwin 的列表中。

您可以通过两种方式在这些函数的dyld 版本上强制设置断点。最简单的是在设置断点时提供共享库,例如:

(lldb) break set -n memcmp -s dyld

由于您指定了共享库,我们假设您是认真的,不会参考回避列表。

如果您要经常调试 dyld,您也可以通过执行以下操作完全禁用避免列表:

(lldb) set set target.breakpoints-use-platform-avoid-list 0

您可以在特定会话或 .lldbinit 中执行此操作。