在 macOS 11 (dynamic_cast) 上运行时,在 macOS 13.6 (clang 15) 上运行应用程序会崩溃

问题描述 投票:0回答:1

当我在构建服务器上将 xcode 升级到 15 时出现问题。

链接二进制文件的应用程序“不久前”构建(tm) - 现在在 macOS11 或更早版本上运行时会崩溃。相同的二进制文件在 macos12/13/14 上运行良好。

罪魁祸首是任何dynamic_cast,下面显示了一个简化的示例(具有相同错误的最小单文件应用程序):

操作系统目标是:10.14 c++ 方言是:C++11(-std=c++11 ...与我链接的旧库相同)

#import "AppDelegate.h"

#import <osg/AnimationPath>
#import <osg/ref_ptr>

/*
 Define some subclass of osg::AnimationPath, so we have something to downcast to
 */
class PanZoomAnimationPath : public osg::AnimationPath {
public:
    PanZoomAnimationPath() {
        setLoopMode(osg::AnimationPath::NO_LOOPING);
    }
};


@interface AppDelegate () {
    osg::ref_ptr<osg::AnimationPath>  _animationPath;
}

@property (strong) IBOutlet NSWindow *window;

@end

@implementation AppDelegate

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
    // Try to do some dynamic cast
    
//    auto createdPath = new osg::AnimationPath();
    auto createdPath = new PanZoomAnimationPath();
    
    // shove into a ref_ptr that is on the class
    _animationPath = createdPath;

    NSLog(@"Ptr to path: %p", createdPath);
    NSLog(@"Ptr from _animationPath: %p", _animationPath.get());
    NSLog(@"Animation path ptr is: %p. Is it valid: %d", _animationPath.get(), _animationPath.valid());
    
    // try to dynamic cast. BOOM (at least, on macOS 11)
    PanZoomAnimationPath *pStudioPath = dynamic_cast<PanZoomAnimationPath * >(_animationPath.get());
    if(pStudioPath) {
        NSLog(@"Success!");
    } else {
        NSLog(@"createdPath is not of type PanZoomAnimationPath");
    }
}

@end

在 macOS13/14 上运行时,它可以工作并产生正确的输出,正确向下转换,并且根据指针是否为 NULL。

在 macOS11 上如果失败(段错误 11)

这是堆栈跟踪:

Path:                  /Users/USER/TestOld.app/Contents/MacOS/TestOld
Identifier:            com.shinywhitebox.TestOld
Version:               1.0 (1)
Code Type:             X86-64 (Native)
Parent Process:        bash [62750]
User ID:               504

Date/Time:             2023-09-28 20:50:19.100 +1300
OS Version:            macOS 11.7.8 (20G1351)
Report Version:        12
Anonymous UUID:        86319E29-4169-27B2-C19A-1C7378984637

Sleep/Wake UUID:       D03F977E-2B4B-443D-8EB9-8478E632ECBD

Time Awake Since Boot: 790000 seconds
Time Since Wake:       1500 seconds

System Integrity Protection: enabled

Crashed Thread:        0  Dispatch queue: com.apple.main-thread

Exception Type:        EXC_BAD_ACCESS (SIGSEGV)
Exception Codes:       KERN_INVALID_ADDRESS at 0x0000000007e6b008
Exception Note:        EXC_CORPSE_NOTIFY

Termination Signal:    Segmentation fault: 11
Termination Reason:    Namespace SIGNAL, Code 0xb
Terminating Process:   exc handler [63209]

