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

ARM compatibility #1

Merged
merged 1 commit into from
Jan 15, 2017
Merged

ARM compatibility #1

merged 1 commit into from
Jan 15, 2017

Conversation

fomojola
Copy link
Contributor

Added an unused int32 to the Channel structure. This fixes execution on ARM platforms (specifically Raspberry Pi) caused by golang/go#599. After cross-compiling for ARM using

GOOS=linux GOARM=6 GOARCH=arm go build github.com/barnybug/go-cast/cmd/cast

it appears that the call

requestId := int(atomic.AddInt64(&c.requestId, 1))

in Request() causes errors because the Channel structure isn't appropriately 64-bit aligned. The returned error looks like this:

pi@raspberrypi:~ $ ./cast --name chromecast media play 'http://192.168.2.22:8080/music/play.mp3"
Connecting to 192.168.2.42:8009...
Connected
panic: runtime error: invalid memory address or nil pointer dereference [recovered]
	panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x4 pc=0x152894]

goroutine 1 [running]:
panic(0x332b60, 0x10824008)
	/usr/local/go/src/runtime/panic.go:500 +0x33c
github.com/barnybug/go-cast/vendor/github.com/codegangsta/cli.HandleAction.func1(0x108f8f30)
	/workspace/src/github.com/barnybug/go-cast/vendor/github.com/codegangsta/cli/app.go:478 +0x290
panic(0x332b60, 0x10824008)
	/usr/local/go/src/runtime/panic.go:458 +0x454
sync/atomic.addUint64(0x1090159c, 0x1, 0x0, 0x1, 0x0)
	/usr/local/go/src/sync/atomic/64bit_arm.go:31 +0x68
github.com/barnybug/go-cast/net.(*Channel).Request(0x10901580, 0x76ef1120, 0x10816440, 0x495920, 0x4aa058, 0x141130, 0x0, 0x0)
	/workspace/src/github.com/barnybug/go-cast/net/channel.go:77 +0x60
github.com/barnybug/go-cast/controllers.(*ReceiverController).GetStatus(0x108c5700, 0x76ef1120, 0x10816440, 0x0, 0x0, 0x0)
	/workspace/src/github.com/barnybug/go-cast/controllers/receiver.go:150 +0x58
github.com/barnybug/go-cast.(*Client).launchMediaApp(0x10816900, 0x76ef1120, 0x10816440, 0x0, 0x0, 0x0, 0x0)
	/workspace/src/github.com/barnybug/go-cast/client.go:133 +0x48
github.com/barnybug/go-cast.(*Client).Media(0x10816900, 0x76ef1120, 0x10816440, 0x4, 0x0, 0x0)
	/workspace/src/github.com/barnybug/go-cast/client.go:171 +0x54
main.runCommand(0x76ef1120, 0x10816440, 0x10816900, 0x36447a, 0x4, 0x1080a0e8, 0x1, 0x1)
	/workspace/src/github.com/barnybug/go-cast/cmd/cast/main.go:343 +0xc8
main.cliCommand(0x10878280)
	/workspace/src/github.com/barnybug/go-cast/cmd/cast/main.go:128 +0x244
reflect.Value.call(0x31c8a0, 0x395e40, 0x13, 0x36428e, 0x4, 0x108f8ef0, 0x1, 0x1, 0x0, 0x0, ...)
	/usr/local/go/src/reflect/value.go:434 +0xd68
reflect.Value.Call(0x31c8a0, 0x395e40, 0x13, 0x108f8ef0, 0x1, 0x1, 0x0, 0x0, 0x0)
	/usr/local/go/src/reflect/value.go:302 +0x84
github.com/barnybug/go-cast/vendor/github.com/codegangsta/cli.HandleAction(0x31c8a0, 0x395e40, 0x10878280, 0x0, 0x0)
	/workspace/src/github.com/barnybug/go-cast/vendor/github.com/codegangsta/cli/app.go:487 +0x1d0
github.com/barnybug/go-cast/vendor/github.com/codegangsta/cli.Command.Run(0x36447a, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3676e2, 0xf, 0x0, ...)
	/workspace/src/github.com/barnybug/go-cast/vendor/github.com/codegangsta/cli/command.go:191 +0xc10
github.com/barnybug/go-cast/vendor/github.com/codegangsta/cli.(*App).RunAsSubcommand(0x108883c0, 0x10878140, 0x0, 0x0)
	/workspace/src/github.com/barnybug/go-cast/vendor/github.com/codegangsta/cli/app.go:361 +0xd18
github.com/barnybug/go-cast/vendor/github.com/codegangsta/cli.Command.startApp(0x3647da, 0x5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3671f2, 0xe, 0x0, ...)
	/workspace/src/github.com/barnybug/go-cast/vendor/github.com/codegangsta/cli/command.go:278 +0x78c
github.com/barnybug/go-cast/vendor/github.com/codegangsta/cli.Command.Run(0x3647da, 0x5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3671f2, 0xe, 0x0, ...)
	/workspace/src/github.com/barnybug/go-cast/vendor/github.com/codegangsta/cli/command.go:79 +0x54
github.com/barnybug/go-cast/vendor/github.com/codegangsta/cli.(*App).Run(0x10888300, 0x1080a0c0, 0x6, 0x6, 0x0, 0x0)
	/workspace/src/github.com/barnybug/go-cast/vendor/github.com/codegangsta/cli/app.go:240 +0x798
main.main()
	/workspace/src/github.com/barnybug/go-cast/cmd/cast/main.go:116 +0x6a0

The addition of the unused int32 forces the alignment to adjust appropriately and prevents the runtime error.

Added an unused int32 to the Channel structure. This fixes execution on ARM platforms (specifically Raspberry Pi) caused by golang/go#599. After cross-compiling for ARM using

GOOS=linux GOARM=6 GOARCH=arm go build github.com/barnybug/go-cast/cmd/cast

it appears that the call

requestId := int(atomic.AddInt64(&c.requestId, 1))

in Request() causes errors because the Channel structure isn't appropriately 64-bit aligned. The returned error looks like this:

pi@raspberrypi:~ $ ./cast --name chromecast media play 'http://192.168.2.22:8080/music/play.mp3"
Connecting to 192.168.2.42:8009...
Connected
panic: runtime error: invalid memory address or nil pointer dereference [recovered]
	panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x4 pc=0x152894]

goroutine 1 [running]:
panic(0x332b60, 0x10824008)
	/usr/local/go/src/runtime/panic.go:500 +0x33c
github.com/barnybug/go-cast/vendor/github.com/codegangsta/cli.HandleAction.func1(0x108f8f30)
	/workspace/src/github.com/barnybug/go-cast/vendor/github.com/codegangsta/cli/app.go:478 +0x290
panic(0x332b60, 0x10824008)
	/usr/local/go/src/runtime/panic.go:458 +0x454
sync/atomic.addUint64(0x1090159c, 0x1, 0x0, 0x1, 0x0)
	/usr/local/go/src/sync/atomic/64bit_arm.go:31 +0x68
github.com/barnybug/go-cast/net.(*Channel).Request(0x10901580, 0x76ef1120, 0x10816440, 0x495920, 0x4aa058, 0x141130, 0x0, 0x0)
	/workspace/src/github.com/barnybug/go-cast/net/channel.go:77 +0x60
github.com/barnybug/go-cast/controllers.(*ReceiverController).GetStatus(0x108c5700, 0x76ef1120, 0x10816440, 0x0, 0x0, 0x0)
	/workspace/src/github.com/barnybug/go-cast/controllers/receiver.go:150 +0x58
github.com/barnybug/go-cast.(*Client).launchMediaApp(0x10816900, 0x76ef1120, 0x10816440, 0x0, 0x0, 0x0, 0x0)
	/workspace/src/github.com/barnybug/go-cast/client.go:133 +0x48
