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 while calling format.formatType() by cgo struct #469

Open
Cylkal opened this issue Sep 6, 2021 · 2 comments
Open

panic while calling format.formatType() by cgo struct #469

Cylkal opened this issue Sep 6, 2021 · 2 comments

Comments

@Cylkal
Copy link

Cylkal commented Sep 6, 2021

go version go1.16.7 linux/amd64

when use matcher gomega.Equal it will use format.Message() to format actual and expected.
When format a struct type, the call chain is as follows:
Message -> Object -> formatValue ->formatStruct
when format struct contains a field which is a cgo struct, it may be panic:

Test Panicked
    runtime error: invalid memory address or nil pointer dereference
    /usr/local/go/src/runtime/panic.go:212

    Full Stack Trace
    reflect.Value.Uint(...)
    	/usr/local/go/src/reflect/value.go:1945
    github.com/onsi/gomega/format.formatValue(0x8e1840, 0x12d, 0x1a8, 0x5, 0x12d, 0x1a8)
    	/root/go/pkg/mod/github.com/onsi/[email protected]/format/format.go:292 +0x2ae
    github.com/onsi/gomega/format.formatValue(0x8d5de0, 0x7f0cf80020d0, 0x1b6, 0x5, 0x8d5de0, 0x7f0cf80020d0)
    	/root/go/pkg/mod/github.com/onsi/[email protected]/format/format.go:304 +0xad8
    github.com/onsi/gomega/format.formatStruct(0x955ac0, 0x7f0cf80020b0, 0x1b9, 0x4, 0x955ac0, 0x9)
    	/root/go/pkg/mod/github.com/onsi/[email protected]/format/format.go:402 +0x1de
    github.com/onsi/gomega/format.formatValue(0x955ac0, 0x7f0cf80020b0, 0x1b9, 0x4, 0x7f0cf80020b0, 0x1b9)
    	/root/go/pkg/mod/github.com/onsi/[email protected]/format/format.go:318 +0xc1d
    github.com/onsi/gomega/format.formatValue(0x8fa1a0, 0xc0000980d0, 0x1b6, 0x4, 0x8fa1a0, 0xc0000980d0)
    	/root/go/pkg/mod/github.com/onsi/[email protected]/format/format.go:304 +0xad8
    github.com/onsi/gomega/format.formatStruct(0x934480, 0xc0000980c0, 0x199, 0x3, 0x934480, 0xc000098000)
    	/root/go/pkg/mod/github.com/onsi/[email protected]/format/format.go:402 +0x1de
    github.com/onsi/gomega/format.formatValue(0x934480, 0xc0000980c0, 0x199, 0x3, 0xc0000980c0, 0x199)
    	/root/go/pkg/mod/github.com/onsi/[email protected]/format/format.go:318 +0xc1d
    github.com/onsi/gomega/format.formatValue(0x93dd60, 0xc0000ac410, 0x196, 0x3, 0x93dd60, 0xc0000ac410)
    	/root/go/pkg/mod/github.com/onsi/[email protected]/format/format.go:304 +0xad8
    github.com/onsi/gomega/format.formatStruct(0x955be0, 0xc0000ac3f0, 0x199, 0x2, 0x955be0, 0xc0000ac500)
    	/root/go/pkg/mod/github.com/onsi/[email protected]/format/format.go:402 +0x1de
    github.com/onsi/gomega/format.formatValue(0x955be0, 0xc0000ac3f0, 0x199, 0x2, 0xc0000ac3f0, 0x199)
    	/root/go/pkg/mod/github.com/onsi/[email protected]/format/format.go:318 +0xc1d
    github.com/onsi/gomega/format.formatValue(0x8fa200, 0xc000096390, 0x196, 0x2, 0x8fa200, 0xc000096390)
    	/root/go/pkg/mod/github.com/onsi/[email protected]/format/format.go:304 +0xad8
    github.com/onsi/gomega/format.formatStruct(0x960b80, 0xc000096360, 0x199, 0x1, 0x960b80, 0xc000096400)
    	/root/go/pkg/mod/github.com/onsi/[email protected]/format/format.go:402 +0x1de
    github.com/onsi/gomega/format.formatValue(0x960b80, 0xc000096360, 0x199, 0x1, 0xc000096360, 0x199)
    	/root/go/pkg/mod/github.com/onsi/[email protected]/format/format.go:318 +0xc1d
    github.com/onsi/gomega/format.formatValue(0x928260, 0xc000096360, 0x16, 0x1, 0x22, 0xa24ee0)
    	/root/go/pkg/mod/github.com/onsi/[email protected]/format/format.go:304 +0xad8
    github.com/onsi/gomega/format.Object(0x928260, 0xc000096360, 0x1, 0x0, 0x0)
    	/root/go/pkg/mod/github.com/onsi/[email protected]/format/format.go:215 +0x157
    github.com/onsi/gomega/format.Message(0x928260, 0xc000096360, 0x9855a8, 0x8, 0xc0001d30a0, 0x1, 0x1, 0xc0000963c0, 0xc00009e100)
    	/root/go/pkg/mod/github.com/onsi/[email protected]/format/format.go:86 +0x165
    github.com/onsi/gomega/matchers.(*EqualMatcher).FailureMessage(0xc0000a6530, 0x928260, 0xc000096360, 0x0, 0x0)
    	/root/go/pkg/mod/github.com/onsi/[email protected]/matchers/equal_matcher.go:37 +0xd0
    github.com/onsi/gomega/internal.(*Assertion).match(0xc00009e1c0, 0xa1d8b0, 0xc0000a6530, 0x1, 0x0, 0x0, 0x0, 0xc0000a6530)
    	/root/go/pkg/mod/github.com/onsi/[email protected]/internal/assertion.go:74 +0xfb
    github.com/onsi/gomega/internal.(*Assertion).To(0xc00009e1c0, 0xa1d8b0, 0xc0000a6530, 0x0, 0x0, 0x0, 0xc00009e1c0)
    	/root/go/pkg/mod/github.com/onsi/[email protected]/internal/assertion.go:38 +0xbe
    tscan/flow/servicescan.glob..func2.4.2()
    	/root/code/tscan-open/flow/servicescan/match_test.go:180 +0x1bc
    github.com/onsi/ginkgo/internal/leafnodes.(*runner).runSync(0xc00044a960, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ...)
    	/root/go/pkg/mod/github.com/onsi/[email protected]/internal/leafnodes/runner.go:113 +0xa3
    github.com/onsi/ginkgo/internal/leafnodes.(*runner).run(0xc00044a960, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ...)
    	/root/go/pkg/mod/github.com/onsi/[email protected]/internal/leafnodes/runner.go:64 +0x15c
    github.com/onsi/ginkgo/internal/leafnodes.(*ItNode).Run(0xc000464640, 0xa166e0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ...)
    	/root/go/pkg/mod/github.com/onsi/[email protected]/internal/leafnodes/it_node.go:26 +0x87
    github.com/onsi/ginkgo/internal/spec.(*Spec).runSample(0xc0002f31d0, 0x0, 0xa166e0, 0xc00039d280)
    	/root/go/pkg/mod/github.com/onsi/[email protected]/internal/spec/spec.go:215 +0x72f
    github.com/onsi/ginkgo/internal/spec.(*Spec).Run(0xc0002f31d0, 0xa166e0, 0xc00039d280)
    	/root/go/pkg/mod/github.com/onsi/[email protected]/internal/spec/spec.go:138 +0xf2
    github.com/onsi/ginkgo/internal/specrunner.(*SpecRunner).runSpec(0xc000323080, 0xc0002f31d0, 0x1)
    	/root/go/pkg/mod/github.com/onsi/[email protected]/internal/specrunner/spec_runner.go:200 +0x111
    github.com/onsi/ginkgo/internal/specrunner.(*SpecRunner).runSpecs(0xc000323080, 0x1)
    	/root/go/pkg/mod/github.com/onsi/[email protected]/internal/specrunner/spec_runner.go:170 +0x147
    github.com/onsi/ginkgo/internal/specrunner.(*SpecRunner).Run(0xc000323080, 0xc0003bd4f8)
    	/root/go/pkg/mod/github.com/onsi/[email protected]/internal/specrunner/spec_runner.go:66 +0x117
    github.com/onsi/ginkgo/internal/suite.(*Suite).Run(0xc0003dad20, 0x7f0d0ee6b9c0, 0xc0001b1080, 0x98b39b, 0x11, 0xc0003fa1c0, 0x1, 0x1, 0xa1fc18, 0xc00039d280, ...)
    	/root/go/pkg/mod/github.com/onsi/[email protected]/internal/suite/suite.go:79 +0x546
    github.com/onsi/ginkgo.runSpecsWithCustomReporters(0xa16e00, 0xc0001b1080, 0x98b39b, 0x11, 0xc000052f28, 0x1, 0x1, 0x0)
    	/root/go/pkg/mod/github.com/onsi/[email protected]/ginkgo_dsl.go:238 +0x218
    github.com/onsi/ginkgo.RunSpecs(0xa16e00, 0xc0001b1080, 0x98b39b, 0x11, 0x8cc9715da2939f)
    	/root/go/pkg/mod/github.com/onsi/[email protected]/ginkgo_dsl.go:213 +0xa7
    tscan/flow/servicescan_test.TestServicescan(0xc0001b1080)
    	/root/code/tscan-open/flow/servicescan/servicescan_suite_test.go:12 +0x7f
    testing.tRunner(0xc0001b1080, 0x9ac008)
    	/usr/local/go/src/testing/testing.go:1193 +0xef
    created by testing.(*T).Run
    	/usr/local/go/src/testing/testing.go:1238 +0x2b3
