Hotpatching causes stack overflow when system function body is very large
- Dominant language
- Rust
- Stars
- 48.2k
- Forks
- 4.8k
- Avg merge
- 3d 16h
- Merged PRs (30d)
- 171
Description
## Bevy version and features
- **Bevy Version**: `0.17.2`
- **Features**: `default`, `hotpatching`
## [Optional] Relevant system information
- **Rust version**: `cargo 1.90.0 (840b83a10 2025-07-30)`
- **Operating System**: Windows 10 Pro (Kernel: 19045)
- **AdapterInfo**: `AdapterInfo { name: "NVIDIA GeForce RTX 4090", vendor: 4318, device: 9860, device_type: DiscreteGpu, driver: "NVIDIA", driver_info: "581.15", backend: Vulkan }`
- **Full SystemInfo**: `SystemInfo { os: "Windows 10 Pro", kernel: "19045", cpu: "13th Gen Intel(R) Core(TM) i7-13700KF", core_count: "16", memory: "63.8 GiB" }`
## What you did
1. I ran the `3d_viewport_to_world` example using `dx` with hot-patching enabled:
```bash
dx serve --hot-patch --example 3d_viewport_to_world --features hotpatching
```
2. Wait for the build to finish and the window to open.
3. I modified `examples/3d/3d_viewport_to_world.rs` to trigger a hot patch.
4. Specifically, I increased the size of the `draw_cursor` system by copying and pasting the logic block inside it 9 times (resulting in 10 repetitions of the logic).
5. Upon saving the file, `dx` attempted to hot-patch the changes.
## What went wrong
### What were you expecting?
I expected the hot-patch to succeed and the application to continue running, rendering the updated logic (10 circles).
### What actually happened?
The application crashed immediately after the hot-patch was applied with a stack overflow error.
**Console Output:**
```text
10:14:18 [dev] Hot-patching: \examples\3d\3d_viewport_to_world.rs took 958ms
10:14:18 [windows] thread 'Compute Task Pool (11)' has overflowed its stack
10:14:19 [dev] Application [windows] exited with error: exit code: 0xc00000fd
```
## Additional information
### Full Logs
```text
PS D:\Users\admin\workspace\bevy> dx serve --hot-patch --example 3d_viewport_to_world --features hotpatching
10:12:01 [dev] failed to parse global settings file
10:12:02 [dev] A new dx version is available: 0.7.1! Run dx self-update to update.
10:12:03 [dev] -----------------------------------------------------------------
Serving your app: 3d_viewport_to_world! 🚀
• Press `ctrl+c` to exit the server
• Press `r` to rebuild the app
• Press `p` to toggle automatic rebuilds
• Press `v` to toggle verbose logging
• Press `/` for more commands and shortcuts
----------------------------------------------------------------
10:12:25 [dev] Build completed successfully in 20949ms, launching app! 💫
10:12:27 [windows] 2025-11-15T02:12:27.347813Z INFO bevy_diagnostic::system_information_diagnostics_plugin::internal: SystemInfo { os: "Windows 10 Pro", kernel: "19045", cpu: "13th Gen Intel(R) Core(TM) i7-13700KF", core_count: "16", memory: "63.8 GiB" }
10:12:27 [windows] 2025-11-15T02:12:27.648941Z INFO bevy_render::renderer: AdapterInfo { name: "NVIDIA GeForce RTX 4090", vendor: 4318, device: 9860, device_type: DiscreteGpu, driver: "NVIDIA", driver_info: "581.15", backend: Vulkan }
10:12:27 [windows] 2025-11-15T02:12:27.942656Z INFO bevy_render::batching::gpu_preprocessing: GPU preprocessing is fully supported on this device.
10:12:27 [windows] 2025-11-15T02:12:27.980351Z INFO bevy_winit::system: Creating new window 3d_viewport_to_world (0v0)
10:13:18 [dev] Hot-patching: \examples\3d\3d_viewport_to_world.rs took 1014ms
...
10:14:18 [dev] Hot-patching: \examples\3d\3d_viewport_to_world.rs took 958ms
10:14:18 [windows] thread 'Compute Task Pool (11)' has overflowed its stack
10:14:19 [dev] Application [windows] exited with error: exit code: 0xc00000fd
```
### Reproduction Code (`draw_cursor`)
Paste this into `examples/3d/3d_viewport_to_world.rs` to reproduce:
```rust
fn draw_cursor(
camera_query: Single<(&Camera, &GlobalTransform)>,
ground: Single<&GlobalTransform, With>,
window: Single<&Window>,
mut gizmos: Gizmos,
) {
let (camera, camera_transform) = *camera_query;
// Repeat this block 10 times to cause stack overflow on hot-patch
if let Some(cursor_position) = window.cursor_position()
&& let Ok(ray) = camera.viewport_to_world(camera_transform, cursor_position)
&& let Some(distance) =
ray.intersect_plane(ground.translation(), InfinitePlane3d::new(ground.up()))
{
let point = ray.get_point(distance);
gizmos.circle(
Isometry3d::new(
point + ground.up() * 0.01,
Quat::from_rotation_arc(Vec3::Z, ground.up().as_vec3()),
),
1.0,
Color::WHITE,
);
}
// ... [Repeated 9 more times with slightly different radii as shown in the description]
if let Some(cursor_position) = window.cursor_position()
&& let Ok(ray) = camera.viewport_to_world(camera_transform, cursor_position)
&& let Some(distance) =
ray.intersect_plane(ground.translation(), InfinitePlane3d::new(ground.up()))
{
let point = ray.get_point(distance);
gizmos.circle(
Isometry3d::new(
point + ground.up() * 0.01,
Quat::from_rotation_arc(Vec3::Z, ground.up().as_vec3()),
),
10.0, // Changed radius
Color::WHITE,
);
}
}
```
Contributor guide
Research direction
Start by running `dx serve --hot-patch --example 3d_viewport_to_world --features hotpatching` and reproduce the failure by expanding `draw_cursor` in `examples/3d/3d_viewport_to_world.rs` to ten logic repetitions. Then trace the hot-patching path involved in applying that example change. Done means the hot-patch completes without a stack overflow and the updated example continues rendering.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- developer-experience, game-dev
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100