Edit: Updated the original post after more investigation to keep it concise. The test project is attached and reproduces the problem. Updated the thread title for the same reason.
Hi!
UnsafeUtility.Free in this example (based on the example in the documentation) does cause an Access Violation. How do I correctly free the memory of the (void*) Buffer of each ReadCommand after the read has completed?
[Test, Performance, Version("1")]
public unsafe void CrashIfRunMultipleTimes()
{
// Arrange
var p1 = Path.Combine(Application.dataPath, "StreamingAssets", "empty.txt");
var p2 = Path.Combine(Application.dataPath, "StreamingAssets", "nonempty.txt");
var p3 = Path.Combine(Application.dataPath, "StreamingAssets", "nonempty_more.txt");
var paths = new List<FixedString512> {p1, p2, p3};
var fs1 = new FileInfo(p1).Length;
var fs2 = new FileInfo(p2).Length;
var fs3 = new FileInfo(p3).Length;
var commands = new List<ReadCommand> {
new ReadCommand {
Buffer =
UnsafeUtility.Malloc(fs1, 16, Allocator.Persistent),
Offset = 0,
Size = fs1
},
new ReadCommand {
Buffer =
UnsafeUtility.Malloc(fs2, 16, Allocator.Persistent),
Offset = 0,
Size = fs2
},
new ReadCommand {
Buffer =
UnsafeUtility.Malloc(fs3, 16, Allocator.Persistent),
Offset = 0,
Size = fs3
}
};
var naPaths = new NativeArray<FixedString512>(paths.Count, Allocator.Persistent);
var naCommands = new NativeArray<ReadCommand>(paths.Count, Allocator.Persistent);
var naReadHandles = new NativeArray<ReadHandle>(paths.Count, Allocator.Persistent);
naPaths.CopyFrom(paths.ToArray());
naCommands.CopyFrom(commands.ToArray());
var job = new ReadAsyncFileJob {Paths = naPaths, ReadCommands = naCommands, ReadHandles = naReadHandles};
// Act
var handle = job.Schedule(naPaths.Length, 64);
handle.Complete();
// Assert
// should not crash, but does when run multiple times
// Free memory
for (var i = 0; i < naCommands.Length; i++)
UnsafeUtility.Free(naCommands[0].Buffer, Allocator.Persistent);
naPaths.Dispose();
naCommands.Dispose();
naReadHandles.Dispose();
}
(245c.52f4): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
Unity!YGNodeFree+0x20:
00007ff7`61d4a8d0 488b8940040000 mov rcx,qword ptr [rcx+440h] ds:808a8984`8d8d93cd=????????????????
0:091> !analyze -v
*******************************************************************************
* *
* Exception Analysis *
* *
*******************************************************************************
KEY_VALUES_STRING: 1
Key : AV.Fault
Value: Read
Key : Analysis.CPU.mSec
Value: 10562
Key : Analysis.DebugAnalysisProvider.CPP
Value: Create: 8007007e on DRAGONMASTER
Key : Analysis.DebugData
Value: CreateObject
Key : Analysis.DebugModel
Value: CreateObject
Key : Analysis.Elapsed.mSec
Value: 18528
Key : Analysis.Memory.CommitPeak.Mb
Value: 565
Key : Analysis.System
Value: CreateObject
Key : Timeline.OS.Boot.DeltaSec
Value: 300484
Key : Timeline.Process.Start.DeltaSec
Value: 807
Key : WER.OS.Branch
Value: rs4_release
Key : WER.OS.Timestamp
Value: 2018-04-10T18:04:00Z
Key : WER.OS.Version
Value: 10.0.17134.1
Key : WER.Process.Version
Value: 2020.1.0.59919
ADDITIONAL_XML: 1
OS_BUILD_LAYERS: 1
NTGLOBALFLAG: 0
PROCESS_BAM_CURRENT_THROTTLED: 0
PROCESS_BAM_PREVIOUS_THROTTLED: 0
APPLICATION_VERIFIER_FLAGS: 0
EXCEPTION_RECORD: (.exr -1)
ExceptionAddress: 00007ff761d4a8d0 (Unity!YGNodeFree+0x0000000000000020)
ExceptionCode: c0000005 (Access violation)
ExceptionFlags: 00000000
NumberParameters: 2
Parameter[0]: 0000000000000000
Parameter[1]: ffffffffffffffff
Attempt to read from address ffffffffffffffff
FAULTING_THREAD: 000052f4
PROCESS_NAME: Unity.exe
READ_ADDRESS: ffffffffffffffff
ERROR_CODE: (NTSTATUS) 0xc0000005 - Die Anweisung in 0x%p verwies auf Arbeitsspeicher bei 0x%p. Der Vorgang %s konnte im Arbeitsspeicher nicht durchgef hrt werden.
EXCEPTION_CODE_STR: c0000005
EXCEPTION_PARAMETER1: 0000000000000000
EXCEPTION_PARAMETER2: ffffffffffffffff
STACK_TEXT:
00000074`bb36f3f0 00007ff7`61f82af6 : 0000021f`9a124ae0 0000021f`9a124ae0 00000000`00000017 00007ff7`62f6d379 : Unity!YGNodeFree+0x20
00000074`bb36f420 00000221`1cc97f9e : 00007ff7`6696bd38 00000220`b84776d0 0000021f`311eb0b0 00000074`bb36f530 : Unity!Native_CUSTOM_YGNodeFreeInternal+0x56
00000074`bb36f460 00000221`1cc97e2b : 00007fff`3112cd78 00007fff`3112cd70 00000220`c9c3a3a0 00000221`1cc97853 : 0x00000221`1cc97f9e
00000074`bb36f4f0 00000221`1cc97bbb : 00000000`ffffffff 00000000`00000000 00000000`00000000 00000000`00000001 : 0x00000221`1cc97e2b
00000074`bb36f550 00000220`b847783c : 00000220`4c7e2d20 00000220`cc2b8780 00000000`00000000 00000000`00000000 : 0x00000221`1cc97bbb
00000074`bb36f5c0 00007fff`30da4239 : 00000220`cc2b8780 00000074`bb36f6a0 00000220`00000000 0000021f`50038038 : 0x00000220`b847783c
00000074`bb36f670 00007fff`30f9de32 : 00000000`00000000 00000220`cbc77b40 00000000`00000000 00000220`cbc77c00 : mono_2_0_bdwgc!mono_gc_run_finalize+0x389
00000074`bb36f730 00007fff`30da3139 : 00000000`00000000 00000220`4c7ead10 00000000`00000000 00000000`00000000 : mono_2_0_bdwgc!GC_invoke_finalizers+0xaa
00000074`bb36f760 00007fff`30d66368 : 00000220`4c4988f0 00000000`00000000 00000000`00000000 00000220`4c7e2d20 : mono_2_0_bdwgc!finalizer_thread+0x1a9
00000074`bb36f820 00007fff`30d660f6 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : mono_2_0_bdwgc!start_wrapper_internal+0x248
00000074`bb36f8f0 00007fff`a56b4034 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : mono_2_0_bdwgc!start_wrapper+0x46
00000074`bb36f920 00007fff`a5823691 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : KERNEL32!BaseThreadInitThunk+0x14
00000074`bb36f950 00000000`00000000 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : ntdll!RtlUserThreadStart+0x21
SYMBOL_NAME: Unity!YGNodeFree+20
MODULE_NAME: Unity
IMAGE_NAME: Unity.exe
STACK_COMMAND: ~91s ; .cxr ; kb
FAILURE_BUCKET_ID: INVALID_POINTER_READ_c0000005_Unity.exe!YGNodeFree
OS_VERSION: 10.0.17134.1
BUILDLAB_STR: rs4_release
OSPLATFORM_TYPE: x64
OSNAME: Windows 10
IMAGE_VERSION: 2020.1.0.59919
FAILURE_ID_HASH: {90a83abd-89db-bfa7-c5d2-da7b8e3cb8eb}
Followup: MachineOwner
---------
Edit:
- ReadHandle.Dispose is missing in the examples - as they only dispose NativeArray but not the handles themself, but adding it does not fix it.
Reproduce
Open the attached project and run the single included Performance test “CrashTest” (multiple times).