------------------------------

the cgo struct like:

/*
#cgo CFLAGS: -I.
#cgo LDFLAGS: -L. -lpcre
#include <pcre.h>
#include <string.h>
*/
import "C"

type pcreExtra C.struct_pcre_extra

where pcre_extra define:

typedef struct pcre_extra {
  unsigned long int flags;        /* Bits for which fields are set */
  void *study_data;               /* Opaque data from pcre_study() */
  unsigned long int match_limit;  /* Maximum number of calls to match() */
  void *callout_data;             /* Data passed back in callouts */
  const unsigned char *tables;    /* Pointer to character tables */
  unsigned long int match_limit_recursion; /* Max recursive calls to match() */
  unsigned char **mark;           /* For passing back a mark pointer */
  void *executable_jit;           /* Contains a pointer to a compiled jit code */
} pcre_extra;

use fmt, it print like:

{flags:65 study_data:0x7fd858002340 match_limit:140567166067728 callout_data:0x7fd89569a13d tables:0x12d match_limit_recursion:140567166067544 mark:0x7fd89569a146 executable_jit:0x7fd8580026a0}

and panic occurs when visit field match_limit_recursion by call reflect.Value.Uint().

Could you avoid format cgo struct, or other method like add a new format methd not format unexported field?

@onsi
Copy link
Owner

onsi commented Sep 10, 2021

hey @Cylkal - sorry I haven't been able to get to this sooner. I'll have to carve out some time to take a deeper look at it. For now, if it helps you get unstuck, you could implement the GomegaStringer interface to control how your object's output is formatted and possibly avoid the panic?

@Cylkal
Copy link
Author

Cylkal commented Sep 22, 2021

hey @Cylkal - sorry I haven't been able to get to this sooner. I'll have to carve out some time to take a deeper look at it. For now, if it helps you get unstuck, you could implement the GomegaStringer interface to control how your object's output is formatted and possibly avoid the panic?

yeah, this may be one way.

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

No branches or pull requests

2 participants