unreal4 奔溃_unreal 如何调用unreal studio - CSDN
  • 这篇博客介绍了在某些情况下,UE4中IsPendingKill()函数中空指针带来的性能消耗分析以及可以采取的优化项。

    这篇博客介绍了在某些情况下,UE4中IndexToObject()函数中空指针带来的性能消耗分析以及可以采取的优化项。

    本博客翻译自Robert Troughton的博客UE4: The Sadness of the Ignored Null Pointer – Coconut Lizard,传送门,翻译工作已征得原作者同意。

    This post is translated from English. You can find the original English language version here: http://coconutlizard.co.uk/blog/ue4/the-ignored-null/


    源代码的问题

    看下面的代码(一如既往的,我注意到这一块的问题是因为IsPendingKill()函数一度在我们项目的性能分析中占了一块比较醒目的位置)…看看你能发现什么可疑的地方吗?

    FORCEINLINE bool IsPendingKill() const
    {
        return GUObjectArray.IndexToObject(InternalIndex)->IsPendingKill();
    }

    然后我们来看一看上面代码中使用到的IndexToObject()函数:

    FORCEINLINE FUObjectItem* IndexToObject(int32 Index)
    {
        check(Index >= 0);
        if (Index < ObjObjects.Num())
        {
            return const_cast<FUObjectItem*>(&ObjObjects[Index]);
        }
        return nullptr;
    }

    看到这里读者应该可以找到问题了。


    代码分析

    没错,如果变量Index太大,则整个函数将返回空指针nullptr。但是函数IsPendingKill并未对空指针进行处理,而是直接调用了FUObjectItem::IsPendingKill()函数,容易引起access violation的问题。可以从对应的汇编代码来进行判断:

    0x1413738e6 movsxd rax, dword ptr [rbx+0xc]
    0x1413738ea cmp eax, dword ptr [rip+0x19c2334]
    0x1413738f0 jnl 0x1413738ff
    0x1413738f2 shl rax, 0x4
    0x1413738f6 add rax, qword ptr [rip+0x19c231b]
    0x1413738fd jmp 0x141373901
    0x1413738ff xor eax, eax
    0x141373901 mov eax, dword ptr [rax+0x8]
    0x141373904 shr eax, 0x1d
    0x141373907 test al, 0x1

    以上的代码大致内容为:

    • 第1~3行处理if (Index < ObjObjects.Num())函数,如果变量Index太大,则跳转到第7行。
    • 第4~5行处理FUobjectItem指针。
    • 第6行的目的是将跳过第7行直达第8行。
    • 第7行将eax设定为0(将一个寄存器对自己进行xor操作相对于直接的赋值操作来说效率更高)。
    • 第8~9行用于获得IsPendingKill函数的值。
    • 第10行进行test。

    综合上面的分析,我们可以得到以下两个猜想中有一个是真的:

    • 要么函数IsPendingKill()函数里有bug… 这个函数本应该检查空指针但是没有。
    • Index变量永远不会太大 - 所以我们或许可以针对这个进行一些优化?

    处理方法

    到目前为止(2016/07/15)来说,这一段代码已经超过15个月没有进行修改了,而且就我来说也没看到过因为这段代码而引起的崩溃。因此我便假设上面的第二个猜想是真的。而且我认为就算我们针对于这个做了改动,应该也不会比以前更差(如果变量Index真的太大的话按照以前的逻辑可是会引起崩溃的)。

    在我们进行处理的时候,我找到了以下的代码,它的功能和IndexToObject()类似:

    FORCEINLINE FUObjectItem* IndexToObjectUnsafeForGC(int32 Index)
    {
        return const_cast<FUObjectItem*>(&ObjObjects[Index]);
    }

    这个函数正是我们想要的,它把变量Index的测试逻辑删掉了,因此我们可以直接将IsPendingKill()函数替换为这个:

    FORCEINLINE bool IsPendingKill() const
    {
        return GUObjectArray.IndexToObjectUnsafeForGC(InternalIndex)->IsPendingKill();
    }

    同样的,我们也可以在其他的几个函数中做同样的处理…这些函数都在Engine\Source\Runtime\CoreUObject\Public\UObject\UObjectBaseUtility.h路径中:

        FORCEINLINE void MarkPendingKill()
        {
          check(!IsRooted());
          GUObjectArray.IndexToObjectUnsafeForGC(InternalIndex)->SetPendingKill();
        }
        FORCEINLINE void ClearPendingKill()
        {
          GUObjectArray.IndexToObjectUnsafeForGC(InternalIndex)->ClearPendingKill();
        }
        FORCEINLINE void AddToRoot()
        {
          GUObjectArray.IndexToObjectUnsafeForGC(InternalIndex)->SetRootSet();
        }
        FORCEINLINE void RemoveFromRoot()
        {
          GUObjectArray.IndexToObjectUnsafeForGC(InternalIndex)->ClearRootSet();
        }
        FORCEINLINE bool IsRooted()
        {
          return GUObjectArray.IndexToObjectUnsafeForGC(InternalIndex)->IsRootSet();
        }
        FORCEINLINE bool ThisThreadAtomicallyClearedRFUnreachable()
        {
          return GUObjectArray.IndexToObjectUnsafeForGC(InternalIndex)->ThisThreadAtomicallyClearedRFUnreachable();
        }
        FORCEINLINE bool IsUnreachable() const
        {
          return GUObjectArray.IndexToObjectUnsafeForGC(InternalIndex)->IsUnreachable();
        }
        FORCEINLINE bool IsPendingKillOrUnreachable() const
        {
          return GUObjectArray.IndexToObjectUnsafeForGC(InternalIndex)->HasAnyFlags(EInternalObjectFlags::PendingKill | EInternalObjectFlags::Unreachable);
        }
        FORCEINLINE bool IsNative() const
        {
          return GUObjectArray.IndexToObjectUnsafeForGC(InternalIndex)->HasAnyFlags(EInternalObjectFlags::Native);
        }
        FORCEINLINE void SetInternalFlags(EInternalObjectFlags FlagsToSet) const
        {
          GUObjectArray.IndexToObjectUnsafeForGC(InternalIndex)->SetFlags(FlagsToSet);
        }
        FORCEINLINE EInternalObjectFlags GetInternalFlags() const
        {
          return GUObjectArray.IndexToObjectUnsafeForGC(InternalIndex)->GetFlags();
        }
        FORCEINLINE bool HasAnyInternalFlags(EInternalObjectFlags FlagsToCheck) const
        {
          return GUObjectArray.IndexToObjectUnsafeForGC(InternalIndex)->HasAnyFlags(FlagsToCheck);
        }
        FORCEINLINE void ClearInternalFlags(EInternalObjectFlags FlagsToClear) const
        {
          GUObjectArray.IndexToObjectUnsafeForGC(InternalIndex)->ClearFlags(FlagsToClear);
        }
        FORCEINLINE bool AtomicallyClearInternalFlags(EInternalObjectFlags FlagsToClear) const
        {
          return GUObjectArray.IndexToObjectUnsafeForGC(InternalIndex)->ThisThreadAtomicallyClearedFlag(FlagsToClear);
        }

    好吧抱歉,貌似代码太多了……

    此外,在Engine\Source\Runtime\CoreUObject\Private\UObject\UObjectBase.cpp中,还有两处可以进行修改的。第一处在UObjectBase::DeferredRegister()函数后面:

    check(!GUObjectArray.IsDisregardForGC(this) || GUObjectArray.IndexToObjectUnsafeForGC(InternalIndex)->IsRootSet());

    还有就是在UObjectBase::AddObject()函数中:

    if (InternalFlagsToSet != EInternalObjectFlags::None)
    {
        GUObjectArray.IndexToObjectUnsafeForGC(InternalIndex)->SetFlags(InternalFlagsToSet);
    }  

    这些大概就是全部了,最终的汇编代码如下:

    00007FF6A79A28F6  movsxd      rax,dword ptr [rbp+0Ch]  
    00007FF6A79A28FA  mov         rdx,qword ptr [GUObjectArray+10h (07FF6A9684288h)]  
    00007FF6A79A2901  add         rax,rax  
    00007FF6A79A2904  mov         ecx,dword ptr [rdx+rax*8+8]  
    00007FF6A79A2908  shr         ecx,1Dh  
    00007FF6A79A290B  test        cl,1  

    我们将其降到了6行汇编代码,而且去掉了分支判断。这无疑是一个很大的改进(译者按:IsPendingKill函数在游戏中会被很频繁的调用,因此这个改进很可能比起读者直观的感受更大)。


    后记

    正如我上面所说的,我并不百分百确定这个改动是“正确的”。如果能够从Epic那里得到一些官方的回复就更好了。但是如果这个改动真的会导致bug,那么应该也是之前的代码的问题……不过这种可能也不大,因为到现在为止也没出现过这段代码所导致的bug。

    但是如论如何,这次处理过后我们能看到在IsPendingKill函数的性能有了很大的提升,当然也包括了其他的函数……这非常酷,不是吗?

    <全文完>

    展开全文
  • unreal引擎编译c++代码的时候,如果代码中有错误,引擎非常容易崩溃崩溃后,经常无法再次成功打开。这时候需要以下操作才可以重新打开: 1.将vs中的错误代码注释掉。 2.打开项目文件夹的目录,将vs、binary、...

    unreal引擎编译c++代码的时候,如果代码中有错误,引擎非常容易崩溃,崩溃后,经常无法再次成功打开。这时候需要以下操作才可以重新打开:
    1.将vs中的错误代码注释掉。
    2.打开项目文件夹的目录,将vs、binary、intermediate、saved删掉。
    3.在目录下找到.uproject右键重新生成。

    展开全文
  • 1.在Epic中下载UnrealEngine4之后 1-1. 首先:启动-选项 1-2. 接着 :(勾选)输入调试用符号-应用 以后出现新的崩溃问题,方便查看详细原因 2.进行UE4相关的文件配置 2-1. 删除C盘中的缓存及修改UE4缓存地址问...

    日志:

    1.第一次记录:2020.2.05 版本:4.24.2
    

    UnrealEngine的初始设置

    1.在Epic中下载UnrealEngine4之后

    1-1. 首先:启动-选项

    在这里插入图片描述

    1-2. 接着 :(勾选)输入调试用符号-应用

    在这里插入图片描述
    以后出现新的崩溃问题,方便查看详细原因

    2.进行UE4相关的文件配置

    2-1. 删除C盘中的缓存及修改UE4缓存地址问项目地址

    参照内容来源于CSDN博客文章:https://blog.csdn.net/cc13813194235/article/details/53424866
    同时本人以 UE4_4.24.2版本 亲测有效

    1.首先随便创建一个游戏项目,选择自己的项目目录

    2.创建完成后关闭UE4

    找到UE4的项目缓存目录
    C:\Users\用户名\AppData\Local\UnrealEngine\Common\DerivedDataCache
    删除DerivedDataCache
    

    3.找到安装UE4的目录
    在这里插入图片描述
    4.在 UE_4.24/Engine/Config 中找到 BaseEngine.ini 文件,直接用记事本打开

    5.编辑——查找——在查找框中输入 [InstalledDerivedDataBackendGraph]
    在这里插入图片描述

    6.将 [InstalledDerivedDataBackendGraph] 下面的内容进行修改

    1 Local=(Type=FileSystem, ReadOnly=false,Clean=false, Flush=false, PurgeTransient=true, DeleteUnused=true,UnusedFileAge=34, FoldersToClean=-1, Path="%ENGINEVERSIONAGNOSTICUSERDIR%DerivedDataCache")
    
    修改为:
    1 Local=(Type=FileSystem, ReadOnly=false,Clean=false, Flush=false, PurgeTransient=true, DeleteUnused=true,UnusedFileAge=34, FoldersToClean=-1,Path="%GAMEDIR%DerivedDataCache")
    

    在这里插入图片描述
    7.修改后进行验证是否修改成功
    1.在BaseEngine.ini 文件中,在查找框中输入 [DerivedDataBackendGraph]
    在这里插入图片描述
    2.找到图中选中的文本,即修改成功,项目缓存路径以及改到项目文件夹内
    在这里插入图片描述

    2-2. 删除联机构建SwarmAgent程序的缓存

    缓存目录:C:\Users\用户名\AppData\Local\UnrealEngine\4.24\Saved\Swarm\SwarmCache
    删除 SwarmCache

    3. UE4的相关设置

    3-1. 设置UE4启动时不编译蓝图

    参照内容来源于知乎文章:https://zhuanlan.zhihu.com/p/104097525

    1.找到配置文件路径:C:\Users\用户名\AppData\Local\UnrealEngine\4.24\Saved\Config\Windows\Engine.ini

    2.打开Engine.ini文件

    3.文本内容中添加

    [/Script/Engine.Blueprint]
    bRecompileOnLoad=False
    
    [/Script/Engine.LevelScriptBlueprint]
    bRecompileOnLoad=False
    
    [/Script/Engine.AnimBlueprint]
    bRecompileOnLoad=False
    

    4.保存,重启

    3-2. 设置仅编译成功时保存

    1.在随便打开一个蓝图,在编译的旁边有个倒三角,如图
    在这里插入图片描述

    3-3. 显示编辑器实时信息

    1.编辑-编辑器偏好设置-通用-性能-勾选显示帧率和实时信息
    在这里插入图片描述

    崩溃日志

    UE4崩溃日志(1)

    参照内容来源于虚幻4官方文档:https://docs.unrealengine.com/zh-CN/GettingStarted/RecommendedSpecifications/index.html
    里面有虚幻4的硬件配置要求,配套软件版本的需求,以及显卡驱动的需求

    因显卡驱动程序原因导致崩溃
    关键字:D3D11RHI、Rendering、Building
    D3D11 为Direct3D11(渲染管线),RHI 为Render hardware interface 渲染硬件层接口,d3d11.dll 为动态链接库Dynamic Link Library
    

    如图所示:
    在这里插入图片描述
    解决方法:

    1.首先进入 NVIDIA GeForce Experience
    在这里插入图片描述

    2.检查更新文件(旁边的三个点)-选择首选项-Studio驱动程序-检查更新文件(如图)
    在这里插入图片描述
    3.检查到更新文件后,下载最新的驱动,自定义安装,勾选恢复默认设置

    4.重启电脑(最好重启一下)

    UE4崩溃日志(2)

    参考内容来源于知乎文章:https://zhuanlan.zhihu.com/p/45508890
    该知乎作者写了很多UE4的Bug以及部分崩溃解决方案

    虚幻4官方文档内容参考:https://docs.unrealengine.com/zh-CN/Engine/Rendering/Nvidia/NVIDIAAftermath/index.html

    因NVIDIA Aftermath 崩溃
    关键字:Aftermath、D3D11Query.cpp] [Line: 111] 、GPU has crashed
    Aftermath 是一个轻量化的实用工具,可减轻部分调试工具对性能历史记录的要求。实际上,它相当轻量化,甚至可以包含在发布的游戏中,提供开发者需要的用户电脑数据。程序员可利用 Aftermath 在代码中插入标记,帮助追踪崩溃发生的根源。
    

    解决方法:
    1.找到 ConsoleVariables.ini ,路径:安装的磁盘:UE_4.24\Engine\Config\ConsoleVariables.ini
    2.找到 [Startup]
    3.在该区域文本内容下添加
    r.DX11NVAfterMathEnabled=0
    r.GPUCrashDebugging=0
    如图:
    在这里插入图片描述
    4.保存,重启UE4

    展开全文
  • UNREAL4 打开到90%左右突然闪退解决方法 将输入法切换至英文在打开UE4.

    UNREAL4 打开到90%左右突然闪退解决方法

    将输入法切换至英文在打开UE4.

    展开全文
  • UE4 本地崩溃日志调试

    千次阅读 2019-03-01 17:50:57
    UE4打出来的包如果崩溃会在本地生成一个dump文件,具体路径在: C:\Users\用户名\AppData\Local\程序名\Saved\Logs(需要显示隐藏文件) 1.找到对应时间点崩溃的文件夹下的.dump文件,拖入vs,其他的如notepad打开...
  • 虚幻4崩溃问题解决方案

    万次阅读 2017-09-19 11:09:48
    虚幻4崩溃问题解决方案一般情况下遇到C++项目编译的时候会崩溃,可采取以下方法解决 方法一 1、找到项目目录 2、删除多余文件,只留下Config、Content、(Debug)、Source、.uproject
  • 按照Airsim 的document里的方法,装好了UE4和airsim,在./UE4Editor 的时候,提示我没有OpenGL 4.3,让我加-opengl3来运行unreal。 我加了这个指令之后,能弹出加载框从0%加载到100%之后,就闪退自动关闭,看...
  • SteamVR+Unreal4 VR开发心得(一)

    千次阅读 2016-06-23 00:29:16
    最近开始使用SteamVR(HTC Vive)+Unreal4做VR开发,平时没事的时候就把开发过程中一些心得写一下。 现在国内这两个开发方向的资料真心不多,自己想查些什么也是国外各种找博客论坛视频看文档,什么语言的都有,感觉很...
  • 网上有不少虚幻4崩溃解决方法都是直接删除很多文件夹,只留几个。 比如: 这种方式,在他们的版本里面,应该可信。可是到4.25版本,这样子删除,会有两种情况,第一种情况,.uproject 无法打开。 第二种情况,.sln...
  • Unreal Engine 4(UE4)是由游戏开发者为游戏开发者提供的完整的游戏开发工具套件。包含80多种实用秘诀,是一本使用C++脚本技术开发UE4游戏的指导书。我们会从在虚幻编辑器中添加和编辑C++类开始。然后,我们会深入...
  • UE4 崩溃记录(随时更新)

    千次阅读 2018-11-22 11:44:23
    1.float值的异常。 原因:此异常值为除0的后果,可以用FMath::IsNaN()来判断。另外,还有FMath::IsFinite()是判断是否无穷,如:当出现2.12345678987此类小数点过多的情况时会判断时无穷。...
  • Unreal Engine4 蓝图讲解

    2019-07-24 20:12:07
    UE4开发群:344602753 Unread Engine4的界面概况: UE4的效果可以说是比较好的,从整体架构上来说,和Unity...
  • unreal官网 右上角获取虚幻引擎 安装全程不需要翻墙安装完这个样子: 点击unreal engine页 下载引擎的最新版本,全程也不需要翻墙. 安装完就可以启动啦! unreal开发 分蓝图和c++代码两种形式.蓝图就是可以不用...
  • UnrealEngine4清除临时文件

    千次阅读 2016-11-04 23:38:33
    打不开ue4工程时或者运行UEEditor崩溃,删除临时文件,只需保留以下文件夹 Conifg, Content & Source 以及 .uproject
  • Unreal Engine 4 控制台命令参数合集

    千次阅读 2016-10-21 10:21:03
    在UE中, 按下~键可以调用到许多有用的指令, 调试场景时能透过此功能深入测试 : Exec的命令是基于字符串的命令,您可以在游戏或编辑器中运行。他们也被称为控制台命令 ,因为它们通常在一个控制台窗口中运行。...
  • UnrealEngine/Engine/Binaries/Linux/UE4Editor&gt;加载之后如下图所示。然后选择我们需要创建工程的文件放在哪里 如果打开UE失败,可以执行./UE4Editor -opengl3 35%的时候会卡住,也不报错误,这个很麻烦,...
  • Unreal Engine 4 C Component介绍WidgetComponent WidgetComponent简介 添加UMG依赖 UMG控件蓝图 UUserWidget的UMG控件 SWidget的Slate控件 扩展WidgetComponent Unreal Engine 4 C++ Component介绍——...
  • UE4文件夹里面包含了许多有用的资源,我们首先去了解这些文件结构,以便日后需要用到的时候随时地查找我们所需要的东西。 打开UE4所安装的目录,你会看到我们下载好的4.10版本的文件夹。 1) DirectXRedist是...
  • 从零开始入门C++:初步认识输入输出样例头文件预定义IO对象输入与输出运算符操纵符endl一个编程技巧:如何重复cin不定量的数据文件重定向 样例 #include <iostream> using namespace std;...
  • https://medium.com/@lordned/unreal-engine-4-rendering-part-5-shader-permutations-2b975e503dd4 翻译:yarswang 转载请保留   如前所述,Unreal将编译给定着色器/材质的多个排列以应对不同的用例。 修改材质...
1 2 3 4 5 ... 20
收藏数 648
精华内容 259
关键字:

unreal4 奔溃