当我在构建服务器上将xcode升级到15时,出现了一个问题。
在“some time ago”(tm)构建的二进制文件链接的应用程序-现在在macOS 11或更早版本上运行时会崩溃。相同的二进制文件在macOS 12/13/14上运行良好。
罪魁祸首是任何dynamic_cast,下面是一个简化的示例(具有相同故障的最小单个文件应用程序):
OS目标是:10.14 c方言是:C11(-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
字符串
当在macOS 13/14上运行时,它可以工作并产生正确的输出,正确地向下转换,并且根据指针是否为NULL。
在macOS 11上,如果失败(segfault 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!
型
macOS 11:
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
型
我也试过重新编译旧的库,但没有成功。它在不同的dynamic_cast上崩溃。
我不是ABI相关问题的Maven,所以在这里寻求任何帮助/指针。
1条答案
按热度按时间20jt8wwn1#
这是由于Xcode 15中的链接器发生了变化。它在发行说明中有记录,但如果你不知道去哪里找,很容易错过,也不容易找到。你可能会认为当你的项目包含受影响的符号并针对旧的macOS版本时,他们会添加一个构建时警告。
无论如何,发行说明还记录了一个解决方案:
在iOS 14/macOS 12或更早版本上,使用弱定义符号的二进制文件在运行时崩溃。由于C项目广泛使用弱符号,这主要影响C项目。(114813650)(FB 13097713)
解决方法:将最低部署目标提升到iOS 15、macOS 12、watchOS 8或tvOS 15,或者将
-Wl,-ld_classic
添加到OTHER_LDFLAGS
构建设置中。(强调我的)