-
-
Notifications
You must be signed in to change notification settings - Fork 21.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Godot crash in ResourceSaver after 1073741824 bytes #62585
Comments
Making CowData use 64-bit unsigned integers is welcome, but it's a significant undertaking as it requires replacing the type in all places where relevant. |
Is this still reproducible in the latest betas? |
Still can happen on 4.0.0 stable. MRP that just generates a few GB of random mesh data and saves it: extends Node
func _ready():
const size = 50000000
var mesh = ArrayMesh.new()
var arrays = []
var vertices = PackedVector3Array()
vertices.resize(size)
for j in range(vertices.size()):
vertices[j] = Vector3(randf(), randf(), randf())
var uvs = PackedVector2Array()
uvs.resize(size)
for j in range(uvs.size()):
uvs[j] = Vector2(randf(), randf())
var uvs2 = PackedVector2Array()
uvs2.resize(size)
for j in range(uvs2.size()):
uvs2[j] = Vector2(randf(), randf())
var colors = PackedColorArray()
colors.resize(size)
for j in range(colors.size()):
colors[j] = Color(randf(), randf(), randf(), randf())
arrays.resize(ArrayMesh.ARRAY_MAX)
arrays[ArrayMesh.ARRAY_VERTEX] = vertices
arrays[ArrayMesh.ARRAY_TEX_UV] = uvs
arrays[ArrayMesh.ARRAY_TEX_UV2] = uvs2
arrays[ArrayMesh.ARRAY_COLOR] = colors
mesh.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLES, arrays);
ResourceSaver.save(mesh, "res://test.res", ResourceSaver.FLAG_COMPRESS) Also since I didn't see it in any of the linked issues: The MRP for just any of the CowData crashes is just |
ERROR: Condition "p_size < 0" is true. Returning: ERR_INVALID_PARAMETER when saving big map from glb to SCN. TSCN saving normally. Godot 4.0 Release. |
This is now causing a big problem for us and all users of Terrain3D. It does cause Godot to crash and does not save data. We can cause it by importing 2 8k maps into our 16k world space and using the ResourceSaver to save. Godot can handle a full 16k map in memory, but it only takes half, 8k by 16k to crash Godot when saving. The crash occurs when we call ResourceSaver.save() or by clicking the arrow in the inspector on the .res and selecting save. The resource is tied to a binary .res file in the inspector. Pre-crash it specifically has:
So call it 1.4gb of memory. Upon saving godot crashes with:
Our issue TokisanGames/Terrain3D#159 |
@akien-mga The new PR didn't fix this issue. It may have fixed part of it, but I attempted to save a 1.2gb resource file and saved it and it crashed. I just built Godot 0bcc0e9 with godot-cpp godotengine/godot-cpp@0145e90 (though it's not relevant). I loaded up a terrain in 8k x 8k segments. First segment saved at 413mb fine. Two segments at 800mb. Three segments crashed. This has nothing to do with our code. Our code loaded the data into a resource, then I manually used the inspector, right-click, and save the resource as a binary .res (contents listed above, defaults to compressed). Crash without any console error messages. Debugging, I found it crashed in https://github.com/godotengine/godot/blob/master/core/io/file_access_compressed.cpp#L344-L350 PR #77306 was intended to be part of the solution for this issue. When I apply that PR on this commit Godot doesn't crash. However it doesn't save the resource either. It writes 11.7mb and has a popup, |
By modifying the MRP at #62585 (comment) to save roughly 2.8 GB through Click to show gdb backtrace#0 0x000055555a4fa8aa in FileAccessCompressed::store_8 (this=0x55555f465320, p_dest=222 '\336') at core/io/file_access_compressed.cpp:349
#1 0x000055555a4ed346 in FileAccess::store_buffer (this=0x55555f465320, p_src=0x7ffc0f600030 "\021\vj*\276C\030>\307\327\177?\017\223\256>2\273",
p_length=2000000000) at core/io/file_access.cpp:711
#2 0x000055555a573aa0 in ResourceFormatSaverBinaryInstance::write_variant (f=..., p_property=..., resource_map=..., external_resources=..., string_map=...,
p_hint=...) at core/io/resource_format_binary.cpp:1841
#3 0x000055555a573907 in ResourceFormatSaverBinaryInstance::write_variant (f=..., p_property=..., resource_map=..., external_resources=..., string_map=...,
p_hint=...) at core/io/resource_format_binary.cpp:1822
#4 0x000055555a573a17 in ResourceFormatSaverBinaryInstance::write_variant (f=..., p_property=..., resource_map=..., external_resources=..., string_map=...,
p_hint=...) at core/io/resource_format_binary.cpp:1831
#5 0x000055555a575c7e in ResourceFormatSaverBinaryInstance::save (this=this@entry=0x7fffffffcc70, p_path=..., p_resource=..., p_flags=p_flags@entry=32)
at core/io/resource_format_binary.cpp:2288
#6 0x000055555a575f79 in ResourceFormatSaverBinary::save (this=<optimized out>, p_resource=..., p_path=..., p_flags=32)
at core/io/resource_format_binary.cpp:2427
#7 0x000055555a588062 in ResourceSaver::save (p_resource=..., p_path=..., p_flags=32) at core/io/resource_saver.cpp:127
#8 0x000055555a87986e in core_bind::ResourceSaver::save (this=0x55555f465528, p_resource=..., p_path=..., p_flags=...) at ./core/variant/type_info.h:301
#9 0x000055555a8a998d in call_with_variant_args_ret_helper<__UnexistingClass, Error, Ref<Resource> const&, String const&, BitField<core_bind::ResourceSaver::SaverFlags>, 0ul, 1ul, 2ul> (p_instance=p_instance@entry=0x55555d8c56f0, p_method=<optimized out>, p_args=p_args@entry=0x7fffffffced0, r_ret=...,
r_error=...) at ./core/variant/binder_common.h:755
#10 0x000055555a8a9ae9 in call_with_variant_args_ret_dv<__UnexistingClass, Error, Ref<Resource> const&, String const&, BitField<core_bind::ResourceSaver::SaverFlags> > (p_instance=0x55555d8c56f0, p_method=<optimized out>, p_args=0x7fffffffd160, p_argcount=3, r_ret=..., r_error=..., default_values=...)
at ./core/variant/binder_common.h:534
#11 0x000055555a8a9b46 in MethodBindTR<Error, Ref<Resource> const&, String const&, BitField<core_bind::ResourceSaver::SaverFlags> >::call (
this=<optimized out>, p_object=<optimized out>, p_args=<optimized out>, p_arg_count=<optimized out>, r_error=...) at ./core/object/method_bind.h:496
#12 0x0000555557eee847 in GDScriptFunction::call (this=<optimized out>, p_instance=<optimized out>, p_instance@entry=0x55555f4626d0,
p_args=p_args@entry=0x0, p_argcount=p_argcount@entry=0, r_err=..., p_state=<optimized out>) at modules/gdscript/gdscript_vm.cpp:1830
#13 0x0000555557e13bce in GDScript::_create_instance (this=this@entry=0x55555f4442e0, p_args=p_args@entry=0x0, p_argcount=p_argcount@entry=0,
p_owner=<optimized out>, p_owner@entry=0x55555f46dd50, p_is_ref_counted=<optimized out>, r_error=...) at modules/gdscript/gdscript.cpp:181
#14 0x0000555557e14089 in GDScript::instance_create (this=0x55555f4442e0, p_this=0x55555f46dd50) at modules/gdscript/gdscript.cpp:396
#15 0x000055555a7e7d19 in Object::set_script (this=this@entry=0x55555f46dd50, p_script=...) at core/object/object.cpp:907
#16 0x000055555784eb4e in Main::start () at main/main.cpp:3233 Click to show MRPRun with extends SceneTree
func _init():
const size = 100000000
var mesh = ArrayMesh.new()
var arrays = []
var vertices = PackedVector3Array()
vertices.resize(size)
for j in range(vertices.size()):
vertices[j] = Vector3(randf(), randf(), randf())
var uvs = PackedVector2Array()
uvs.resize(size)
for j in range(uvs.size()):
uvs[j] = Vector2(randf(), randf())
var uvs2 = PackedVector2Array()
uvs2.resize(size)
for j in range(uvs2.size()):
uvs2[j] = Vector2(randf(), randf())
var colors = PackedColorArray()
colors.resize(size)
for j in range(colors.size()):
colors[j] = Color(randf(), randf(), randf(), randf())
arrays.resize(ArrayMesh.ARRAY_MAX)
arrays[ArrayMesh.ARRAY_VERTEX] = vertices
arrays[ArrayMesh.ARRAY_TEX_UV] = uvs
arrays[ArrayMesh.ARRAY_TEX_UV2] = uvs2
arrays[ArrayMesh.ARRAY_COLOR] = colors
mesh.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLES, arrays);
ResourceSaver.save(mesh, "res://test.res", ResourceSaver.FLAG_COMPRESS)
quit() Reopening issue. |
Likely caused by https://github.com/godotengine/godot/blob/master/core/io/file_access_compressed.cpp#L49 in write_buffer_size = next_power_of_2(write_max); since |
These changes get this function working beyond 2gb and no longer crashes, however it never returns from the save. The engine is hung. The msvc debugger seems to think it's running. CPU usage is minimal. Temporary files exist, but files are 0. I tested importing terrain maps and saving to a resource file:
|
@lyuma this may be fixed with the cow size increase to 64 bit |
Godot version
4.0.alpha c41e4b1
System information
Windows 10, 64-bit
Issue description
I ran into this when saving a large scn with lots of textures, and used "Make Local" so all textures got embedded.
I tried saving this scene, and it gave an error in resize
After this error, it proceeded to crash.
CowData resizes to the next power of two, which is 2147483648, and overflows a signed int.
I think everything here should be made less sloppy. Array operations should always use unsigned, not signed values. Integers should be 64-bit where possible: GDScript already uses 64-bit, so why are they downgraded to 32-bit in C++? Finally, FileAccess should check the return value of
resize()
and fail gracefully.Steps to reproduce
Sorry I don't have more specific steps. The asset I used is not redistributable, and the save was automated by a script in order to enable ZSTD compression.
Minimal reproduction project
N/A
The text was updated successfully, but these errors were encountered: