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

unaligned 64-bit atomic operation #52

Closed
kkettinger opened this issue Jan 31, 2023 · 4 comments · Fixed by #53
Closed

unaligned 64-bit atomic operation #52

kkettinger opened this issue Jan 31, 2023 · 4 comments · Fixed by #53

Comments

@kkettinger
Copy link

kkettinger commented Jan 31, 2023

I'm trying to control the state machine with gin (http server) on a raspberry pi 4, but after firing the first event i get a panic:

2023/01/31 23:18:24 [Recovery] 2023/01/31 - 23:18:24 panic recovered:
POST /api/measure/automatic HTTP/1.1
Host: raspberrypi:8080
Accept: */*
Content-Length: 20
Content-Type: application/json
User-Agent: curl/7.83.1


unaligned 64-bit atomic operation
/usr/local/go/src/runtime/internal/atomic/unaligned.go:8 (0x125f3)
        panicUnaligned: panic("unaligned 64-bit atomic operation")
/usr/local/go/src/runtime/internal/atomic/atomic_arm.s:280 (0x12947)
        Load64: CHECK_ALIGN
/home/kk/go/pkg/mod/github.com/qmuntal/stateless@v1.6.1/statemachine.go:279 (0x177bcb)
        (*StateMachine).Firing: return atomic.LoadUint64(&sm.ops) != 0
/home/kk/go/pkg/mod/github.com/qmuntal/stateless@v1.6.1/statemachine.go:338 (0x177bf4)
        (*StateMachine).internalFireQueued: if sm.Firing() {
/home/kk/go/pkg/mod/github.com/qmuntal/stateless@v1.6.1/statemachine.go:324 (0x177957)
        (*StateMachine).internalFire: return sm.internalFireQueued(ctx, trigger, args...)
/home/kk/go/pkg/mod/github.com/qmuntal/stateless@v1.6.1/statemachine.go:251 (0x17aeb7)
        (*StateMachine).FireCtx: return sm.internalFire(ctx, trigger, args...)
/home/kk/go/pkg/mod/github.com/qmuntal/stateless@v1.6.1/statemachine.go:234 (0x17ae6c)
        (*StateMachine).Fire: return sm.FireCtx(context.Background(), trigger, args...)
/home/kk/repos/custom-app/internal/measure/measure.go:30 (0x17ae74)
        Start: measurement.stateMachine.Fire(triggerStart)
/home/kk/repos/custom-app/internal/restserver/measure.go:46 (0x418d27)
        MeasureEndpointPOST: measure.Start()
/home/kk/go/pkg/mod/github.com/gin-gonic/gin@v1.8.2/context.go:173 (0x40c3db)
        (*Context).Next: c.handlers[c.index](c)
/home/kk/go/pkg/mod/github.com/gin-gonic/gin@v1.8.2/recovery.go:101 (0x40c3b8)
        CustomRecoveryWithWriter.func1: c.Next()
/home/kk/go/pkg/mod/github.com/gin-gonic/gin@v1.8.2/context.go:173 (0x40b4bb)
        (*Context).Next: c.handlers[c.index](c)
/home/kk/go/pkg/mod/github.com/gin-gonic/gin@v1.8.2/logger.go:240 (0x40b498)
        LoggerWithConfig.func1: c.Next()
/home/kk/go/pkg/mod/github.com/gin-gonic/gin@v1.8.2/context.go:173 (0x40a433)
        (*Context).Next: c.handlers[c.index](c)
/home/kk/go/pkg/mod/github.com/gin-gonic/gin@v1.8.2/gin.go:616 (0x40a128)
        (*Engine).handleHTTPRequest: c.Next()
/home/kk/go/pkg/mod/github.com/gin-gonic/gin@v1.8.2/gin.go:572 (0x409e87)
        (*Engine).ServeHTTP: engine.handleHTTPRequest(c)
/usr/local/go/src/net/http/server.go:2947 (0x2c875f)
        serverHandler.ServeHTTP: handler.ServeHTTP(rw, req)
/usr/local/go/src/net/http/server.go:1991 (0x2c4efb)
        (*conn).serve: serverHandler{c.server}.ServeHTTP(w, w.req)
/usr/local/go/src/runtime/asm_arm.s:831 (0x8008b)
        goexit: MOVW    R0, R0  // NOP

System:
Linux raspberrypi 5.15.84-v7l+ #1613 SMP Thu Jan 5 12:01:26 GMT 2023 armv7l GNU/Linux

If i change the ops variable frm uint64 to uint32 and all corresponding atomic methods to uint32 too, it works fine without panic:

type StateMachine struct {
	// ops is accessed atomically so we put it at the beginning of the struct to achieve 64 bit alignment
-	ops                    uint64
+	ops                    uint32
	stateConfig            map[State]*stateRepresentation
	triggerConfig          map[Trigger]triggerWithParameters
	stateAccessor          func(context.Context) (State, error)
	stateMutator           func(context.Context, State) error
	unhandledTriggerAction UnhandledTriggerActionFunc
	onTransitioningEvents  []TransitionFunc
	onTransitionedEvents   []TransitionFunc
	eventQueue             list.List
	firingMode             FiringMode
	firingMutex            sync.Mutex
}
@qmuntal
Copy link
Owner

qmuntal commented Feb 1, 2023

Thanks for reporting this bug. I thought I already fixed this issue in #31, wondering why is happening again. Which Go version are you using?

@kkettinger
Copy link
Author

I'm using the version go version go1.19.5 linux/arm.

@qmuntal
Copy link
Owner

qmuntal commented Feb 2, 2023

Could you check if this branch fixes your issue: https://github.com/qmuntal/stateless/tree/fix-ops

Thanks in advance.

@kkettinger
Copy link
Author

Just tested it on the raspberrypi, works without panic. Thanks a lot!

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