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 when trying to build 32-bit binary #83

Closed
roffe opened this issue Mar 11, 2024 · 4 comments · Fixed by #96
Closed

Panic when trying to build 32-bit binary #83

roffe opened this issue Mar 11, 2024 · 4 comments · Fixed by #96

Comments

@roffe
Copy link

roffe commented Mar 11, 2024

Panic when trying to build 32-bit binary

GOOS = "Windows"
GOARCH = "386"
CGO_ENABLED = "1"

go version go1.22.0 windows/amd64

panic: compileCallback: expected function with one uintptr-sized result

goroutine 1 [running, locked to thread]:
syscall.compileCallback({0x12fd2e0, 0x13ebc50}, 0x1)
        C:/Go/src/runtime/syscall_windows.go:291 +0x496
syscall.NewCallback(...)
        C:/Go/src/syscall/syscall_windows.go:214
github.com/saltosystems/winrt-go/internal/delegate.init()
        C:/Users/roffe/go/src/github.com/saltosystems/winrt-go/internal/delegate/delegate.go:18 +0x83
exit status 2
jagobagascon added a commit that referenced this issue Mar 12, 2024
The `NewCallback` function expects the received argument to be a
function with one uintptr-sized result. That uintptr type may be a 32 or
64 bit pointer depending on the system, but some functions were always
returning a uint64 value. That was causing errors in 32 bit systems.

fixes #83
@jagobagascon
Copy link
Contributor

It looks like the syscall callbacks need to return a uintptr-sized result, but we are returning a uint64 which messes with 32 bit systems. Thanks for the report!

I was able to reproduce the problem, and I think this branch (feature/fix-callback-return-type) will fix the issue. Could you test it please?

@roffe
Copy link
Author

roffe commented Mar 12, 2024

Thank you for the fast response!

It compiles now but my very simple test program using tinygo.org/x/bluetooth crashes after first scan result.

Not sure if it's now a issue for this repo or tinygo.org/x/bluetooth

Im on Windows 11 23H2 22631.3155, Go 1.22 and using tdm-gcc as C compiler if that helps

goarch=386

PS: 19 2024-03-12 13:48:50 bttest >go run .
scanning...
2024/03/12 13:49:09 main.go:26: found device: 67:04:C5:16:96:38, -70, 
exit status 0xc0000005

goarch=amd64

PS: 22 2024-03-12 13:52:46 bttest >$env:GOARCH="amd64" 
PS: 23 2024-03-12 13:54:03 bttest >go run .
scanning...
2024/03/12 13:54:05 main.go:24: found device: 65:06:17:73:85:23, -90, 
2024/03/12 13:54:05 main.go:24: found device: 49:92:32:66:14:17, -70,
2024/03/12 13:54:05 main.go:24: found device: 49:92:32:66:14:17, -70,
2024/03/12 13:54:05 main.go:24: found device: 5F:55:B0:D7:0E:1B, -70,
2024/03/12 13:54:05 main.go:24: found device: 46:46:46:EC:DC:B7, -88,
2024/03/12 13:54:05 main.go:24: found device: 64:B7:08:5F:F6:9A, -88,
2024/03/12 13:54:05 main.go:24: found device: 65:03:49:F6:3A:9C, -70, 
2024/03/12 13:54:05 main.go:24: found device: 65:03:49:F6:3A:9C, -70,
2024/03/12 13:54:05 main.go:24: found device: D0:03:DF:AB:78:6F, -72,
2024/03/12 13:54:05 main.go:24: found device: 64:B7:08:5F:F6:9A, -86, 
2024/03/12 13:54:05 main.go:24: found device: 64:B7:08:5F:F6:9A, -86, OBDX Pro GT
2024/03/12 13:54:05 main.go:42: connected to 64:B7:08:5F:F6:9A
package main

import (
	"log"
	"time"

	"tinygo.org/x/bluetooth"
)

var adapter = bluetooth.DefaultAdapter

func init() {
	log.SetFlags(log.LstdFlags | log.Lshortfile)
}

