A game about forced loneliness, made by TACStudios
at master 145 lines 7.4 kB view raw view rendered
1# Debugging and profiling tools 2 3The following sections describe how to debug and profile your Burst-compiled code in the Editor and in player builds. 4 5>[!TIP] 6>Before attempting to debug Burst-compiled code, enable script debugging for the Editor, or a player build by following the steps in [Debug C# code in Unity](xref:ManagedCodeDebugging). Although you can theoretically debug Burst-compiled code even when the script compilation mode is set to Release, in practice it doesn't work reliably. Breakpoints might be skipped, and variables might not appear in the Locals window, for example. 7 8<a name="debugging-in-editor"></a> 9 10## Debugging Burst-compiled code in the Editor 11 12To debug Burst-compiled code in the Editor, you can either use a managed debugger, or a native debugger. This section explains both options. 13 14### Attach a managed debugger 15 16You can attach a managed debugger such as Visual Studio, Visual Studio for Mac, or JetBrains Rider. This is the same type of debugger you can use to debug regular managed C# code in your Unity project. The ways of attaching a debugger differ depending on the version of Unity you're using: 17 18- **Unity 2022.2+**: When you place a breakpoint inside Burst-compiled code, and you have a managed debugger attached, Unity disables Burst automatically for that code path. This allows you to use a managed debugger to debug the managed version of your code. When you remove all breakpoints from that code path, Unity re-enables Burst for that code path. 19 20- **Unity 2022.1 and older**: Disable Burst, either with the global option in the Editor [Burst menu](editor-burst-menu.md) (**Jobs** &gt; **Burst** &gt; **Enable Compilation**), or comment out the `[BurstCompile]` attribute from the specific entry-point that you want to debug. 21 22### Attach a native debugger 23 24You can attach a native debugger such as Visual Studio or Xcode. Before doing so, you need to disable Burst optimizations. You can do this in the following ways: 25 26- Use the **Native Debug Mode Compilation** setting in the Editor [Burst menu](editor-burst-menu.md) (**Jobs** &gt; **Burst** &gt; **Native Debug Mode Compilation**). **Important:** This setting disables optimizations across all jobs, which impacts the performance of Burst code. If you want to disable optimizations only for a specific job, use the other option in this list. 27 28- Add the `Debug = true` flag to your job, which disables optimizations and enables debugging on that specific job: 29 30 ```c# 31 [BurstCompile(Debug = true)] 32 public struct MyJob : IJob 33 { 34 // ... 35 } 36 ``` 37 38 >[!TIP] 39 >Player builds pick up the `Debug` flag, so you can also use this to debug a player build. 40 41To attach a native debugger to the Unity Editor process, see the [native debugging](#native-debugging) section below. 42 43<a name="debugging-in-player"></a> 44 45## Debugging Burst-compiled code in a player build 46 47Because of the way that Unity builds the code for a player, you need to tell the debugging tool where to find the symbols. To do this, point the tool to the folder that contains the `lib_burst_generated` files, which is usually in the `Plugins` folder. 48 49To debug Burst-compiled code in a player build, you need to attach a native debugger (such as Visual Studio or Xcode) to the player process. Before doing so, you need to: 50 51- Enable symbol generation. You can do this in either of two ways: 52 53 - Enable the **Development Build** option before you build the player, or 54 55 - Enable the **Force Debug Information** option in [Burst AOT Player Settings](building-aot-settings.md) 56 57- Disable Burst optimizations. You can do this in either of two ways: 58 59 - Disable the **Enable Optimizations** option in [Burst AOT Player Settings](building-aot-settings.md). **Important:** This setting disables optimizations across all jobs, which impacts the performance of Burst code. If you want to disable optimizations only for a specific job, use the other option in this list. 60 61 - Add the `Debug = true` flag to your job, which disables optimizations and enables debugging on that specific job: 62 63 ```c# 64 [BurstCompile(Debug = true)] 65 public struct MyJob : IJob 66 { 67 // ... 68 } 69 ``` 70 71To attach a native debugger to the player process, see the [native debugging](#native-debugging) section below. 72 73<a name="native-debugging"></a> 74 75## Native debugging 76 77Follow the instructions above to setup native debugging correctly for the [Editor](#debugging-in-editor) or a [player build](#debugging-in-player). Then, attach a native debugger such as Visual Studio or Xcode. 78 79### Native debugging limitations 80 81* Native debuggers can't discover lambda captures on `Entity.ForEach`, so you can't inspect variables originating from these. 82* Structs that use [`[StructLayout(LayoutKind=Explicit)]`](https://docs.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.layoutkind?view=net-6.0) and have overlapping fields are represented by a struct that hides one of the overlaps. 83 84Types that are nested, are namespaced in C/C++ style. e.g. 85 86```c# 87namespace Pillow 88{ 89 public struct Spot 90 { 91 public struct SubSpot 92 { 93 public int a; 94 public int b; 95 } 96 public int a; 97 public int b; 98 public SubSpot sub; 99 } 100``` 101 102You would refer to SubSpot as Pillow::Spot::SubSpot in this case (for instance if you were trying to cast a pointer in a debugger watch window). 103 104### Code-based breakpoints 105 106Burst supports code-based breakpoints through the [`System.Diagnostics.Debugger.Break`](https://docs.microsoft.com/en-us/dotnet/api/system.diagnostics.debugger.break?view=net-6.0) method. This method generates a debug trap in your code. You must attach a debugger to your code so that it can intercept the break. Breakpoints trigger whether you've attached a debugger or not. 107 108Burst adds information to track local variables, function parameters and breakpoints. If your debugger supports conditional breakpoints, use these over adding breakpoints in your code, because they only fire when you've attached a debugger. 109 110## Profiling Burst-compiled code 111 112### Profiling using standalone profiling tools 113 114You can use profiling tools (such as Instruments or Superluminal) to profile Burst-compiled code in a player build. Because of the way that Unity builds the code for a player, you need to tell the profiling tool where to find the symbols. To do this, point the tool to the folder that contains the `lib_burst_generated` files, which is usually in the `Plugins` folder. 115 116<a name="profiler-markers"></a> 117 118### Unity Profiler markers 119 120To improve the data you get from Unity Profiler (either for Burst-compiled code running in the Editor or in an attached player), you can create Unity Profiler markers from Burst code by calling `new ProfilerMarker("MarkerName")`: 121 122```c# 123[BurstCompile] 124private static class ProfilerMarkerWrapper 125{ 126 private static readonly ProfilerMarker StaticMarker = new ProfilerMarker("TestStaticBurst"); 127 128 [BurstCompile(CompileSynchronously = true)] 129 public static int CreateAndUseProfilerMarker(int start) 130 { 131 using (StaticMarker.Auto()) 132 { 133 var p = new ProfilerMarker("TestBurst"); 134 p.Begin(); 135 var result = 0; 136 for (var i = start; i < start + 100000; i++) 137 { 138 result += i; 139 } 140 p.End(); 141 return result; 142 } 143 } 144} 145```