XCode: 以编程方式启用符号断点?
XCode: Programmatically enable a symbolic breakpoint?
有没有办法以编程方式启用断点?通常我会使用断点条件,但我需要使用符号断点。
具体来说,在调用 scrollToIndexPath
和调用 reloadData
之间,某些东西正在改变我的 UIScrollView 的 contentOffset
。我只想在调用 scrollToIndexPath
之后启用符号断点。
您可以使用 __builtin_trap() 来完成此操作。在 x86 系统上,您必须在遇到陷阱后手动调整 pc。但这很容易做到,如果您的代码经常受到攻击并且您只需要在某些复杂的情况下陷入困境,那么这有时很有用。类似于:
> lldb trapit
(lldb) target create "trapit"
Current executable set to 'trapit' (x86_64).
(lldb) run
Process 63363 launched: '/private/tmp/trapit' (x86_64)
About to trap.
Process 63363 stopped
* thread #1: tid = 0x2054b7, function: main , stop reason = EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)
frame #0: 0x0000000100000f4d trapit`main at trapit.c:6
3 int main()
4 {
5 printf ("About to trap.\n");
-> 6 __builtin_trap();
7 printf("Trapped.\n");
8 }
(lldb) dis -f
trapit`main:
0x100000f30 <+0>: pushq %rbp
0x100000f31 <+1>: movq %rsp, %rbp
0x100000f34 <+4>: subq [=10=]x10, %rsp
0x100000f38 <+8>: leaq 0x47(%rip), %rdi ; "About to trap.\n"
0x100000f3f <+15>: movb [=10=]x0, %al
0x100000f41 <+17>: callq 0x100000f66 ; symbol stub for: printf
0x100000f46 <+22>: leaq 0x49(%rip), %rdi ; "Trapped.\n"
-> 0x100000f4d <+29>: ud2
0x100000f4f <+31>: movl %eax, -0x4(%rbp)
0x100000f52 <+34>: movb [=10=]x0, %al
0x100000f54 <+36>: callq 0x100000f66 ; symbol stub for: printf
0x100000f59 <+41>: xorl %ecx, %ecx
0x100000f5b <+43>: movl %eax, -0x8(%rbp)
0x100000f5e <+46>: movl %ecx, %eax
0x100000f60 <+48>: addq [=10=]x10, %rsp
0x100000f64 <+52>: popq %rbp
0x100000f65 <+53>: retq
(lldb) reg write pc 0x100000f4f
(lldb) c
Process 63363 resuming
Trapped.
Process 63363 exited with status = 0 (0x00000000)
Jim Ingham 的回答适用于 x86 系统。对于 iOS 设备,我能够使用 this answer 中描述的方法以编程方式创建断点。插入行
asm("svc 0");
使调试器在 XCode 中的后续指令处停止。
有趣的是,如果您未连接到 XCode,程序会继续正常执行。
有没有办法以编程方式启用断点?通常我会使用断点条件,但我需要使用符号断点。
具体来说,在调用 scrollToIndexPath
和调用 reloadData
之间,某些东西正在改变我的 UIScrollView 的 contentOffset
。我只想在调用 scrollToIndexPath
之后启用符号断点。
您可以使用 __builtin_trap() 来完成此操作。在 x86 系统上,您必须在遇到陷阱后手动调整 pc。但这很容易做到,如果您的代码经常受到攻击并且您只需要在某些复杂的情况下陷入困境,那么这有时很有用。类似于:
> lldb trapit
(lldb) target create "trapit"
Current executable set to 'trapit' (x86_64).
(lldb) run
Process 63363 launched: '/private/tmp/trapit' (x86_64)
About to trap.
Process 63363 stopped
* thread #1: tid = 0x2054b7, function: main , stop reason = EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)
frame #0: 0x0000000100000f4d trapit`main at trapit.c:6
3 int main()
4 {
5 printf ("About to trap.\n");
-> 6 __builtin_trap();
7 printf("Trapped.\n");
8 }
(lldb) dis -f
trapit`main:
0x100000f30 <+0>: pushq %rbp
0x100000f31 <+1>: movq %rsp, %rbp
0x100000f34 <+4>: subq [=10=]x10, %rsp
0x100000f38 <+8>: leaq 0x47(%rip), %rdi ; "About to trap.\n"
0x100000f3f <+15>: movb [=10=]x0, %al
0x100000f41 <+17>: callq 0x100000f66 ; symbol stub for: printf
0x100000f46 <+22>: leaq 0x49(%rip), %rdi ; "Trapped.\n"
-> 0x100000f4d <+29>: ud2
0x100000f4f <+31>: movl %eax, -0x4(%rbp)
0x100000f52 <+34>: movb [=10=]x0, %al
0x100000f54 <+36>: callq 0x100000f66 ; symbol stub for: printf
0x100000f59 <+41>: xorl %ecx, %ecx
0x100000f5b <+43>: movl %eax, -0x8(%rbp)
0x100000f5e <+46>: movl %ecx, %eax
0x100000f60 <+48>: addq [=10=]x10, %rsp
0x100000f64 <+52>: popq %rbp
0x100000f65 <+53>: retq
(lldb) reg write pc 0x100000f4f
(lldb) c
Process 63363 resuming
Trapped.
Process 63363 exited with status = 0 (0x00000000)
Jim Ingham 的回答适用于 x86 系统。对于 iOS 设备,我能够使用 this answer 中描述的方法以编程方式创建断点。插入行
asm("svc 0");
使调试器在 XCode 中的后续指令处停止。
有趣的是,如果您未连接到 XCode,程序会继续正常执行。