func main() {
	must("enable BLE stack", adapter.Enable())
	ch := make(chan bluetooth.ScanResult, 1)

	start := time.Now()

	println("scanning...")
	err := adapter.Scan(func(adapter *bluetooth.Adapter, device bluetooth.ScanResult) {
		log.Printf("found device: %s, %d, %s", device.Address.String(), device.RSSI, device.LocalName())
		if time.Since(start) > 10*time.Second {
			adapter.StopScan()
		}
		if device.LocalName() == "OBDX Pro GT" {
			adapter.StopScan()
			ch <- device
		}
	})
	must("start scan", err)

	var device bluetooth.Device
	select {
	case d := <-ch:
		device, err = adapter.Connect(d.Address, bluetooth.ConnectionParams{})
		if err != nil {
			log.Fatal("failed to connect:", err)
		}
		log.Printf("connected to %s", d.Address.String())
	case <-time.After(10 * time.Second):
		log.Fatal("Did not find any OBDX Pro GT device")
	}

	device.Disconnect()

}

func must(action string, err error) {
	if err != nil {
		log.Fatal("failed to " + action + ": " + err.Error())
	}
}

@jagobagascon
Copy link
Contributor

I get the same result so we may be missing something. After the first scanned device the program closes with exit status 0xc0000005.

@jagobagascon
Copy link
Contributor

jagobagascon commented Mar 13, 2024

I tried debugging the generated binary using WinDbg and I think this is the stack when the error happens:

[0x0]   0xffffffffcccccccc!+   0x315cf784   0x707be2e1   
[0x1]   Windows_Devices_Bluetooth!wistd::__function::__func<<lambda_294007b0f2593fc9ac11b79d22635d8e>,long __stdcall(Windows::Foundation::ITypedEventHandler<Windows::Devices::Bluetooth::GenericAttributeProfile::GattCharacteristic *,Windows::Devices::Bluetooth::GenericAttributeProfile::GattValueChangedEventArgs *> *)>::operator()+0x21   0x315cf788   0x707bc2cd   
[0x2]   Windows_Devices_Bluetooth!Microsoft::WRL::InvokeTraits<2>::InvokeDelegates<<lambda_060960e27843950aa1a5ff05be23c883>,Windows::Foundation::ITypedEventHandler<Windows::Devices::Bluetooth::GenericAttributeProfile::GattSession *,Windows::Devices::Bluetooth::GenericAttributeProfile::GattSessionStatusChangedEventArgs *> >+0x53   0x315cf7a0   0x707b9bc0   
[0x3]   Windows_Devices_Bluetooth!wil::AsyncEventSourceT<Windows::Foundation::ITypedEventHandler<Windows::Devices::Bluetooth::Advertisement::BluetoothLEAdvertisementPublisher *,Windows::Devices::Bluetooth::Advertisement::BluetoothLEAdvertisementPublisherStatusChangedEventArgs *>,Windows::Internal::GitEventSourceSupportsAgile,Microsoft::WRL::InvokeModeOptions<2>,1,wil::err_returncode_policy>::AsyncEventWorkItem::RaiseEvent+0x30   0x315cf7dc   0x707c4257   
[0x4]   Windows_Devices_Bluetooth!wil::details::AsyncEventInvocationPolicy<1>::HandleAsyncEventInvoke+0x67   0x315cf7f8   0x707c42ee   
[0x5]   Windows_Devices_Bluetooth!wil::details::EventInvocationContext<1>::AsyncEventWorkCallback+0x4e   0x315cf818   0x77cbf4f8   
[0x6]   ntdll!$push_thunk$stdcall$v$uuu+0x50   0x315cf830   0x0   

Which is crazy because I'm just scanning devices, I'm not connecting nor reading any characteristic. But the errors happens in a GattCharacteristic for some reason.

At this point I think someone should try this on a 32 bit machine. There's too many layers of abstraction that could cause issues (a 32 bit binary running on a Windows ARM virtual machine running in parallels on a ARM MacOS).

jagobagascon added a commit that referenced this issue May 10, 2024
According to the syscall.NewCallback docs all the callbacks should
return an uintptr sized result. But we were previously using uint64
which only works for 64 bit systems. This change should allow using
winrt-go on 32 bit windows devices.

fixes #83
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 a pull request may close this issue.

2 participants