github.com/barnybug/go-cast.(*Client).Media(0x10816900, 0x76ef1120, 0x10816440, 0x4, 0x0, 0x0)
	/workspace/src/github.com/barnybug/go-cast/client.go:171 +0x54
main.runCommand(0x76ef1120, 0x10816440, 0x10816900, 0x36447a, 0x4, 0x1080a0e8, 0x1, 0x1)
	/workspace/src/github.com/barnybug/go-cast/cmd/cast/main.go:343 +0xc8
main.cliCommand(0x10878280)
	/workspace/src/github.com/barnybug/go-cast/cmd/cast/main.go:128 +0x244
reflect.Value.call(0x31c8a0, 0x395e40, 0x13, 0x36428e, 0x4, 0x108f8ef0, 0x1, 0x1, 0x0, 0x0, ...)
	/usr/local/go/src/reflect/value.go:434 +0xd68
reflect.Value.Call(0x31c8a0, 0x395e40, 0x13, 0x108f8ef0, 0x1, 0x1, 0x0, 0x0, 0x0)
	/usr/local/go/src/reflect/value.go:302 +0x84
github.com/barnybug/go-cast/vendor/github.com/codegangsta/cli.HandleAction(0x31c8a0, 0x395e40, 0x10878280, 0x0, 0x0)
	/workspace/src/github.com/barnybug/go-cast/vendor/github.com/codegangsta/cli/app.go:487 +0x1d0
github.com/barnybug/go-cast/vendor/github.com/codegangsta/cli.Command.Run(0x36447a, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3676e2, 0xf, 0x0, ...)
	/workspace/src/github.com/barnybug/go-cast/vendor/github.com/codegangsta/cli/command.go:191 +0xc10
github.com/barnybug/go-cast/vendor/github.com/codegangsta/cli.(*App).RunAsSubcommand(0x108883c0, 0x10878140, 0x0, 0x0)
	/workspace/src/github.com/barnybug/go-cast/vendor/github.com/codegangsta/cli/app.go:361 +0xd18
github.com/barnybug/go-cast/vendor/github.com/codegangsta/cli.Command.startApp(0x3647da, 0x5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3671f2, 0xe, 0x0, ...)
	/workspace/src/github.com/barnybug/go-cast/vendor/github.com/codegangsta/cli/command.go:278 +0x78c
github.com/barnybug/go-cast/vendor/github.com/codegangsta/cli.Command.Run(0x3647da, 0x5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3671f2, 0xe, 0x0, ...)
	/workspace/src/github.com/barnybug/go-cast/vendor/github.com/codegangsta/cli/command.go:79 +0x54
github.com/barnybug/go-cast/vendor/github.com/codegangsta/cli.(*App).Run(0x10888300, 0x1080a0c0, 0x6, 0x6, 0x0, 0x0)
	/workspace/src/github.com/barnybug/go-cast/vendor/github.com/codegangsta/cli/app.go:240 +0x798
main.main()
	/workspace/src/github.com/barnybug/go-cast/cmd/cast/main.go:116 +0x6a0

The addition of the unused int32 forces the alignment to adjust appropriately and prevents the runtime error.
@barnybug barnybug merged commit 8197169 into barnybug:master Jan 15, 2017
@barnybug
Copy link
Owner

Nice spot. That's an ugly Go bug!

@fomojola
Copy link
Contributor Author

Thanks! Haven't written much go, so it was quite a frightening stack trace to encounter: was quite pleased to realize the solution was quite that simple (even if I'm honestly not sure WHY that works).

Great work with go-cast, by the way. Finally got it all wired and the Raspberry Pi tucked in the basement can now stream any MP3 from the NAS to the chromecast audio in the living room with ease. Now just need a suitable media library so I can index the music on the NAS and I should be good to go.

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.

2 participants