我们的Unity3D游戏使用C ++ DLL作为我们框架的一部分,它在Windows中一直很好用。我们最近尝试为Linux构建我们的游戏并遇到了一个非常糟糕的崩溃。
我将问题从Unity3D本身中分离出来 - >它在Windows和Linux之间完全正常,没有我们的C ++库。
我已经将库编译到Ubuntu x64环境中的Linux库。
游戏加载到我们的初始场景中(证明Unity3D没问题),但是当我们加载一个利用库的级别时,我们在使用从Unity3D传递的数据调用其中一个库函数时会在坏内存上出现段错误。
我编译了该库的调试版本并在Linux中的gdb中运行游戏以生成以下调试调用堆栈:
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7ffff7fd3780 (LWP 7347)]
0x00007fffb42d94da in geom::Vector3f::Vector3f (this=0x1adff9a8, other=...)
at /mnt/hgfs/WFTO/war-for-the-overworld/CustomPlugins/GameLogic/GameLogic/Source/lib/geom/Vector3f.h:16
16/mnt/hgfs/WFTO/war-for-the-overworld/CustomPlugins/GameLogic/GameLogic/Source/lib/geom/Vector3f.h: No such file or directory.
(gdb)
Continuing.
Program received signal SIGABRT, Aborted.
0x00007ffff6236425 in raise () from /lib/x86_64-linux-gnu/libc.so.6
(gdb) bt
#0 0x00007ffff6236425 in raise () from /lib/x86_64-linux-gnu/libc.so.6
#1 0x00007ffff6239b8b in abort () from /lib/x86_64-linux-gnu/libc.so.6
#2 0x00007ffff2749f6c in ?? () from /home/ryan/.gvfs/build on strich/Release/Linux/WFTO_Data/Mono/x86_64/libmono.so
#3 0x00007ffff27876e9 in ?? () from /home/ryan/.gvfs/build on strich/Release/Linux/WFTO_Data/Mono/x86_64/libmono.so
#4 <signal handler called>
#5 0x00007fffb42d94da in geom::Vector3f::Vector3f (this=0x1adff9a8, other=...)
at /mnt/hgfs/WFTO/war-for-the-overworld/CustomPlugins/GameLogic/GameLogic/Source/lib/geom/Vector3f.h:16
#6 0x00007fffb42db207 in data::LocatedObject::LocatedObject (this=0x1adff920, id=48, clientObject=0x23,
ownerPlayerNumber=0, location=...)
at /mnt/hgfs/WFTO/war-for-the-overworld/CustomPlugins/GameLogic/GameLogic/Source/components/data/abstract/LocatedObject.h:23
#7 0x00007fffb42db75e in data::PhysicalObject::PhysicalObject (this=0x1adff920, id=48, clientObject=0x23,
ownerPlayerNumber=0, location=..., bounds=..., orientation=..., collisionType=data::COLLISION_FULL_SOLID)
at /mnt/hgfs/WFTO/war-for-the-overworld/CustomPlugins/GameLogic/GameLogic/Source/components/data/abstract/PhysicalObject.h:40
#8 0x00007fffb42e443c in data::PropData::PropData (this=0x1adff920, id=48, clientObject=0x23, ownerPlayerNumber=0,
location=..., bounds=..., orientation=...)
at /mnt/hgfs/WFTO/war-for-the-overworld/CustomPlugins/GameLogic/GameLogic/Source/components/data/prop/PropData.h:18
#9 0x00007fffb42b6e0d in data_PropData_new (id=48, clientObject=0x23, ownerPlayerNumber=0,
location=<error reading variable: Cannot access memory at address 0x4208cccd429acccd>,
bounds=<error reading variable: Cannot access memory at address 0x3f666666>,
orientation=<error reading variable: Cannot access memory at address 0x1cb3>)
at /mnt/hgfs/WFTO/war-for-the-overworld/CustomPlugins/GameLogic/GameLogic/Source/components/data/prop/PropData_export.h:32
基于上述原因,其根本原因非常清楚。当调用 data_PropData_new 时,我们的库正在获取传递给函数的一些参数的错误内存指针。这是C ++函数头:
extern "C" {
DLL_EXPORT PropData* data_PropData_new(
long long id, ManagedReference clientObject, int ownerPlayerNumber,
geom::Vector3f location, geom::Vector3f bounds, geom::Vector3f orientation)
C#DllImport:
[DllImport("GameLogic", EntryPoint = "data_PropData_new", CallingConvention = CallingConvention.Cdecl)]
internal static extern NativePropData create(
long id, IntPtr clientObject, int ownerPlayerNumber,
Vector3f location, Vector3f bounds, Vector3f orientation);
首先要注意的是,所有类型为 geom :: Vector3f 的参数都有不良记忆。好的,这是一个很好的领导。下面是C ++和C#的 Vector3f 代码:
Vector3f.h (Quite large so I PasteBin'd it).
Vector3f.cs (Quite large so I PasteBin'd it).
重要的是要注意这个库在Windows中运行得非常好。但不是Linux。可能是因为在Linux下没有将Vector3f数据正确地固定在内存中吗?我有一种预感,即Vector3f上存在一些Mono InteropServices平台特定的编组问题,但我很难弄清楚原因和地点。