Skip to content

HostBuffer.emplace overflows DeviceBuffer near block end (off-by-one in size check) #186526

Open

Description

@soulman-is-good

Steps to reproduce

  1. In a flame_3d ^0.2.0 app, render a 3D scene with enough draw calls and uniform writes per frame that the per-frame HostBuffer cursor approaches the 1 MB block boundary (e.g. ~330+ surfaces using a material with a Lights uniform of 784 bytes, plus VertexInfo, JointMatrices, Material, AmbientLight, Camera blocks).
  2. Rotate the camera to a heading at which the cursor lands inside the "danger window" [blockLengthInBytes - bytes.lengthInBytes, blockLengthInBytes).

Expected results

The HostBuffer allocates a new 1 MB block when the upcoming write would overflow the current block.

Actual results

DeviceBuffer.overwrite fails because the write extends past blockLengthInBytes, producing dark screen and throwing error in console:

══╡ EXCEPTION CAUGHT BY RENDERING LIBRARY ╞═════════════════════════════════════════════════════════
The following _Exception was thrown during paint():
Exception: Failed to write range (offset=1023488, length=784) to HostBuffer-managed DeviceBuffer
(frame=0, buffer=0, offset=1024272).

The relevant error-causing widget was:
  RenderGameWidget
  RenderGameWidget:file:///<REDACTED>/.pub-cache/hosted/pub.dev/flame-1.37.0/lib/src/game/game_widget/game_widget.dart:356:36

When the exception was thrown, this was the stack:
#0      HostBuffer.emplace (package:flutter_gpu/src/buffer.dart:306:7)
#1      GraphicsDevice.bindUniform (package:flame_3d/src/graphics/graphics_device.dart:174:47)
#2      Shader.bind (package:flame_3d/src/resources/shader/shader.dart:105:18)
#3      GraphicsDevice.bindMaterial (package:flame_3d/src/graphics/graphics_device.dart:169:29)
#4      GraphicsDevice.bindSurface (package:flame_3d/src/graphics/graphics_device.dart:137:5)
#5      Mesh.bind (package:flame_3d/src/resources/mesh/mesh.dart:29:14)
#6      GraphicsDevice.bindMesh (package:flame_3d/src/graphics/graphics_device.dart:131:10)
#7      MeshComponent.bind (package:flame_3d/src/components/mesh_component.dart:34:9)
#8      Object3D.renderTree (package:flame_3d/src/components/object_3d.dart:74:7)
#9      Component.renderChild (package:flame/src/components/core/component.dart:596:11)
#10     Component.renderTree (package:flame/src/components/core/component.dart:622:9)
#11     World.renderFromCamera (package:flame/src/camera/world.dart:33:11)
#12     World3D.renderFromCamera (package:flame_3d/src/camera/world_3d.dart:64:11)
#13     CameraComponent.renderTree.renderWorld (package:flame/src/camera/camera_component.dart:208:18)
#14     CameraComponent.renderTree (package:flame/src/camera/camera_component.dart:232:11)
#15     FlameGame.renderTree (package:flame/src/game/flame_game.dart:168:17)
#16     FlameGame.render (package:flame/src/game/flame_game.dart:158:7)
#17     GameRenderBox.paint (package:flame/src/game/game_render_box.dart:149:10)
#18     RenderObject._paintWithContext (package:flutter/src/rendering/object.dart:3429:7)
#19     PaintingContext._repaintCompositedChild (package:flutter/src/rendering/object.dart:180:11)
#20     PaintingContext.repaintCompositedChild (package:flutter/src/rendering/object.dart:125:5)
#21     PipelineOwner.flushPaint (package:flutter/src/rendering/object.dart:1325:31)
#22     PipelineOwner.flushPaint (package:flutter/src/rendering/object.dart:1335:15)
#23     RendererBinding.drawFrame (package:flutter/src/rendering/binding.dart:631:23)
#24     WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:1304:13)
#25     RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:495:5)
#26     SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:1430:15)
#27     SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:1345:9)
#28     SchedulerBinding._handleDrawFrame (package:flutter/src/scheduler/binding.dart:1198:5)
#29     _invoke (dart:ui/hooks.dart:356:13)
#30     PlatformDispatcher._drawFrame (dart:ui/platform_dispatcher.dart:444:5)
#31     _drawFrame (dart:ui/hooks.dart:328:31)

The following RenderObject was being processed when the exception was fired: GameRenderBox#6b7e1:
  needs compositing
  creator: RenderGameWidget ← Listener ← _GestureSemantics ← RawGestureDetector ← MouseRegion ←
    Listener ← Stack ← FutureBuilder<void> ← LayoutBuilder ← DecoratedBox ← Directionality ←
    MouseRegion ← ⋯
  parentData: <none> (can use size)
  constraints: BoxConstraints(0.0<=w<=1614.0, 0.0<=h<=977.0)
  layer: OffsetLayer#118cf
  size: Size(1614.0, 977.0)
This RenderObject has no descendants.

Code sample

Code sample
import 'dart:typed_data';

import 'package:flutter/material.dart';
import 'package:flutter_gpu/gpu.dart';

void main() {
  WidgetsFlutterBinding.ensureInitialized();

  print(
    'minimumUniformByteAlignment = '
    '${gpuContext.minimumUniformByteAlignment} bytes',
  );
  print(
    'blockLengthInBytes (default) = '
    '${HostBuffer.kDefaultBlockLengthInBytes} bytes',
  );

  final hostBuffer = gpuContext.createHostBuffer();

  // Step 1: fill the cursor to (blockLength - 256) in a single emplace.
  // 1023744 is a multiple of all common alignments (16/32/64/128/256), so
  // the next emplace's padding will be 0 regardless of platform.
  print('Step 1: emplace(ByteData(1023744)) → cursor → 1023744');
  hostBuffer.emplace(ByteData(1023744));

  // Step 2: emplace 728 bytes. The buggy bounds check passes (1023744 <
  // 1024000), but the write extends to 1024472, overflowing the 1024000-byte
  // block. DeviceBuffer.overwrite returns false and HostBuffer.emplace
  // throws.
  print('Step 2: emplace(ByteData(728)) — throws...');
  hostBuffer.emplace(ByteData(728));

  // Run a minimal app so the engine stays alive long enough for the print
  // output to flush. Tap the screen to exit.
  runApp(const _BugApp());
}

class _BugApp extends StatelessWidget {
  const _BugApp();

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Center(
          child: Text(
            'HostBuffer.emplace overflow reproduction.\n'
            'See console output.\n\n'
            'Expected exception:\n'
            '  Failed to write range (offset=1023744, length=728) to\n'
            '  HostBuffer-managed DeviceBuffer\n'
            '  (frame=0, buffer=0, offset=1024472).',
            textAlign: TextAlign.center,
          ),
        ),
      ),
    );
  }
}

Screenshots or Video

Screenshots / Video demonstration

https://youtu.be/xWQsWn2huNg

Logs

Logs
[Paste your logs here]

Flutter Doctor output

Doctor output
Doctor summary (to see all details, run flutter doctor -v):
[!] Flutter (Channel stable, 3.41.9, on macOS 15.7.5 24G624 darwin-arm64, locale en-NL)
    ! Warning: `dart` on your path resolves to /opt/homebrew/Cellar/dart/3.11.0/libexec/bin/dart, which is not inside your current Flutter SDK checkout at /Users/savinmax/flutter. Consider adding /Users/savinmax/flutter/bin to the front of your path.
[✗] Android toolchain - develop for Android devices
    ✗ Unable to locate Android SDK.
      Install Android Studio from: https://developer.android.com/studio/index.html
      On first launch it will assist you in installing the Android SDK components.
      (or visit https://flutter.dev/to/macos-android-setup for detailed instructions).
      If the Android SDK has been installed to a custom location, please use
      `flutter config --android-sdk` to update to that location.

[✓] Xcode - develop for iOS and macOS (Xcode 16.2)
[✓] Chrome - develop for the web
[✓] Connected device (2 available)
[✓] Network resources

! Doctor found issues in 2 categories.

Activity

  1. added a commit that references this issue on May 14, 2026
    65b7a68
  2. puneetkukreja98 commented on May 15, 2026

    @puneetkukreja98
    Contributor

    @soulman-is-good Thanks for reporting the issue. I ran the sample code in a macOS environment and am getting these logs. Routing this to team-fluttergpu for investigation.
    Logs:

    Launching lib/main.dart on macOS in debug mode...
    Building macOS application...                                           
    ✓ Built build/macos/Build/Products/Debug/test_appi.app
    2026-05-15 18:30:15.855 test_appi[86707:2248743] Running with merged UI and platform thread. Experimental.
    [IMPORTANT:flutter/shell/platform/embedder/embedder_surface_metal_impeller.mm(51)] Using the Impeller rendering backend (Metal).
    Failed to foreground app; open returned 1
    flutter: minimumUniformByteAlignment = 256 bytes
    flutter: blockLengthInBytes (default) = 1024000 bytes
    flutter: Step 1: emplace(ByteData(1023744)) → cursor → 1023744
    flutter: Step 2: emplace(ByteData(728)) — throws...
    [ERROR:flutter/runtime/dart_vm_initializer.cc(40)] Unhandled Exception: Exception: Failed to write range (offset=1023744, length=728) to HostBuffer-managed DeviceBuffer (frame=0, buffer=0, offset=1024472).
    #0      HostBuffer.emplace (package:flutter_gpu/src/buffer.dart:306:7)
    #1      main (package:test_appi/main.dart:31:14)
    #2      _runMain.<anonymous closure> (dart:ui/hooks.dart:345:23)
    #3      _delayEntrypointInvocation.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:314:19)
    #4      _RawReceivePort._handleMessage (dart:isolate-patch/isolate_patch.dart:193:12)
    
    Syncing files to device macOS...                                    54ms
    
    Flutter run key commands.
    r Hot reload. 🔥🔥🔥
    R Hot restart.
    h List all available interactive commands.
    d Detach (terminate "flutter run" but leave application running).

    Flutter doctor -v

    [✓] Flutter (Channel stable, 3.41.9, on macOS 26.4.1 25E253 darwin-arm64, locale en-US) [703ms]
        • Flutter version 3.41.9 on channel stable at /Users/puneetkukreja/Developer/flutter
        • Upstream repository https://github.com/flutter/flutter.git
        • Framework revision 00b0c91f06 (2 weeks ago), 2026-04-29 10:03:19 -0700
        • Engine revision 42d3d75a56
        • Dart version 3.11.5
        • DevTools version 2.54.2
        • Feature flags: enable-web, enable-linux-desktop, enable-macos-desktop, enable-windows-desktop, enable-android, enable-ios, cli-animations, enable-native-assets, omit-legacy-version-file,
          enable-lldb-debugging, enable-uiscene-migration
    
    [✓] Android toolchain - develop for Android devices (Android SDK version 36.1.0) [2.6s]
        • Android SDK at /Users/puneetkukreja/Library/Android/sdk
        • Emulator version 36.5.10.0 (build_id 15081367) (CL:N/A)
        • Platform android-36.1, build-tools 36.1.0
        • Java binary at: /Library/Java/JavaVirtualMachines/jdk-17.jdk/Contents/Home/bin/java
          This JDK is specified in your Flutter configuration.
          To change the current JDK, run: `flutter config --jdk-dir="path/to/jdk"`.
        • Java version Java(TM) SE Runtime Environment (build 17.0.12+8-LTS-286)
        • All Android licenses accepted.
    
    [✓] Xcode - develop for iOS and macOS (Xcode 26.5) [1,334ms]
        • Xcode at /Applications/Xcode.app/Contents/Developer
        • Build 17F42
        • CocoaPods version 1.16.2
    
    [✓] Chrome - develop for the web [5ms]
        • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
    
    [✓] Connected device (3 available) [7.0s]
        • Puneet’s iPhone (wireless) (mobile) • 00008110-00167CEE0C46401E • ios            • iOS 18.0.1 22A3370
        • macOS (desktop)                     • macos                     • darwin-arm64   • macOS 26.4.1 25E253 darwin-arm64
        • Chrome (web)                        • chrome                    • web-javascript • Google Chrome 148.0.7778.168
    
    [✓] Network resources [1,051ms]
        • All expected network resources are available.
    
    • No issues found!
    
  3. added
    engineflutter/engine related. See also e: labels.
    and removed
    in triagePresently being triaged by the triage team
    on May 15, 2026
  4. moved this to 🤔 Needs Triage in Flutter GPUon May 15, 2026
  5. moved this from 🤔 Needs Triage to 🐞 Bugs in Flutter GPUon Jun 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    engineflutter/engine related. See also e: labels.flutter-gputeam-fluttergpuOwned by Flutter GPU team

    Type

    No type

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions