不重复了
重现步骤
Exception Type: EXC_CRASH
Exception Codes: 0x0000000000000000, 0x0000000000000000
Exception signal: SIGABRT
triggered
thread queue 53771 com.apple.main-thread
0 libsystem_kernel.dylib 0x1e690c1dc 0x1e6901000+0xb1dc __pthread_kill+8
1 libsystem_pthread.dylib 0x21fc12c60 0x21fc0b000+0x7c60 pthread_kill+268
2 libsystem_c.dylib 0x19ccc92d0 0x19cc52000+0x772d0 abort+124
3 libsystem_malloc.dylib 0x1a560ad7c 0x1a55f4000+0x16d7c malloc_vreport+892
4 libsystem_malloc.dylib 0x1a560a9f4 0x1a55f4000+0x169f4 malloc_report+64
5 libsystem_malloc.dylib 0x1a56055a0 0x1a55f4000+0x115a0 ___BUG_IN_CLIENT_OF_LIBMALLOC_POINTER_BEING_FREED_WAS_NOT_ALLOCATED+32
6 libc++.1.dylib 0x1a58d4ac4 0x1a58bc000+0x18ac4 std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>::~basic_string()+44
7 UAGame 0x105ef6d70 0x104ab4000+0x1442d70 G6ToolKit::google::protobuf::SimpleDescriptorDatabase::DescriptorIndex<std::__1::pair<void const*, int> >::AddFile(G6ToolKit::google::protobuf::FileDescriptorProto const&, std::__1::pair<void const*, int>) + 332+332
8 UAGame 0x105ef6b74 0x104ab4000+0x1442b74 G6ToolKit::google::protobuf::EncodedDescriptorDatabase::Add(void const*, int) + 108+108
9 UAGame 0x105ead898 0x104ab4000+0x13f9898 G6ToolKit::google::protobuf::DescriptorPool::InternalAddGeneratedFile(void const*, int) + 48+48
10 UAGame 0x105eddd6c 0x104ab4000+0x1429d6c G6ToolKit_protobuf_google_2fprotobuf_2fdescriptor_2eproto::AddDescriptorsImpl() + 28+28
11 UAGame 0x105f2c5dc 0x104ab4000+0x14785dc G6ToolKit::google::protobuf::internal::FunctionClosure0::Run() + 28+28
12 UAGame 0x105f2de04 0x104ab4000+0x1479e04 G6ToolKit::google::protobuf::GoogleOnceInitImpl(long*, G6ToolKit::google::protobuf::Closure*) + 112+112
13 UAGame 0x105fc7f80 0x104ab4000+0x1513f80 G6ToolKit::google::protobuf::GoogleOnceInit(long*, void (*)()) + 64+64
14 UAGame 0x105ef4d88 0x104ab4000+0x1440d88 G6ToolKit_protobuf_google_2fprotobuf_2fdescriptor_2eproto::StaticDescriptorInitializer::StaticDescriptorInitializer() + 20+20
15 dyld 0x1bc5ede58 0x1bc5b8000+0x35e58 invocation function for block in dyld4::Loader::findAndRunAllInitializers(dyld4::RuntimeState&) const+624
16 dyld 0x1bc62ac2c 0x1bc5b8000+0x72c2c invocation function for block in dyld3::MachOAnalyzer::forEachInitializer(Diagnostics&, dyld3::MachOAnalyzer::VMAddrConverter const&, void (unsigned int) block_pointer, void const*) const+172
这是项目接入protobuf然后在iOS 18.5的开发版本出现的闪退,游戏启动不了,回想还有很多类似的a静态库,工作量不少,稳定性也没有保障
请问UE这边有提供比较权威的解决方案吗,华为的系统也有类似的问题,AI的建议是通过
// YourProject.Build.cs if (Target.Platform == UnrealTargetPlatform.IOS) { // 直接添加链接器参数 PublicAdditionalLibraries.Add("-Wl,-alias,_UE4Malloc,_malloc"); PublicAdditionalLibraries.Add("-Wl,-alias,_UE4Free,_free"); }
// MyMemoryBridge.cpp
include “HAL/MemoryBase.h”
extern “C” {
void* UE4Malloc(size_t Size) {
return FMemory::Malloc(Size);
}
void UE4Free(void* Ptr) {
FMemory::Free(Ptr);
}
}
来替换a静态库的连接解决问题,这个应该挺好的,不知道UE这边有提供这种方案吗
PublicAdditionalLibraries 这个我搜了下,好像没有相关API?
Hi,
你好,这是一个已知的问题,你可以先试试这个方案 https://github.com/EpicGames/UnrealEngine/commit/c82c70d4a5dd3f8c447fb3bf123d5ee447a1ea22 ,看看是否有效。
[Image Removed]按照上面的方案,我合入后出现这个报错,找不到Interpose的FrameWork,是还有哪些地方没有处理好吗?
另外这个的原理是啥?
按照方案是不是直接用这段代码放在任何地方就好了?
include <fcntl.h>
typedef int (*p_creat) (const char* path, mode_t mode);
static int replacement_creat(const char* path, mode_t mode)
{
return creat(path, mode);
}
__attribute__((used)) static struct{ p_creat replacement; p_creat replacee; } interpose_creat
__attribute__ ((section (“__DATA,__interpose”))) = { replacement_creat, creat };
不好意思,git的链接里没有包含二进制文件,有些确实,请把下面的目录解压到\Engine\Source\ThirdParty\IOS里
我们还在尝试,不过有个问题
https://developer.apple.com/forums/thread/774805?answerId\=826017022\#826017022
这篇文章里面说
I’ve read the post: An Apple Library Primer, and found: “Dynamic linker interposing is not documented as API. While it’s a useful technique for developer tools, do not use it in products you ship to end users.”, so I guess this tricky way is still not recommended.
In the end, I think the solution is either to raise the deployment target to iOS 17, or totally remove the usage of the std stuff in libc++1.dylib.
说明这个方法是没有办法在发布版本使用的,请问UE这块有办法在发布版本用吗?
尝试了上面的方案,还是会闪退
目前我们找到了其他方法处理了,感谢支持
Hi,
这个workround我们的确没有在Fortnite里使用(可能也没有考虑到是否能在Shipping版使用的问题)。我后续会再跟相关同事确认一下。另外按理说MallocBinned里已经使用FPlatformMemory::PtrIsOSMalloc来判断内存是否直接是来自系统分配的,所以应该能处理这个情况。不过目前看起来没找到其他方案的话,这种设备上只能暂时用Ansi来做内存分配器了。
感谢反馈,不知道是否方便透露一下修复的方式或者思路?
1
mkdir temp_arm64 && cd temp_arm64
ar x ../libtoolkit
cd ..
2
cd temp_arm64
for obj_file in *.o; do
llvm\-objcopy \-\-redefine\-sym \_malloc\=\_UE4Malloc \\
\-\-redefine\-sym \_free\=\_UE4Free \\
\-\-redefine\-sym \_\_Znwm\=\_UE4New \\
\-\-redefine\-sym \_\_ZdlPv\=\_UE4Delete \\
\-\-redefine\-sym \_\_Znam\=\_UE4NewArray \\
\-\-redefine\-sym \_\_ZdaPv\=\_UE4DeleteArray \\
\-\-redefine\-sym \_\_ZnwmRKSt9nothrow\_t\=\_UE4NewNoThrow \\
\-\-redefine\-sym \_\_ZnamRKSt9nothrow\_t\=\_UE4NewArrayNoThrow \\
\-\-redefine\-sym \_\_ZdlPvRKSt9nothrow\_t\=\_UE4DeleteNoThrow \\
\-\-redefine\-sym \_\_ZdaPvRKSt9nothrow\_t\=\_UE4DeleteArrayNoThrow \\
\-\-redefine\-sym \_\_ZdlPvm\=\_UE4DeleteSized \\
\-\-redefine\-sym \_\_ZdaPvm\=\_UE4DeleteArraySized \\
\-\-redefine\-sym \_\_ZdlPvmRKSt9nothrow\_t\=\_UE4DeleteSizedNoThrow \\
\-\-redefine\-sym \_\_ZdaPvmRKSt9nothrow\_t\=\_UE4DeleteArraySizedNoThrow \\
$obj\_file
done
3
cd ..
ar rcs libtoolkit_new temp_arm64/*.o
4
查看结果
nm libtoolkit_new | grep -E “UE4NewArray|UE4DeleteArray”
或者
cd
cd temp_arm64
nm *.o | grep “_UE4Malloc\|_UE4Free”
替换静态库的
OPERATOR_NEW_MSVC_PRAGMA void* operator new ( size_t Size ) OPERATOR_NEW_THROW_SPEC { return FMemory::Malloc( Size ); } \
OPERATOR_NEW_MSVC_PRAGMA void* operator new( size_t Size ) OPERATOR_NEW_THROW_SPEC { return FMemory::Malloc( Size ); } \
OPERATOR_NEW_MSVC_PRAGMA void* operator new ( size_t Size, const std::nothrow_t& ) OPERATOR_NEW_NOTHROW_SPEC { return FMemory::Malloc( Size ); } \
OPERATOR_NEW_MSVC_PRAGMA void* operator new( size_t Size, const std::nothrow_t& ) OPERATOR_NEW_NOTHROW_SPEC { return FMemory::Malloc( Size ); } \
void operator delete ( void* Ptr ) OPERATOR_DELETE_THROW_SPEC { FMemory::Free( Ptr ); } \
void operator delete( void* Ptr ) OPERATOR_DELETE_THROW_SPEC { FMemory::Free( Ptr ); } \
void operator delete ( void* Ptr, const std::nothrow_t& ) OPERATOR_DELETE_NOTHROW_SPEC { FMemory::Free( Ptr ); } \
void operator delete( void* Ptr, const std::nothrow_t& ) OPERATOR_DELETE_NOTHROW_SPEC { FMemory::Free( Ptr ); } \
void operator delete ( void* Ptr, size_t Size ) OPERATOR_DELETE_THROW_SPEC { FMemory::Free( Ptr ); } \
void operator delete( void* Ptr, size_t Size ) OPERATOR_DELETE_THROW_SPEC { FMemory::Free( Ptr ); } \
void operator delete ( void* Ptr, size_t Size, const std::nothrow_t& ) OPERATOR_DELETE_NOTHROW_SPEC { FMemory::Free( Ptr ); } \
void operator delete( void* Ptr, size_t Size, const std::nothrow_t& ) OPERATOR_DELETE_NOTHROW_SPEC { FMemory::Free( Ptr ); }
自己写桥接函数,然后用malloc\free替代
非常感谢。