对于我的 iPhone 项目中的断言宏,我正在寻找一种以编程方式进入调试器的方法。在 Windows (MSVC++) 上,我可以为此目的使用 __debugbreak()。调用此函数将停止我的程序,启动调试器,并显示调用 __debugbreak() 的行的调用堆栈。
有什么类似于 iPhone 的 __debugbreak() 的吗?我试过 Debugger(),但这给了我一个链接器错误。
谢谢,克劳斯
编辑
事实证明这也有效:
#define Debugger() { raise( SIGINT ) ; }
我认为这是相同的原理。
我用这个:
#define Debugger() { kill( getpid(), SIGINT ) ; }
我认为它可以在模拟器和设备上工作..不需要组装!
Apple 开发者论坛上的一位乐于助人的人给了我在asm("trap")
设备上asm("int3")
运行和在模拟器上运行时使用的提示。如果您以调试模式(Option-Command-Y)启动程序,这会使程序进入调试器。
(__builtin_trap()
也闯入调试器,但之后您无法继续。assert(false)
使用消息终止程序,但不会闯入调试器。)
First Add -DDEBUG
to OTHER_CFLAGS
on your debug target; this will define the DEBUG
symbol when building a debug build.
Then add a simple assert macro to your prefix header:
#ifdef DEBUG
#define MyAssert(val) _MyAssert(val)
#else
#define MyAssert(val) do { } while(0)
#endif
Next create a _MyAssert
function in a module somewhere:
#ifdef DEBUG
void _MyAssert(int expression)
{
if (expression == 0) {
NSLog(@"Assertion failed!"); // Place breakpoint here
}
}
#endif
Finally create a breakpoint on the NSLog
line.
简单的 assert() 宏有问题吗?就像是
assert(pointerToTest != nil);
如果条件不成立,将在此时停止您的进程。如果在调试器下运行,您将看到导致断言失败的调用的堆栈跟踪。如果您想在每次点击某个代码路径时触发它,您可以这样做
assert(false);
我发现当从 NIB 调出窗口或视图时,这些断言对于验证所有 IBOutlets 是否非零非常有用。
我只是在我想停止的地方设置了一个断点。Xcode 会永久记住断点,因此每当我使用 gdb 运行应用程序时,它都会在该点停止。
如果你想在断言失败时中断,一个设置断点的好地方是在 Objective-C 运行时的函数 objc_exception_throw 上,它实际上是抛出异常的地方。使用 Run > Show > Breakpoints 窗口并双击“Double-click for symbol”行,然后输入名称。
如果您在调试中运行程序,您的应用程序应该在遇到无效断言时启动调试器。
正如 Jens Alfke 所说,要让它停止,您需要启用“在 Objective-C 异常时停止”(在“运行”菜单下)。
有关调试与发布和断言的更多信息,请阅读http://myok12.wordpress.com/2010/10/10/to-use-or-not-to-use-assertions/
虽然是一个古老的线程,但在研究 Xcode 7 的同一主题时发现了这一点。为我解决这个问题的是一个名为“创建异常断点...”的功能
调试 > 断点 > 创建异常断点...
这会在 Breakpoint Navigator 中放置一个特殊断点(在 View > Navigator > Show Breakpoint Navigator 下)。
这打破了异常的实际抛出:
[ exception raise ]
无需终止您的代码执行。如果这是您的代码结构,您可以继续。
双击“All Exception”旁边的断点标记可让您调整异常断点停止的位置和方式: