Skip to content

fix(wgpu): C-allocate device descriptor to allow DeviceLostCallback - #8

Open
dhannyell wants to merge 1 commit into
oliverbestmann:mainfrom
dhannyell:fix/request-device-cgo-pointer
Open

fix(wgpu): C-allocate device descriptor to allow DeviceLostCallback#8
dhannyell wants to merge 1 commit into
oliverbestmann:mainfrom
dhannyell:fix/request-device-cgo-pointer

Conversation

@dhannyell

@dhannyell dhannyell commented Jul 21, 2026

Copy link
Copy Markdown

Fixes #7

C-allocates the device descriptor in RequestDevice so the cgo pointer checker
does not scan it as Go memory, allowing the DeviceLostCallback handle to be
embedded without panicking. See #7 for the full root-cause analysis and the
minimal reproduction.

Diff

 	if descriptor != nil {
-		desc = &C.WGPUDeviceDescriptor{}
+		desc = (*C.WGPUDeviceDescriptor)(C.calloc(1, C.size_t(unsafe.Sizeof(C.WGPUDeviceDescriptor{}))))
+		defer C.free(unsafe.Pointer(desc))

Validation

  • Before: panic at adapter.go:241 when a DeviceLostCallback is set.
  • After: RequestDevice with a callback succeeds.
  • Regression: RequestDevice(nil) still works.
  • Heap safety: three devices created/released in sequence (nil →
    label+callback → label+RequiredLimits+callback) all succeed.
  • Race detector: go run -race clean.
  • Existing example: go build ./examples/triangle/ and go vet ./wgpu/
    pass.

RequestDevice Go-allocated the descriptor with &C.WGPUDeviceDescriptor{} and then embedded the DeviceLostCallback handle (a Go pointer, &pointers[0] from newHandle) in desc.deviceLostCallbackInfo.userdata1. Passing desc (a Go pointer to Go memory now containing a Go pointer) to C violates the cgo pointer rule and panics with 'Go pointer to unpinned Go pointer'.

C-allocate desc with calloc instead, matching the pattern already used for requiredFeatures/requiredLimits/deviceExtras in the same function. The checker does not scan C memory, so the embedded Go pointer is allowed; &pointers[0] points to byte storage with no nested pointers. wgpuAdapterRequestDevice is synchronous, so freeing at function exit is safe. The nil-descriptor path is unchanged.

Verified: RequestDevice with a DeviceLostCallback now succeeds instead of panicking; RequestDevice(nil) still works; three devices created/released in sequence (nil, label+callback, label+RequiredLimits+callback) all succeed; go run -race clean; go build ./wgpu/ and go vet ./wgpu/ pass.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] RequestDevice cause cgo panic when DeviceLostCallback is provided

1 participant