【问题标题】:Why does this code crash when compiled with Apple LLVM, but not in LLVM/GCC?为什么这段代码在使用 Apple LLVM 编译时会崩溃,而不是在 LLVM/GCC 中?
【发布时间】:2012-11-22 05:39:29
【问题描述】:

我正在尝试获取此代码:http://code.google.com/p/switchcontrol/source/browse/trunk/code/AFSwitchControl.m 在 Xcode 4.5.2 中的 Apple LLVM 下编译。它在使用 LLVM/GCC 编译时可以工作,但在第 198 行切换到 Apple LLVM 时会在 mouseDown 方法中崩溃:

NSRect knobRect = _AFSwitchControlKnobRectForInsetBackground(slotRect, _offset);

因为_offset 没有设置。假设在 bind 方法中设置了这一行:

[self setOffset:(CGFloat)[self state]];

但由于某种原因,LLVM 下似乎没有设置任何内容。我的绑定调用如下所示:

[control bind:NSValueBinding toObject:self withKeyPath:@"isToggleSwitchOn" options:nil];

任何想法为什么控件的状态在 LLVM 下没有返回任何内容?谢谢!

【问题讨论】:

    标签: objective-c xcode cocoa llvm llvm-gcc


    【解决方案1】:

    问题其实出在上面几行,在对_AFSwitchControlPartRects的调用中。

    - (void)mouseDown:(NSEvent *)event {
        NSRect textRect, backgroundRect;
        _AFSwitchControlPartRects([self bounds], &textRect, &backgroundRect);
    
        NSRect slotRect = _AFSwitchControlInsetBackgroundRect(backgroundRect);
        NSRect knobRect = _AFSwitchControlKnobRectForInsetBackground(slotRect, _offset);
    

    _AFSwitchControlPartRects 的第二个参数,&textRect 是一个指向矩形的指针。

    但是在函数的实现中,该参数应该是一个指针,指向足够空间用于两个矩形。

    NS_INLINE void _AFSwitchControlPartRects(NSRect bounds, NSRect *textRects, NSRect *backgroundRect) {
        NSDivideRect(bounds, textRects, backgroundRect, NSWidth(bounds)/5.0, NSMinXEdge);
    
        textRects[1] = _AFSwitchControlInsetTextRect(NSOffsetRect(textRects[0], NSWidth(*backgroundRect), 0));
        textRects[0] = _AFSwitchControlInsetTextRect(textRects[0]);
    

    当它写入 textRects[1] 时,它会在 -mouseDown 的堆栈上涂鸦。缓冲区溢出。

    在我看来它正在发生在破坏 self 上,所以下一次对 self 的取消引用将会死掉。这恰好是_offset的使用。

    【讨论】:

    • 谢谢!我将其更改为 NSRect textRect[2] 并改为调用 _AFSwitchControlPartRects([self bounds], textRect, &backgroundRect)。
    猜你喜欢
    • 2011-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-08
    • 2012-12-14
    • 1970-01-01
    • 2016-01-13
    相关资源
    最近更新 更多