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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3644465/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 19:42:30  来源:igfitidea点击:

Can I create a breakpoint in code in iOS, like `__asm{int 3}` on VC++, and continue execution after it's been hit?

xcodeiosarm

提问by Richard Groves

I'm trying to put the equivalent of asm{int 3}(or similar) into my iPhone program. My goal is to have Xcode stop exactly on the offending line, without having to fiddle with the call stack (so _Debuggerdoesn't sound like it would do, not that I could find which framework it's in anyway...), and leave me able to resume execution (which is why I'm not happy with assert).

我正在尝试将等价物asm{int 3}(或类似物)放入我的 iPhone 程序中。我的目标是让 Xcode 准确地停在有问题的行上,而不必摆弄调用堆栈(所以_Debugger听起来不像它会做的,不是我无论如何都能找到它所在的框架......),然后离开我能够恢复执行(这就是我不满意的原因assert)。

(I'm used to both these behaviours on other systems, and I'd like to reproduce them on iOS.)

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

My best attempt so far has been this:

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

asm volatile("bkpt 1");

This stops Xcode on the line in question, but when I try to continue with Cmd+Alt+P, Xcode appears to run the BKPTagain. And if I use Shift+Cmd+O, I just get this:

这会在有问题的线路上停止 Xcode,但是当我尝试使用 Cmd+Alt+P 继续时,Xcode 似乎BKPT再次运行。如果我使用 Shift+Cmd+O,我会得到这个:

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

(Needless to say, the remote device IS still connected.)

(不用说,远程设备仍处于连接状态。)

I don't have a huge amount of experience with iOS, Mac, ARM, gdb, or gcc's asmstuff. So I'm stumped already. Is there some way of getting iOS and Xcode to do what I want?

我对 iOS、Mac、ARM、gdb 或 gcc 的asm东西没有丰富的经验。所以我已经难住了。有什么方法可以让 iOS 和 Xcode 做我想做的事吗?

(I don't know if it makes a difference but judging by the instruction size my program is ARM code.)

(我不知道这是否有区别,但从指令大小来看,我的程序是 ARM 代码。)

采纳答案by Logan Capaldo

raise(SIGTRAP)is a relatively portable way to have an "in code" breakpoint.

raise(SIGTRAP)是一种具有“代码中”断点的相对可移植的方式。

回答by Richard Groves

Try:

尝试:

__builtin_trap();

works on Mac as well as iOS, and you can drag the little green cursor to the next line to continue running.

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

回答by Brent Faust

I've tried all of these solutions and although @RichardGroves answer preserved the stack, the best solution is to:

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

  1. create your own assert method, such as Debug::assert(...)
  2. set a breakpoint within XCode on that implementation
  3. use the Step Out command to get back to the caller
  1. 创建自己的断言方法,例如 Debug::assert(...)
  2. 在该实现的 XCode 中设置断点
  3. 使用 Step Out 命令返回呼叫者

This is because it's the only reliable way to both

这是因为这是唯一可靠的方法

  • view the stack trace
  • step / continue
  • 查看堆栈跟踪
  • 步骤/继续

回答by Vivek

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

Above is a poor man's trap in that you have to manually attach to the program in question. Increase the delay as appropriate. Put the code where you want to break, and insert a breakpoint on the sleep statement, build and run your program, and attach to it from Xcode. Once Xcode breaks, you can right-click on the resume variable and edit it to 1, to resume execution.

以上是一个穷人的陷阱,您必须手动附加到有问题的程序。适当增加延迟。把代码放在你想中断的地方,并在 sleep 语句上插入一个断点,构建并运行你的程序,然后从 Xcode 附加到它。一旦 Xcode 中断,您可以右键单击 resume 变量并将其编辑为 1,以恢复执行。

Screenshot

截屏

回答by Pavel P

I tried to find implementation that behaves the same as __debugbreak()that comes with Microsoft compiler and breaks inside my code and not somewhere inside system libraries and allows me to continue execution. This implementation of __debugbreak()works exactly as I wanted:

我试图找到与 Microsoft 编译器附带的__debugbreak()行为相同的实现,并在我的代码内部而不是系统库中的某处中断,并允许我继续执行。__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 ; mov %eax, %eax")
#endif

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

回答by spnkr

To force xcode to break, use

要强制 xcode 中断,请使用

kill(getpid(), SIGSTOP)

You can then step out/up and use lldb per usual. When you're done, you can hit continue and it works just like a breakpoint set from the Xcode GUI.

然后,您可以像往常一样退出/升级并使用 lldb。完成后,您可以点击继续,它就像从 Xcode GUI 设置断点一样工作。

Tested with Swift 5 and Xcode 11.3

使用 Swift 5 和 Xcode 11.3 测试

回答by pxpgraphics

int pthread_kill(pthread_t thread, int sig);allows for continuation, and pauses on the current thread, via pthread_self().

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

Similar to other signal functions (e.g., kill(), raise(), etc.), however,pthread_kill()is used to request that a signal be delivered to a particular thread.

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

Pthread_kill Manual

pthread_kill 手册

回答by Stephan Lechner

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

together with an XCode exception breakpoint of type

连同类型为 XCode 的异常断点

Exception:C++ "named:std::runtime"

例外:C++“命名:标准::运行时”

worked for me (using XCode 8.0).
It yields the same result as if I had set a breakpoint manually at the line where the

对我来说有效(使用 XCode 8.0)。
它产生的结果与我在

std::runtime_error::runtime_error

function is called, i.e. correct thread, correct call stack, and the possibility to resume.

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