ibmruntimes / go-recordio

Record I/O in Go: a Go module for record I/O in VSAM databases directly from Go (no need for cgo)
BSD 3-Clause "New" or "Revised" License
8 stars 5 forks source link

SIGILL: illegal instruction #6

Closed JirkaAichler closed 1 year ago

JirkaAichler commented 2 years ago

I am trying to read data sets with the following code:

func ReadDataSet(name string) string {
    message := ""
    dsn := fmt.Sprintf("//'%s'", name)
    fh := zosrecordio.Fopen(dsn, "rb, lrecl=80, blksize=80, recfm=fb, type=record")
    defer fh.Fclose()

    var line [80]byte
    bytes := fh.Fread(line[:])
    for bytes > 0 {
        utils.EtoA(line[:bytes])
        message = message + "\n" + string(line[:bytes])
        bytes = fh.Fread(line[:])
    }

    if fh.Ferror() != nil {
        utils.Perror()
    }

    return message
}

It works fine for a single access. When I call this function in parallel, it crashes after a while. Parallel calls are done by REST server.

Error:

...
[GIN] 2022/08/30 - 09:15:03 | 200 |   24.808218ms |    10.57.17.182 | GET      "/dataset/aicji01.jcl(if)"
[GIN] 2022/08/30 - 09:15:03 | 200 |   26.975954ms |    10.57.17.182 | GET      "/dataset/aicji01.jcl(if)"
SIGILL: illegal instruction
PC=0x3bd65e96 m=13 sigcode=11
instruction bytes @ 0x3bd65e8e
 0xe3 0xf0 0xf1 0x60 0x0 0x17 0xd 0xef 0x94 0xef 0xc3 0xcc 0xe3 0x10 0x49 0x78 0x0 0x16 0xb9 0x2 0x0 0x11 0x47 0x80 0x81 0x58 0xe3 0xb0 0x81 0xb6 0x0 0x4 0x47 0xf0 0x81 0x5c 0xb9 0x82 0x0 0xbb 0x91 0x80 0xc3 0xcc 0x47 0xe0 0x81 0xa2 0xd5 0x3 0x49 0x20 0x81 0xce 0x47 0xb0 0x81 0xa2 0x94 0x7f 0xc3 0xcc 0x96 0x10
r0   0x57       r1   0x50810ebba8
r2   0x0        r3   0x3c5b92c0
r4   0x50810eb280       r5   0x50810ed090
r6   0x3bd65e96 r7   0x3bd65ef8
r8   0x3bd65d5a r9   0x50810ed090
r10  0x12345678 r11  0x50810ed090
r12  0x50812fec60       r13  0x50810ebb10
r14  0x3bd65e96 r15  0x1300
pc   0x3bd65e96 link 0x3bd65e96
ar0  0x0        ar1  0x0
ar2  0xffffffff ar3  0xffffffff
ar4  0xffffffff ar5  0xffffffff
ar6  0xffffffff ar7  0xffffffff
ar8  0xffffffff ar9  0xffffffff
ar10 0xffffffff ar11 0xffffffff
ar12 0x0        ar13 0x0
ar14 0x0        ar15 0x0

goroutine 2392 [running]:
runtime: unknown pc 0x3bd65e96
stack: frame={sp:0x1300, fp:0x0} stack=[0xc00158f000,0xc001590000)

runtime: unknown pc 0x3bd65e96
stack: frame={sp:0x1300, fp:0x0} stack=[0xc00158f000,0xc001590000)

...

goroutine 2403 [runnable]:
github.com/ibmruntimes/go-recordio.RecordStream.Fread({0x3c61d0d0}, {0xc003e6b850, 0x50, 0x50})
        /a/aicji01/go/pkg/mod/github.com/ibmruntimes/go-recordio@v0.0.0-20220525174743-c08c00a5cb44/record.go:75 +0xb6
MF_Rest_API/src/internal.ReadDataSet({0xc003d08109, 0xf})
        /a/aicji01/go/rest/src/internal/dataset.go:18 +0x118
MF_Rest_API/src/controllers.Dataset.func1(0xc002020400)
        /a/aicji01/go/rest/src/controllers/dataset.go:12 +0x5c
github.com/gin-gonic/gin.(*Context).Next(...)
        /a/aicji01/go/pkg/mod/github.com/gin-gonic/gin@v1.8.1/context.go:173
github.com/gin-gonic/gin.CustomRecoveryWithWriter.func1(0xc002020400)
        /a/aicji01/go/pkg/mod/github.com/gin-gonic/gin@v1.8.1/recovery.go:101 +0x9c
github.com/gin-gonic/gin.(*Context).Next(...)
        /a/aicji01/go/pkg/mod/github.com/gin-gonic/gin@v1.8.1/context.go:173
github.com/gin-gonic/gin.LoggerWithConfig.func1(0xc002020400)
        /a/aicji01/go/pkg/mod/github.com/gin-gonic/gin@v1.8.1/logger.go:240 +0x10e
github.com/gin-gonic/gin.(*Context).Next(...)
        /a/aicji01/go/pkg/mod/github.com/gin-gonic/gin@v1.8.1/context.go:173
github.com/gin-gonic/gin.(*Engine).handleHTTPRequest(0xc0020e0820, 0xc002020400)
        /a/aicji01/go/pkg/mod/github.com/gin-gonic/gin@v1.8.1/gin.go:616 +0x68c
github.com/gin-gonic/gin.(*Engine).ServeHTTP(0xc0020e0820, {0x3b920220, 0xc00215c000}, 0xc001f54300)
        /a/aicji01/go/pkg/mod/github.com/gin-gonic/gin@v1.8.1/gin.go:572 +0x25c
net/http.serverHandler.ServeHTTP({0xc00203b2c0}, {0x3b920220, 0xc00215c000}, 0xc001f54300)
        /a/aicji01/go/usr/lpp/IBM/cvg/v1r18/go/src/net/http/server.go:2916 +0x4ca
net/http.initALPNRequest.ServeHTTP({{0x3b920948, 0xc003da4030}, 0xc002161380, {0xc00203b2c0}}, {0x3b920220, 0xc00215c000}, 0xc001f54300)
        /a/aicji01/go/usr/lpp/IBM/cvg/v1r18/go/src/net/http/server.go:3523 +0x1e2
net/http.(*http2serverConn).runHandler(0xc003fa4180, 0xc00215c000, 0xc001f54300, 0xc001ea0120)
        /a/aicji01/go/usr/lpp/IBM/cvg/v1r18/go/src/net/http/h2_bundle.go:5903 +0x8c
created by net/http.(*http2serverConn).processHeaders
        /a/aicji01/go/usr/lpp/IBM/cvg/v1r18/go/src/net/http/h2_bundle.go:5633 +0x814

signal: killed

Any idea how to fix it?

ccw-1 commented 1 year ago

The instruction stream does not look like Go generated code, I think the underlying LE service for record I/O is not thread-safe. We might have to attach a mutex to the file handle. For now, you can use a global mutex around these calls.

JirkaAichler commented 1 year ago

Thank you for your answer. I would suggest mentioning this information inside a doc that would warn inexperienced Go programmers like me :-)