yeqown / go-qrcode

To help gophers generate QR Codes with customized styles, such as color, block size, block shape, and icon.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[BUG] DATA RACE Issue When Calling qrcode.New from Multiple Goroutines

mnrtks opened this issue · comments

Describe the bug

I am experiencing a data race issue when invoking qrcode.New concurrently from multiple goroutines.
I have confirmed that this issue occurs in version v2.2.2.

To Reproduce

package main

import (
	"fmt"
	"sync"

	"github.com/yeqown/go-qrcode/v2"
)

func main() {
	var wg sync.WaitGroup

	for i := 0; i < 10; i++ {
		wg.Add(1)

		u := fmt.Sprintf("http://example.com/dummy?id=%04d", i)
		go func(u string) {
			defer wg.Done()
			_, err := qrcode.New(u)
			if err != nil {
				panic(err)
			}
		}(u)
	}

	wg.Wait()
}
go run -race ./
go run -race ./
==================
WARNING: DATA RACE
Read at 0x00c000000168 by goroutine 13:
  github.com/yeqown/go-qrcode/v2.loadAlignmentPatternLoc()
      pkg/mod/github.com/yeqown/go-qrcode/v2@v2.2.2/version.go:371 +0x60
  github.com/yeqown/go-qrcode/v2.(*QRCode).prefillMatrix()
      pkg/mod/github.com/yeqown/go-qrcode/v2@v2.2.2/qrcode.go:335 +0x380
  github.com/yeqown/go-qrcode/v2.(*QRCode).init()
      pkg/mod/github.com/yeqown/go-qrcode/v2@v2.2.2/qrcode.go:124 +0x5dc
  github.com/yeqown/go-qrcode/v2.build()
      pkg/mod/github.com/yeqown/go-qrcode/v2@v2.2.2/qrcode.go:42 +0x1d8
  github.com/yeqown/go-qrcode/v2.New()
      pkg/mod/github.com/yeqown/go-qrcode/v2@v2.2.2/qrcode.go:16 +0x7c
  main.main.func1()
      work/qrcodedatarace/main.go:19 +0x78
  main.main.gowrap1()
      work/qrcodedatarace/main.go:23 +0x54

Previous write at 0x00c000000168 by goroutine 7:
  github.com/yeqown/go-qrcode/v2.loadAlignmentPatternLoc()
      pkg/mod/github.com/yeqown/go-qrcode/v2@v2.2.2/version.go:389 +0x1c0
  github.com/yeqown/go-qrcode/v2.(*QRCode).prefillMatrix()
      pkg/mod/github.com/yeqown/go-qrcode/v2@v2.2.2/qrcode.go:335 +0x380
  github.com/yeqown/go-qrcode/v2.(*QRCode).init()
      pkg/mod/github.com/yeqown/go-qrcode/v2@v2.2.2/qrcode.go:124 +0x5dc
  github.com/yeqown/go-qrcode/v2.build()
      pkg/mod/github.com/yeqown/go-qrcode/v2@v2.2.2/qrcode.go:42 +0x1d8
  github.com/yeqown/go-qrcode/v2.New()
      pkg/mod/github.com/yeqown/go-qrcode/v2@v2.2.2/qrcode.go:16 +0x7c
  main.main.func1()
      work/qrcodedatarace/main.go:19 +0x78
  main.main.gowrap1()
      work/qrcodedatarace/main.go:23 +0x54

Goroutine 13 (running) created at:
  main.main()
      work/qrcodedatarace/main.go:17 +0x50

Goroutine 7 (running) created at:
  main.main()
      work/qrcodedatarace/main.go:17 +0x50
==================
==================
WARNING: DATA RACE
Read at 0x00c00000ed10 by goroutine 12:
  github.com/yeqown/go-qrcode/v2.(*QRCode).prefillMatrix()
      pkg/mod/github.com/yeqown/go-qrcode/v2@v2.2.2/qrcode.go:335 +0x538
  github.com/yeqown/go-qrcode/v2.(*QRCode).init()
      pkg/mod/github.com/yeqown/go-qrcode/v2@v2.2.2/qrcode.go:124 +0x5dc
  github.com/yeqown/go-qrcode/v2.build()
      pkg/mod/github.com/yeqown/go-qrcode/v2@v2.2.2/qrcode.go:42 +0x1d8
  github.com/yeqown/go-qrcode/v2.New()
      pkg/mod/github.com/yeqown/go-qrcode/v2@v2.2.2/qrcode.go:16 +0x7c
  main.main.func1()
      work/qrcodedatarace/main.go:19 +0x78
  main.main.gowrap1()
      work/qrcodedatarace/main.go:23 +0x54

Previous write at 0x00c00000ed10 by goroutine 7:
  github.com/yeqown/go-qrcode/v2.loadAlignmentPatternLoc()
      pkg/mod/github.com/yeqown/go-qrcode/v2@v2.2.2/version.go:386 +0x33c
  github.com/yeqown/go-qrcode/v2.(*QRCode).prefillMatrix()
      pkg/mod/github.com/yeqown/go-qrcode/v2@v2.2.2/qrcode.go:335 +0x380
  github.com/yeqown/go-qrcode/v2.(*QRCode).init()
      pkg/mod/github.com/yeqown/go-qrcode/v2@v2.2.2/qrcode.go:124 +0x5dc
  github.com/yeqown/go-qrcode/v2.build()
      pkg/mod/github.com/yeqown/go-qrcode/v2@v2.2.2/qrcode.go:42 +0x1d8
  github.com/yeqown/go-qrcode/v2.New()
      pkg/mod/github.com/yeqown/go-qrcode/v2@v2.2.2/qrcode.go:16 +0x7c
  main.main.func1()
      work/qrcodedatarace/main.go:19 +0x78
  main.main.gowrap1()
      work/qrcodedatarace/main.go:23 +0x54

Goroutine 12 (running) created at:
  main.main()
      work/qrcodedatarace/main.go:17 +0x50

Goroutine 7 (running) created at:
  main.main()
      work/qrcodedatarace/main.go:17 +0x50
==================
==================
WARNING: DATA RACE
Read at 0x00c00009c180 by goroutine 8:
  runtime.mapaccess1_fast64()
      .local/share/mise/installs/go/1.22.1/go/src/runtime/map_fast64.go:13 +0x1bc
  github.com/yeqown/go-qrcode/v2.loadAlignmentPatternLoc()
      pkg/mod/github.com/yeqown/go-qrcode/v2@v2.2.2/version.go:371 +0x54
  github.com/yeqown/go-qrcode/v2.(*QRCode).prefillMatrix()
      pkg/mod/github.com/yeqown/go-qrcode/v2@v2.2.2/qrcode.go:335 +0x380
  github.com/yeqown/go-qrcode/v2.(*QRCode).init()
      pkg/mod/github.com/yeqown/go-qrcode/v2@v2.2.2/qrcode.go:124 +0x5dc
  github.com/yeqown/go-qrcode/v2.build()
      pkg/mod/github.com/yeqown/go-qrcode/v2@v2.2.2/qrcode.go:42 +0x1d8
  github.com/yeqown/go-qrcode/v2.New()
      pkg/mod/github.com/yeqown/go-qrcode/v2@v2.2.2/qrcode.go:16 +0x7c
  main.main.func1()
      work/qrcodedatarace/main.go:19 +0x78
  main.main.gowrap1()
      work/qrcodedatarace/main.go:23 +0x54

Previous write at 0x00c00009c180 by goroutine 7:
  runtime.mapaccess2_fast64()
      .local/share/mise/installs/go/1.22.1/go/src/runtime/map_fast64.go:53 +0x1cc
  github.com/yeqown/go-qrcode/v2.loadAlignmentPatternLoc()
      pkg/mod/github.com/yeqown/go-qrcode/v2@v2.2.2/version.go:389 +0x1b4
  github.com/yeqown/go-qrcode/v2.(*QRCode).prefillMatrix()
      pkg/mod/github.com/yeqown/go-qrcode/v2@v2.2.2/qrcode.go:335 +0x380
  github.com/yeqown/go-qrcode/v2.(*QRCode).init()
      pkg/mod/github.com/yeqown/go-qrcode/v2@v2.2.2/qrcode.go:124 +0x5dc
  github.com/yeqown/go-qrcode/v2.build()
      pkg/mod/github.com/yeqown/go-qrcode/v2@v2.2.2/qrcode.go:42 +0x1d8
  github.com/yeqown/go-qrcode/v2.New()
      pkg/mod/github.com/yeqown/go-qrcode/v2@v2.2.2/qrcode.go:16 +0x7c
  main.main.func1()
      work/qrcodedatarace/main.go:19 +0x78
  main.main.gowrap1()
      work/qrcodedatarace/main.go:23 +0x54

Goroutine 8 (running) created at:
  main.main()
      work/qrcodedatarace/main.go:17 +0x50

Goroutine 7 (running) created at:
  main.main()
      work/qrcodedatarace/main.go:17 +0x50
==================
Found 3 data race(s)
exit status 66

Expected behavior

I expect that no data races occur.

Screenshots

Additional context

@mnrtks could you make a PR to fix this? The data race has pointed to the root cause as the loadAlignmentPatternLoc function.

@yeqown
I have created a pull request (#104) to fix the data race issue in the loadAlignmentPatternLoc function.
Please review it.