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
Can I create a breakpoint in code in iOS, like `__asm{int 3}` on VC++, and continue execution after it's been hit?
提问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 _Debugger
doesn'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 BKPT
again. 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 asm
stuff. 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 的回答保留了堆栈,但最好的解决方案是:
- create your own assert method, such as
Debug::assert(...)
- set a breakpoint within XCode on that implementation
- use the Step Out command to get back to the caller
- 创建自己的断言方法,例如
Debug::assert(...)
- 在该实现的 XCode 中设置断点
- 使用 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,以恢复执行。
回答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()
用于请求将信号传递给特定线程。
回答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.
函数被调用,即正确的线程,正确的调用堆栈,以及恢复的可能性。