我可以在iOS中的代码中创建一个断点,比如VC ++上的`__asm {int 3}`,并在命中之后继续执行吗?

时间:2010-09-04 23:57:57

标签: xcode ios arm

我正在尝试将等效的asm{int 3}(或类似)放入我的iPhone程序中。我的目标是让Xcode完全停在有问题的线上,而不必调整调用堆栈(所以_Debugger听起来不像它那样,不是说我无论如何都能找到它的框架...... ),让我能够恢复执行(这就是为什么我对assert不满意。)

(我已经习惯了其他系统上的这些行为,我想在iOS上重现它们。)

到目前为止,我最好的尝试是:

asm volatile("bkpt 1");

这会阻止相关行上的Xcode,但是当我尝试继续使用Cmd + Alt + P时,Xcode似乎再次运行BKPT。如果我使用Shift + Cmd + O,我就得到这个:

Watchdog has expired.  Remote device was disconnected?  Debugging session terminated.

(不用说,远程设备IS仍然连接。)

我对iOS,Mac,ARM,gdb或gcc的asm内容没有太多经验。所以我已经难过了。有没有办法让iOS和Xcode做我想做的事情?

(我不知道它是否有所不同,但根据指令大小判断我的程序是ARM代码。)

9 个答案:

答案 0 :(得分:17)

尝试:

__builtin_trap();

适用于Mac和iOS,您可以将绿色小光标拖到下一行继续运行。

答案 1 :(得分:5)

raise(SIGTRAP)是一种相对便携的方式来获得“in code”断点。

答案 2 :(得分:4)

我已尝试过所有这些解决方案,虽然@RichardGroves的答案保留了堆栈,但最佳解决方案是:

  1. 创建自己的断言方法,例如Debug::assert(...)
  2. 在XCode中为该实现设置断点
  3. 使用Step Out命令返回调用者
  4. 这是因为它是唯一可靠的方式

    • 查看堆栈跟踪
    • 步骤/继续

答案 3 :(得分:1)

int resume = false;
for (int i = 0; i < 20 && !resume; ++i)
    sleep(1);

上面是一个穷人的陷阱,你必须手动附加到相关程序。适当增加延迟。将代码放在要中断的位置,并在sleep语句中插入断点,构建并运行程序,并从Xcode附加到它。一旦Xcode中断,您可以右键单击resume变量并将其编辑为1,以便继续执行。

Screenshot

答案 4 :(得分:1)

我试图找到与Microsoft编译器一样的__debugbreak()行为的实现,并在我的代码内部而不是在系统库中的某个地方中断,并允许我继续执行。这个implementation of __debugbreak()完全符合我的要求:

#if defined(__APPLE__) && defined(__aarch64__)
#define __debugbreak() __asm__ __volatile__(            \
    "   mov    x0, %x0;    \n" /* pid                */ \
    "   mov    x1, #0x11;  \n" /* SIGSTOP            */ \
    "   mov    x16, #0x25; \n" /* syscall 37 = kill  */ \
    "   svc    #0x80       \n" /* software interrupt */ \
    "   mov    x0, x0      \n" /* nop                */ \
    ::  "r"(getpid())                                   \
    :   "x0", "x1", "x16", "memory")
#elif defined(__APPLE__) && defined(__arm__)
#define __debugbreak() __asm__ __volatile__(            \
    "   mov    r0, %0;     \n" /* pid                */ \
    "   mov    r1, #0x11;  \n" /* SIGSTOP            */ \
    "   mov    r12, #0x25; \n" /* syscall 37 = kill  */ \
    "   svc    #0x80       \n" /* software interrupt */ \
    "   mov    r0, r0      \n" /* nop                */ \
    ::  "r"(getpid())                                   \
    :   "r0", "r1", "r12", "memory")
#elif defined(__APPLE__) && defined(__i386__)
#define __debugbreak() __asm__ __volatile__("int $3; mov %eax, %eax")
#endif

#define ASSERT(expr) do { if (!(expr)){ __debugbreak(); } } while(0)

答案 5 :(得分:0)

int pthread_kill(pthread_t thread, int sig);允许通过pthread_self()继续并暂停当前线程。

与其他信号函数(例如kill()raise()等)类似,但pthread_kill()用于请求将信号传递到特定线程。

Pthread_kill Manual

答案 6 :(得分:0)

std::runtime_error::runtime_error("breakpoint")

与类型

的XCode异常断点一起使用
  

异常:C ++“named:std :: runtime”

为我工作(使用XCode 8.0) 它产生的结果与我在

的行手动设置断点的结果相同
std::runtime_error::runtime_error
调用

函数,即正确的线程,正确的调用堆栈,以及恢复的可能性。

答案 7 :(得分:0)

要强制xcode破解,请使用

kill(getpid(), SIGSTOP)

然后您可以按常规退出/使用lldb。完成后,您可以单击继续,它的工作方式就像在Xcode GUI中设置的断点一样。

经过Swift 5和Xcode 11.3的测试

答案 8 :(得分:0)

arm / arm64中x86 int3 / int 3的直接等效值为

#if TARGET_CPU_ARM | TARGET_CPU_ARM64 | TARGET_CPU_ARM64E
asm volatile("trap");
#endif