VM Regions Near 0x7e6b008:
--> 
    __TEXT                      107e6b000-107e73000    [   32K] r-x/r-x SM=COW  /Users/*/TestOld.app/Contents/MacOS/TestOld

Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0   libc++abi.dylib                 0x00007fff20543d16 __dynamic_cast + 393
1   com.shinywhitebox.TestOld       0x0000000107e6ea2f -[AppDelegate applicationDidFinishLaunching:] + 255
2   com.apple.CoreFoundation        0x00007fff2066d463 __CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER__ + 12
3   com.apple.CoreFoundation        0x00007fff20708ed9 ___CFXRegistrationPost_block_invoke + 49
4   com.apple.CoreFoundation        0x00007fff20708e54 _CFXRegistrationPost + 496
5   com.apple.CoreFoundation        0x00007fff2063e6ce _CFXNotificationPost + 736
6   com.apple.Foundation            0x00007fff213b1c18 -[NSNotificationCenter postNotificationName:object:userInfo:] + 59
7   com.apple.AppKit                0x00007fff22e88d80 -[NSApplication _postDidFinishNotification] + 305
8   com.apple.AppKit                0x00007fff22e88ad2 -[NSApplication _sendFinishLaunchingNotification] + 208
9   com.apple.AppKit                0x00007fff22e85c71 -[NSApplication(NSAppleEventHandling) _handleAEOpenEvent:] + 541
10  com.apple.AppKit                0x00007fff22e858c7 -[NSApplication(NSAppleEventHandling) _handleCoreEvent:withReplyEvent:] + 665
11  com.apple.Foundation            0x00007fff213dd366 -[NSAppleEventManager dispatchRawAppleEvent:withRawReply:handlerRefCon:] + 308
12  com.apple.Foundation            0x00007fff213dd1d6 _NSAppleEventManagerGenericHandler + 80
13  com.apple.AE                    0x00007fff2645b853 0x7fff2644f000 + 51283
14  com.apple.AE                    0x00007fff2645af6e 0x7fff2644f000 + 49006
15  com.apple.AE                    0x00007fff26453cd3 aeProcessAppleEvent + 448
16  com.apple.HIToolbox             0x00007fff288d3012 AEProcessAppleEvent + 54
17  com.apple.AppKit                0x00007fff22e7ff70 _DPSNextEvent + 2046
18  com.apple.AppKit                0x00007fff22e7e2a5 -[NSApplication(NSEvent) _nextEventMatchingEventMask:untilDate:inMode:dequeue:] + 1364
19  com.apple.AppKit                0x00007fff22e705c9 -[NSApplication run] + 586
20  com.apple.AppKit                0x00007fff22e447cc NSApplicationMain + 816
21  com.shinywhitebox.TestOld       0x0000000107e6e81f main + 47
22  libdyld.dylib                   0x00007fff2059af3d start + 1

Thread 1:: Dispatch queue: com.apple.CFVolumeObserver.0x7fad90e1fe60

从 macOS 14 运行时,您将获得:

Ptr from _animationPath: 0x60000039a7d0
Animation path ptr is: 0x60000039a7d0. Is it valid: 1
Success!

从 macOS11 开始:

2023-09-28 21:10:10.997 TestOld[63675:8470300] Ptr from _animationPath: 0x7fe879e2c3b0
2023-09-28 21:10:10.997 TestOld[63675:8470300] Animation path ptr is: 0x7fe879e2c3b0. Is it valid: 1
Segmentation fault: 11

我也尝试过重新编译旧的库,但这没有用。它在不同的动态转换上崩溃。

我不是 ABI 相关问题的专家,因此请在这里寻求任何帮助/指示。

c++ xcode macos objective-c++ abi
1个回答
1
投票

这是由于 Xcode 15 中的链接器发生了变化。它记录在发行说明中,但如果您不知道在哪里查找,很容易错过并且不容易找到。您可能会认为,当您的项目包含受影响的符号并针对较旧的 macOS 版本时,他们会添加构建时警告……

无论如何,发行说明还记录了解决方法:

使用弱定义符号的二进制文件在 iOS 14/macOS 12 或更早版本上运行时会崩溃。这主要影响 C++ 项目,因为它们广泛使用弱符号。 (114813650) (FB13097713)

解决方法: 将最低部署目标提高到 iOS 15、macOS 12、watchOS 8 或 tvOS 15,或

-Wl,-ld_classic
添加到
OTHER_LDFLAGS
构建设置。

(强调我的)

© www.soinside.com 2019 - 2024. All rights reserved.