FAQ
I strange cgo panic in Go1.6beta1.

https://github.com/pebbe/zmq4/issues/68

Is this a bug in Go beta?

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Search Discussions

  • Pieter Droogendijk at Jan 13, 2016 at 3:07 pm
    There are some rules on what's allowed to be passed between C and Go, and
    the runtime enforces them (or at least as many as possible) now.

    https://github.com/golang/go/issues/12416

    On Wednesday, January 13, 2016 at 2:41:45 PM UTC+1, Peter Kleiweg wrote:

    I strange cgo panic in Go1.6beta1.

    https://github.com/pebbe/zmq4/issues/68

    Is this a bug in Go beta?
    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Ian Lance Taylor at Jan 13, 2016 at 3:11 pm
    The final version of the pointer passing rules is written down at
    https://tip.golang.org/cmd/cgo/#hdr-Passing_pointers .

    This is also mentioned in the Go 1.6 release notes at
    https://tip.golang.org/doc/go1.6.html .

    Ian
    On Wed, Jan 13, 2016 at 7:06 AM, Pieter Droogendijk wrote:
    There are some rules on what's allowed to be passed between C and Go, and
    the runtime enforces them (or at least as many as possible) now.

    https://github.com/golang/go/issues/12416

    On Wednesday, January 13, 2016 at 2:41:45 PM UTC+1, Peter Kleiweg wrote:

    I strange cgo panic in Go1.6beta1.

    https://github.com/pebbe/zmq4/issues/68

    Is this a bug in Go beta?
    --
    You received this message because you are subscribed to the Google Groups
    "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an
    email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Peter Kleiweg at Jan 13, 2016 at 4:52 pm
    So, why can I pass a pointer to some []byte, and not a pointer to some other []byte? How can there by Go pointers in a []byte?

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Konstantin Khomoutov at Jan 13, 2016 at 5:13 pm

    On Wed, 13 Jan 2016 08:52:44 -0800 (PST) Peter Kleiweg wrote:

    So, why can I pass a pointer to some []byte, and not a pointer to
    some other []byte? How can there by Go pointers in a []byte?
    I think the discussion has been side-tracked a bit.
    What happens is supposedly just a bug in the Go runtime and is not
    related to the rules of calling C code via Go.

    Any set of rules (such as the lagugage spec) imply the runtime and the
    program are bug-free; if they are not, certain bets are off.

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Ian Lance Taylor at Jan 13, 2016 at 6:35 pm

    On Wed, Jan 13, 2016 at 8:52 AM, Peter Kleiweg wrote:
    So, why can I pass a pointer to some []byte, and not a pointer to some other []byte? How can there by Go pointers in a []byte?
    There are no pointers in a []byte. But the details matter. For
    example, if you have a `struct { ptr *int; s []byte }` and you later
    write code like `f(&s[0])` and then in `f(p *byte)` you write
    `C.fn(p)` then the fact that you are passing the address of an element
    in a []byte has been lost. The cgo checking is conservative. It sees
    that the pointer being passed to C points into a block of memory that
    contains a Go pointer (the ptr field of the struct) and it gives an
    error.

    I don't think that is what is happening in issue #13934, but it is an
    example of why you can get an error in some cases but not others.

    Ian

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Peter Kleiweg at Jan 13, 2016 at 8:00 pm

    Ian Lance Taylor schreef op 13 januari 2016 19:35:08 CET:
    On Wed, Jan 13, 2016 at 8:52 AM, Peter Kleiweg wrote:
    So, why can I pass a pointer to some []byte, and not a pointer to
    some other []byte? How can there by Go pointers in a []byte?

    There are no pointers in a []byte. But the details matter. For
    example, if you have a `struct { ptr *int; s []byte }` and you later
    write code like `f(&s[0])` and then in `f(p *byte)` you write
    `C.fn(p)` then the fact that you are passing the address of an element
    in a []byte has been lost. The cgo checking is conservative. It sees
    that the pointer being passed to C points into a block of memory that
    contains a Go pointer (the ptr field of the struct) and it gives an
    error.
    If I read this correctly, any call to C with a pointer can cause a panic, unless there are no pointers to any Go variable in all of your program.

    I trust this change will be reversed before the official release of version 1.6, or a lot of software will stop working.


    --
    Peter Kleiweg
    http://pkleiweg.home.xs4all.nl

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Ian Lance Taylor at Jan 13, 2016 at 8:31 pm

    On Wed, Jan 13, 2016 at 12:00 PM, Peter Kleiweg wrote:
    Ian Lance Taylor <iant@golang.org> schreef op 13 januari 2016 19:35:08 CET:
    On Wed, Jan 13, 2016 at 8:52 AM, Peter Kleiweg <pkleiweg@xs4all.nl>
    wrote:
    So, why can I pass a pointer to some []byte, and not a pointer to
    some other []byte? How can there by Go pointers in a []byte?

    There are no pointers in a []byte. But the details matter. For
    example, if you have a `struct { ptr *int; s []byte }` and you later
    write code like `f(&s[0])` and then in `f(p *byte)` you write
    `C.fn(p)` then the fact that you are passing the address of an element
    in a []byte has been lost. The cgo checking is conservative. It sees
    that the pointer being passed to C points into a block of memory that
    contains a Go pointer (the ptr field of the struct) and it gives an
    error.
    If I read this correctly, any call to C with a pointer can cause a panic, unless there are no pointers to any Go variable in all of your program.
    I'm not sure how you came up with that reading, but it is incorrect.

    I trust this change will be reversed before the official release of version 1.6, or a lot of software will stop working.
    I hope that people will try out the beta releases to see what happens.
    This change was discussed on the golang-dev mailing list and over at
    https://golang.org/issue/12416 . Plenty of people have had a chance
    to comment on it.

    Note that issue 13934, which I think is the problem you were initially
    reporting, has been closed as working on tip.

    Ian

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Peter Kleiweg at Jan 13, 2016 at 10:00 pm

    Op woensdag 13 januari 2016 21:32:08 UTC+1 schreef Ian Lance Taylor:

    On Wed, Jan 13, 2016 at 12:00 PM, Peter Kleiweg <pkle...@xs4all.nl
    <javascript:>> wrote:
    Ian Lance Taylor <ia...@golang.org <javascript:>> schreef op 13 januari
    2016 19:35:08 CET:
    On Wed, Jan 13, 2016 at 8:52 AM, Peter Kleiweg <pkle...@xs4all.nl
    <javascript:>>
    wrote:
    So, why can I pass a pointer to some []byte, and not a pointer to
    some other []byte? How can there by Go pointers in a []byte?

    There are no pointers in a []byte. But the details matter. For
    example, if you have a `struct { ptr *int; s []byte }` and you later
    write code like `f(&s[0])` and then in `f(p *byte)` you write
    `C.fn(p)` then the fact that you are passing the address of an element
    in a []byte has been lost. The cgo checking is conservative. It sees
    that the pointer being passed to C points into a block of memory that
    contains a Go pointer (the ptr field of the struct) and it gives an
    error.
    If I read this correctly, any call to C with a pointer can cause a
    panic, unless there are no pointers to any Go variable in all of your
    program.

    I'm not sure how you came up with that reading, but it is incorrect.
    It is how I understand what you wrote. You can't pass a pointer to C that
    is in the same memory block as something else that points to something that
    isn't allowed. But I have no idea how to prevent a pointer ending up in the
    same memory block as something else.


    Note that issue 13934, which I think is the problem you were initially
    reporting, has been closed as working on tip.
    I just tested. No panic.

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Ian Lance Taylor at Jan 13, 2016 at 10:48 pm

    On Wed, Jan 13, 2016 at 2:00 PM, Peter Kleiweg wrote:
    Op woensdag 13 januari 2016 21:32:08 UTC+1 schreef Ian Lance Taylor:
    On Wed, Jan 13, 2016 at 12:00 PM, Peter Kleiweg wrote:

    Ian Lance Taylor <ia...@golang.org> schreef op 13 januari 2016 19:35:08
    CET:
    On Wed, Jan 13, 2016 at 8:52 AM, Peter Kleiweg <pkle...@xs4all.nl>
    wrote:
    So, why can I pass a pointer to some []byte, and not a pointer to
    some other []byte? How can there by Go pointers in a []byte?

    There are no pointers in a []byte. But the details matter. For
    example, if you have a `struct { ptr *int; s []byte }` and you later
    write code like `f(&s[0])` and then in `f(p *byte)` you write
    `C.fn(p)` then the fact that you are passing the address of an element
    in a []byte has been lost. The cgo checking is conservative. It sees
    that the pointer being passed to C points into a block of memory that
    contains a Go pointer (the ptr field of the struct) and it gives an
    error.
    If I read this correctly, any call to C with a pointer can cause a
    panic, unless there are no pointers to any Go variable in all of your
    program.
    I'm not sure how you came up with that reading, but it is incorrect.

    It is how I understand what you wrote. You can't pass a pointer to C that is
    in the same memory block as something else that points to something that
    isn't allowed. But I have no idea how to prevent a pointer ending up in the
    same memory block as something else.
    A memory block here is a single allocation done by the Go program. If
    you write new(**byte) you have a memory block that contains exactly
    one pointer.

    Ian

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Pieter Droogendijk at Jan 13, 2016 at 3:11 pm
    Or better yet, the design
    doc: https://github.com/golang/proposal/blob/master/design/12416-cgo-pointers.md
    On Wednesday, January 13, 2016 at 2:41:45 PM UTC+1, Peter Kleiweg wrote:

    I strange cgo panic in Go1.6beta1.

    https://github.com/pebbe/zmq4/issues/68

    Is this a bug in Go beta?
    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Tamás Gulácsi at Feb 4, 2016 at 10:45 am
    2016. január 13., szerda 14:41:45 UTC+1 időpontban Peter Kleiweg a
    következőt írta:
    I strange cgo panic in Go1.6beta1.

    https://github.com/pebbe/zmq4/issues/68

    Is this a bug in Go beta?
    I have another similar question:

    How does we have to rewrite gopkg.in/rana/ora.v3 to be able to use it with
    go1.6 ?

    The following code raises the aforementioned panic:

    // Stmt represents an Oracle statement.
    type Stmt struct {
         id uint64
         cfg StmtCfg
         mu sync.Mutex
         ses *Ses
         ocistmt *C.OCIStmt
         stmtType C.ub4
         sql string
         gcts []GoColumnType
         bnds []bnd
         hasPtrBind bool

         openRsets *rsetList
    }

    // attr gets an attribute from the statement handle. No locking occurs.
    func (stmt *Stmt) attr(attrup unsafe.Pointer, attrSize C.ub4, attrType
    C.ub4) error {
         r := C.OCIAttrGet(
             unsafe.Pointer(stmt.ocistmt), //const void *trgthndlp,
             C.OCI_HTYPE_STMT, //ub4 cfgtrghndltyp,
             attrup, //void *attributep,
             &attrSize, //ub4 *sizep,
             attrType, //ub4 attrtype,
             stmt.ses.srv.env.ocierr) //OCIError *errhp );
         if r == C.OCI_ERROR {
             return stmt.ses.srv.env.ociError()
         }
         return nil
                                                }


    and stmt.ses.srv.env.ocierr is of type *C.OCIError.


    --- FAIL: TestBindDefine_OraBfile_bfile_session (0.00s)
             z_oracle_test.go:789: Ses.Prep.func1 recovered: runtime error: cgo
    argument has Go pointer to Go pointer
                     goroutine 19 [running]:
                     gopkg.in/rana/ora%2ev3.errR(0xc8200537e8, 0x1, 0x1, 0x0,
    0x0)
                             /home/tgulacsi/src/gopkg.in/rana/ora.v3/util.go:214
    +0x97
                     gopkg.in/rana/ora%2ev3.(*Ses).Prep.func1(0xc820053c90)
                             /home/tgulacsi/src/gopkg.in/rana/ora.v3/ses.go:256
    +0xa2
                     gopkg.in/rana/ora%2ev3._cgoCheckPointer0(0x6c9260,
    0xc8200aa0e8, 0x0, 0x0, 0x0, 0x2bf8808)
                             ??:0 +0x4d
                     gopkg.in/rana/ora%2ev3.(*Stmt).attr(0xc8200aa000,
    0xc8200aa0e8, 0x1800000004, 0x0, 0x0)

    /home/tgulacsi/src/gopkg.in/rana/ora.v3/stmt.go:1154 +0xc4
                     gopkg.in/rana/ora%2ev3.(*Ses).Prep(0xc8200a6000,
    0xc8200a8360, 0x25, 0x0, 0x0, 0x0, 0xc8200aa000, 0x0, 0x0)
                             /home/tgulacsi/src/gopkg.in/rana/ora.v3/ses.go:302
    +0x904
                     gopkg.in/rana/ora%2ev3_test.createTable(0x1, 0x78a480, 0xe,
    0xc8200a6000, 0x0, 0x0, 0x0, 0x0)

    /home/tgulacsi/src/gopkg.in/rana/ora.v3/z_oracle_test.go:730 +0x2be
                     gopkg.in/rana/ora%2ev3_test.testBindDefine(0x74a3c0,
    0xc8200a8330, 0x78a480, 0xe, 0xc8200da000, 0x0, 0x0, 0x0, 0x0)

    /home/tgulacsi/src/gopkg.in/rana/ora.v3/z_oracle_test.go:204 +0x94

    gopkg.in/rana/ora%2ev3_test.TestBindDefine_OraBfile_bfile_session(0xc8200da000)

    /home/tgulacsi/src/gopkg.in/rana/ora.v3/z_bfile_session_test.go:20 +0x10c
                     testing.tRunner(0xc8200da000, 0xb2e4d8)
                             /usr/local/go/src/testing/testing.go:473 +0x98
                     created by testing.RunTests
                             /usr/local/go/src/testing/testing.go:582 +0x892
                     : goroutine 19 [running]:
                     gopkg.in/rana/ora%2ev3_test.testErr(0x7f259f5aa028,
    0xc82009c940, 0xc8200da000, 0x0, 0x0, 0x0)

    /home/tgulacsi/src/gopkg.in/rana/ora.v3/z_oracle_test.go:789 +0x50
                     gopkg.in/rana/ora%2ev3_test.testBindDefine(0x74a3c0,
    0xc8200a8330, 0x78a480, 0xe, 0xc8200da000, 0x0, 0x0, 0x0, 0x0)

    /home/tgulacsi/src/gopkg.in/rana/ora.v3/z_oracle_test.go:205 +0xf4

    gopkg.in/rana/ora%2ev3_test.TestBindDefine_OraBfile_bfile_session(0xc8200da000)

    /home/tgulacsi/src/gopkg.in/rana/ora.v3/z_bfile_session_test.go:20 +0x10c
                     testing.tRunner(0xc8200da000, 0xb2e4d8)
                             /usr/local/go/src/testing/testing.go:473 +0x98
                     created by testing.RunTests
                             /usr/local/go/src/testing/testing.go:582 +0x892



    Which of these arguments is the "Go pointer to Go pointer" ?

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Konstantin Khomoutov at Feb 4, 2016 at 2:21 pm

    On Thu, 4 Feb 2016 02:45:47 -0800 (PST) Tamás Gulácsi wrote: [...]
    How does we have to rewrite gopkg.in/rana/ora.v3 to be able to use it
    with go1.6 ?

    The following code raises the aforementioned panic:

    // Stmt represents an Oracle statement.
    type Stmt struct {
    id uint64
    cfg StmtCfg
    mu sync.Mutex
    ses *Ses
    ocistmt *C.OCIStmt
    stmtType C.ub4
    sql string
    gcts []GoColumnType
    bnds []bnd
    hasPtrBind bool

    openRsets *rsetList
    }

    // attr gets an attribute from the statement handle. No locking
    occurs. func (stmt *Stmt) attr(attrup unsafe.Pointer, attrSize C.ub4,
    attrType C.ub4) error {
    r := C.OCIAttrGet(
    unsafe.Pointer(stmt.ocistmt), //const void *trgthndlp,
    C.OCI_HTYPE_STMT, //ub4 cfgtrghndltyp,
    attrup, //void *attributep,
    &attrSize, //ub4 *sizep,
    attrType, //ub4 attrtype,
    stmt.ses.srv.env.ocierr) //OCIError *errhp );
    if r == C.OCI_ERROR {
    return stmt.ses.srv.env.ociError()
    }
    return
    nil }


    and stmt.ses.srv.env.ocierr is of type *C.OCIError.


    --- FAIL: TestBindDefine_OraBfile_bfile_session (0.00s)
    z_oracle_test.go:789: Ses.Prep.func1 recovered: runtime
    error: cgo argument has Go pointer to Go pointer
    goroutine 19 [running]:
    gopkg.in/rana/ora%2ev3.errR(0xc8200537e8, 0x1, 0x1,
    0x0, 0x0)
    /home/tgulacsi/src/gopkg.in/rana/ora.v3/util.go:214
    +0x97
    gopkg.in/rana/ora%2ev3.(*Ses).Prep.func1(0xc820053c90)
    /home/tgulacsi/src/gopkg.in/rana/ora.v3/ses.go:256
    +0xa2
    gopkg.in/rana/ora%2ev3._cgoCheckPointer0(0x6c9260,
    0xc8200aa0e8, 0x0, 0x0, 0x0, 0x2bf8808)
    ??:0 +0x4d
    gopkg.in/rana/ora%2ev3.(*Stmt).attr(0xc8200aa000,
    0xc8200aa0e8, 0x1800000004, 0x0, 0x0) [...]
    Which of these arguments is the "Go pointer to Go pointer" ?
    _cgoCheckPointer0() appears to refer to 0xc8200aa0e8 which is the
    second argument to attr(), which is `attrup unsafe.Pointer' so I would
    speculate that the value passed via that argument is the culprit.

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Tamás Gulácsi at Feb 4, 2016 at 2:48 pm
    2016. február 4., csütörtök 15:21:31 UTC+1 időpontban Konstantin Khomoutov
    a következőt írta:
    [...]
    Which of these arguments is the "Go pointer to Go pointer" ?
    _cgoCheckPointer0() appears to refer to 0xc8200aa0e8 which is the
    second argument to attr(), which is `attrup unsafe.Pointer' so I would
    speculate that the value passed via that argument is the culprit.


    Thanks!

    That may help. It's called as

      err = stmt.attr(unsafe.Pointer(&stmt.stmtType), 4, C.OCI_ATTR_STMT_TYPE)
    // determine statement type

    so yes, definitely a Go pointer to an int in a struct. How could I feed
    this to the checker?

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Konstantin Khomoutov at Feb 4, 2016 at 3:02 pm

    On Thu, 4 Feb 2016 06:48:07 -0800 (PST) Tamás Gulácsi wrote:
    [...]
    Which of these arguments is the "Go pointer to Go pointer" ?
    _cgoCheckPointer0() appears to refer to 0xc8200aa0e8 which is the
    second argument to attr(), which is `attrup unsafe.Pointer' so I
    would speculate that the value passed via that argument is the
    culprit.
    Thanks!

    That may help. It's called as

    err = stmt.attr(unsafe.Pointer(&stmt.stmtType), 4,
    C.OCI_ATTR_STMT_TYPE) // determine statement type

    so yes, definitely a Go pointer to an int in a struct. How could I
    feed this to the checker?
    IIUC, if you call `go build` passing it the "-work" command-line option
    it won't delete the temporary work directory after completing so you
    will be able to recover the source code of that _cgoCheckPointer0()
    function.

    A more crude approach would be to temporary patch the library's code to
    simply pass nil as that argument in all the cases and see if it fixes
    the CGO pointer check--supposedly producing a nil pointer dereference
    panic slightly later.

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Gulácsi Tamás at Feb 4, 2016 at 6:38 pm
    This code:

    func (stmt *Stmt) attr(attrup unsafe.Pointer, attrSize C.ub4, attrType
    C.ub4) error {
         aS := C.ub4(attrSize)
         var aU unsafe.Pointer
         aU = attrup
         var oS *C.OCIStmt
         oS = stmt.ocistmt
         var oE *C.OCIError
         oE = stmt.ses.srv.env.ocierr
         fmt.Fprintf(os.Stderr, "C.OCIAttrGet(%p, %d, %p, %p, %d, %p)\n", oS,
    C.OCI_HTYPE_STMT, &aU, &aS, attrType, oE)
         r := C.OCIAttrGet(
             unsafe.Pointer(oS), //unsafe.Pointer(stmt.ocistmt), //const void
       *trgthndlp,
             C.OCI_HTYPE_STMT, //ub4 cfgtrghndltyp,
             &aU, //attrup, //void
    *attributep,
             &aS, //&attrSize, //ub4
      *sizep,
             attrType, //ub4 attrtype,
             oE, //stmt.ses.srv.env.ocierr, //OCIError
    *errhp
         )
         if r == C.OCI_ERROR {
             return stmt.ses.srv.env.ociError()
         }
         return nil
    }


    Results:

    C.OCIAttrGet(0x170ce00, 4, 0xc82009c040, 0xc8200963ec, 24, 0x16fad68)
    initError: Ses.Prep.func1 recovered: runtime error: cgo argument has Go
    pointer to Go pointer
    goroutine 1 [running, locked to thread]:
    gopkg.in/rana/ora%2ev3.errR(0xc82004f860, 0x1, 0x1, 0x0, 0x0)
             /home/gthomas/src/gopkg.in/rana/ora.v3/util.go:214 +0x97
    gopkg.in/rana/ora%2ev3.(*Ses).Prep.func1(0xc82004fd50)
             /home/gthomas/src/gopkg.in/rana/ora.v3/ses.go:256 +0xa2
    gopkg.in/rana/ora%2ev3._cgoCheckPointer0(0x6ba4c0, 0xc82009c040,
    0xc820096450, 0x1, 0x1, 0x170ce00)
             ??:0 +0x4d
    gopkg.in/rana/ora%2ev3.(*Stmt).attr(0xc8200a4000, 0xc8200a40e8,
    0x1800000004, 0x0, 0x0)
             /home/gthomas/src/gopkg.in/rana/ora.v3/stmt.go:1163 +0x4c1
    gopkg.in/rana/ora%2ev3.(*Ses).Prep(0xc8200a0000, 0x819860, 0x99, 0x0, 0x0,
    0x0, 0xc8200a4000, 0x0, 0x0)
             /home/gthomas/src/gopkg.in/rana/ora.v3/ses.go:302 +0x904
    gopkg.in/rana/ora%2ev3_test.init.1()
             /home/gthomas/src/gopkg.in/rana/ora.v3/z_oracle_test.go:158 +0xdd7
    gopkg.in/rana/ora%2ev3_test.init()
             /home/gthomas/src/gopkg.in/rana/ora.v3/z_time_session_test.go:273
    +0x9e
    main.init()
             gopkg.in/rana/ora.v3/_test/_testmain.go:2142 +0x4f


    Does this mean that 0xc82009c040 (the third parameter of _cgoCheckPointer0)
    is the culprit?

    Konstantin Khomoutov <flatworm@users.sourceforge.net> ezt írta (időpont:
    2016. febr. 4., Cs, 16:02):
    On Thu, 4 Feb 2016 06:48:07 -0800 (PST)
    Tamás Gulácsi wrote:
    [...]
    Which of these arguments is the "Go pointer to Go pointer" ?
    _cgoCheckPointer0() appears to refer to 0xc8200aa0e8 which is the
    second argument to attr(), which is `attrup unsafe.Pointer' so I
    would speculate that the value passed via that argument is the
    culprit.
    Thanks!

    That may help. It's called as

    err = stmt.attr(unsafe.Pointer(&stmt.stmtType), 4,
    C.OCI_ATTR_STMT_TYPE) // determine statement type

    so yes, definitely a Go pointer to an int in a struct. How could I
    feed this to the checker?
    IIUC, if you call `go build` passing it the "-work" command-line option
    it won't delete the temporary work directory after completing so you
    will be able to recover the source code of that _cgoCheckPointer0()
    function.

    A more crude approach would be to temporary patch the library's code to
    simply pass nil as that argument in all the cases and see if it fixes
    the CGO pointer check--supposedly producing a nil pointer dereference
    panic slightly later.
    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Konstantin Khomoutov at Feb 4, 2016 at 7:19 pm

    On Thu, 04 Feb 2016 18:38:15 +0000 Gulácsi Tamás wrote:

    This code: [...]
    Results:

    C.OCIAttrGet(0x170ce00, 4, 0xc82009c040, 0xc8200963ec, 24, 0x16fad68)
    initError: Ses.Prep.func1 recovered: runtime error: cgo argument has
    Go pointer to Go pointer
    goroutine 1 [running, locked to thread]:
    gopkg.in/rana/ora%2ev3.errR(0xc82004f860, 0x1, 0x1, 0x0, 0x0)
    /home/gthomas/src/gopkg.in/rana/ora.v3/util.go:214 +0x97
    gopkg.in/rana/ora%2ev3.(*Ses).Prep.func1(0xc82004fd50)
    /home/gthomas/src/gopkg.in/rana/ora.v3/ses.go:256 +0xa2
    gopkg.in/rana/ora%2ev3._cgoCheckPointer0(0x6ba4c0, 0xc82009c040,
    0xc820096450, 0x1, 0x1, 0x170ce00)
    ??:0 +0x4d
    gopkg.in/rana/ora%2ev3.(*Stmt).attr(0xc8200a4000, 0xc8200a40e8,
    0x1800000004, 0x0, 0x0) [...]
    Does this mean that 0xc82009c040 (the third parameter of
    _cgoCheckPointer0) is the culprit?
    Unfortunately, I don't know: I was guessing about the behaviour of
    that _cgoCheckPointer0() function because from your original example
    it appeared to be the only sensible hunch (to me).

    I'd try inspecting what cgo generates for you as I outlined in my
    previous response:

    [...]
    IIUC, if you call `go build` passing it the "-work" command-line
    option it won't delete the temporary work directory after
    completing so you will be able to recover the source code of that
    _cgoCheckPointer0() function.
    [...]

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Gulácsi Tamás at Feb 4, 2016 at 10:15 pm
    Thanks a lot, Konstantin!

    By allocating with C.malloc, the problem vanishes!
    Now I have another problem: at a lot of places, I pass a Go slice to C
    land, and want it to read it and write to it, too.

    I could make it compile, but here I get a []byte, and want it to hand to C,
    and allow it to write to that slice later, and see the results in Go!
    So now I copy the value (do we have a nicer method than this loop with the
    ugly conversions?) to the C.malloc-ed slice, and overwrite the Go slice's
    Data to point to the malloc-ed array.

    type bndBin struct {
         stmt *Stmt
         ocibnd *C.OCIBind
    }

    func (bnd *bndBin) bind(value []byte, position int, stmt *Stmt) (err error)
    {
         bnd.stmt = stmt
         bindp := (*C.OCIBind)(C.malloc(C.sizeof_dvoid))
         // copy to C land
         valuep := (*C.char)(C.malloc(C.size_t(len(value))))
         for i, c := range value {
             *((*C.char)(unsafe.Pointer(uintptr(unsafe.Pointer(valuep)) +
    uintptr(i)))) = (C.char)(c)
         }
         r := C.OCIBINDBYPOS(
                                   bnd.stmt.ocistmt, //OCIStmt *stmtp,
             &bindp, //(**C.OCIBind)(&bnd.ocibnd), //OCIBind
      **bindpp, bnd.stmt.ses.srv.env.ocierr, //OCIError
       *errhp,
             C.ub4(position), //ub4 position,
                                  unsafe.Pointer(valuep), //void
    *valuep,
             C.LENGTH_TYPE(len(value)), //sb8 value_sz,
             C.SQLT_LBI, //ub2 dty,
             nil, //void *indp,
             nil, //ub2 *alenp,
             nil, //ub2 *rcodep,
             0, //ub4 maxarr_len,
             nil, //ub4 *curelep,
             C.OCI_DEFAULT) //ub4 mode );
         if r == C.OCI_ERROR {
             C.free(valuep)
             C.free(bindp)
             return bnd.stmt.ses.srv.env.ociError()
         }
         hdr := (*reflect.SliceHeader)(unsafe.Pointer(&value))
         hdr.Data = uintptr(unsafe.Pointer(valuep))

         return nil
    }


    Is this the intended way for the possibly moving GC, to communicate with C?
    Then I have to rewrite a lot...

    Konstantin Khomoutov <flatworm@users.sourceforge.net> ezt írta (időpont:
    2016. febr. 4., Cs, 20:19):
    On Thu, 04 Feb 2016 18:38:15 +0000
    Gulácsi Tamás wrote:
    This code: [...]
    Results:

    C.OCIAttrGet(0x170ce00, 4, 0xc82009c040, 0xc8200963ec, 24, 0x16fad68)
    initError: Ses.Prep.func1 recovered: runtime error: cgo argument has
    Go pointer to Go pointer
    goroutine 1 [running, locked to thread]:
    gopkg.in/rana/ora%2ev3.errR(0xc82004f860, 0x1, 0x1, 0x0, 0x0)
    /home/gthomas/src/gopkg.in/rana/ora.v3/util.go:214 +0x97
    gopkg.in/rana/ora%2ev3.(*Ses).Prep.func1(0xc82004fd50)
    /home/gthomas/src/gopkg.in/rana/ora.v3/ses.go:256 +0xa2
    gopkg.in/rana/ora%2ev3._cgoCheckPointer0(0x6ba4c0, 0xc82009c040,
    0xc820096450, 0x1, 0x1, 0x170ce00)
    ??:0 +0x4d
    gopkg.in/rana/ora%2ev3.(*Stmt).attr(0xc8200a4000, 0xc8200a40e8,
    0x1800000004, 0x0, 0x0) [...]
    Does this mean that 0xc82009c040 (the third parameter of
    _cgoCheckPointer0) is the culprit?
    Unfortunately, I don't know: I was guessing about the behaviour of
    that _cgoCheckPointer0() function because from your original example
    it appeared to be the only sensible hunch (to me).

    I'd try inspecting what cgo generates for you as I outlined in my
    previous response:

    [...]
    IIUC, if you call `go build` passing it the "-work" command-line
    option it won't delete the temporary work directory after
    completing so you will be able to recover the source code of that
    _cgoCheckPointer0() function.
    [...]
    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Ian Lance Taylor at Feb 4, 2016 at 10:38 pm

    On Thu, Feb 4, 2016 at 2:15 PM, Gulácsi Tamás wrote:
    Now I have another problem: at a lot of places, I pass a Go slice to C land,
    and want it to read it and write to it, too.

    I could make it compile, but here I get a []byte, and want it to hand to C,
    and allow it to write to that slice later, and see the results in Go!
    So now I copy the value (do we have a nicer method than this loop with the
    ugly conversions?) to the C.malloc-ed slice, and overwrite the Go slice's
    Data to point to the malloc-ed array.
    For something like []byte, byte does not contain a pointer, so it's
    fine to write code like
         b := make([]byte, 32)
         C.fillBytes((*C.char)(unsafe.Pointer(&b[0])), 32)
    You can pass a Go pointer to C. What you can't do is pass a Go
    pointer to C if it points to memory that contains a Go pointer.

    Ian

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Tamás Gulácsi at Feb 5, 2016 at 10:31 am
    2016. február 4., csütörtök 23:38:28 UTC+1 időpontban Ian Lance Taylor a
    következőt írta:

    For something like []byte, byte does not contain a pointer, so it's

    fine to write code like

         b := make([]byte, 32)

         C.fillBytes((*C.char)(unsafe.Pointer(&b[0])), 32)

    You can pass a Go pointer to C. What you can't do is pass a Go

    pointer to C if it points to memory that contains a Go pointer.



    Ian


    Thanks Ian, you're right, I can pass a ponter to a []byte.


    What I can't is to solve the following. This code:


    type defLob struct {
         rset *Rset
         ocidef *C.OCIDefine
         ociLobLocator unsafe.Pointer // *C.OCILobLocator
         null C.sb2
         gct GoColumnType
         sqlt C.ub2
         charsetForm C.ub1
    }

    func (def *defLob) define(position int, charsetForm C.ub1, sqlt C.ub2, gct
    GoColumnType, rset *Rset) error {
         def.free()
         def.rset = rset
         def.gct = gct
         def.sqlt = sqlt
         def.charsetForm = charsetForm
         def.ociLobLocator =
    unsafe.Pointer(*((**C.OCILobLocator)(C.malloc(C.size_t(unsafe.Sizeof(def.ociLobLocator))))))
         fmt.Fprintf(os.Stderr, "OCIDEFINEBYPOS def=%p &def.ociLobLocator=%p
    def.null=%p\n", def, unsafe.Pointer(&def.ociLobLocator),
    unsafe.Pointer(&def.null))

         r := C.OCIDEFINEBYPOS(
             def.rset.ocistmt, //OCIStmt
    *stmtp,
             &def.ocidef, //OCIDefine
    **defnpp,
             def.rset.stmt.ses.srv.env.ocierr, //OCIError
      *errhp,
             C.ub4(position), //ub4
    position,
             unsafe.Pointer(&def.ociLobLocator), //void
      *valuep,
             C.LENGTH_TYPE(unsafe.Sizeof(def.ociLobLocator)), //sb8
    value_sz, sqlt, //ub2
    dty,
             unsafe.Pointer(&def.null), //void *indp,
             nil, //ub2 *rlenp,
             nil, //ub2 *rcodep,
             C.OCI_DEFAULT) //ub4 mode );
         if r != C.OCI_SUCCESS {
             C.free(def.ociLobLocator)
             def.ociLobLocator = nil
             return def.rset.stmt.ses.srv.env.ociError()
         }
         prefetchLength := C.boolean(C.TRUE)
         return def.rset.stmt.ses.srv.env.setAttr(unsafe.Pointer(def.ocidef),
    C.OCI_HTYPE_DEFINE, unsafe.Pointer(&prefetchLength), 0,
    C.OCI_ATTR_LOBPREFETCH_LENGTH)
    }



    panics as:
    OCIDEFINEBYPOS def=0xc8200a84e0 &def.ociLobLocator=0xc8200a84f0
    def.null=0xc8200a84f8
    --- FAIL: TestBindDefine_bytes_blob_bufferSize_session (16.00s)
             z_oracle_test.go:789: Stmt.qry.func1 recovered: runtime error: cgo
    argument has Go pointer to Go pointer
                     goroutine 19 [running]:
                     gopkg.in/rana/ora%2ev3.errR(0xc820057568, 0x1, 0x1, 0x0,
    0x0)
                             /home/tgulacsi/src/gopkg.in/rana/ora.v3/util.go:214
    +0x97
                     gopkg.in/rana/ora%2ev3.(*Stmt).qry.func1(0xc820057d60)
                             /home/tgulacsi/src/gopkg.in/rana/ora.v3/stmt.go:239
    +0xa2
                     gopkg.in/rana/ora%2ev3._cgoCheckPointer0(0x6ca160,
    0xc8200a84f0, 0xc8210fc910, 0x1, 0x1, 0x6b3e60)
                             ??:0 +0x4d
                     gopkg.in/rana/ora%2ev3.(*defLob).define(0xc8200a84e0, 0x1,
    0x711701, 0x1b, 0xc8200ac000, 0x0, 0x0)

    /home/tgulacsi/src/gopkg.in/rana/ora.v3/defLob.go:49 +0x593
                     gopkg.in/rana/ora%2ev3.(*Rset).open(0xc8200ac000,
    0xc8200aa140, 0x7f195c028158, 0x0, 0x0)
                             /home/tgulacsi/src/gopkg.in/rana/ora.v3/rset.go:533
    +0x3568
                     gopkg.in/rana/ora%2ev3.(*Stmt).qry(0xc8200aa140, 0x0, 0x0,
    0x0, 0xc8200ac000, 0x0, 0x0)
                             /home/tgulacsi/src/gopkg.in/rana/ora.v3/stmt.go:279
    +0x66d
                     gopkg.in/rana/ora%2ev3.(*Stmt).Qry(0xc8200aa140, 0x0, 0x0,
    0x0, 0x0, 0x0, 0x0)
                             /home/tgulacsi/src/gopkg.in/rana/ora.v3/stmt.go:230
    +0x4b
                     gopkg.in/rana/ora%2ev3_test.testBindDefine(0x6bf320,
    0xc8200a0000, 0x78b8d0, 0xd, 0xc8200d8000, 0x0, 0xc820057f18, 0x1, 0x1)

    /home/tgulacsi/src/gopkg.in/rana/ora.v3/z_oracle_test.go:229 +0x7c6

    gopkg.in/rana/ora%2ev3_test.TestBindDefine_bytes_blob_bufferSize_session(0xc8200d8000)

    /home/tgulacsi/src/gopkg.in/rana/ora.v3/z_bytes_session_test.go:178 +0xfa
                     testing.tRunner(0xc8200d8000, 0xb30bf8)
                             /usr/local/go/src/testing/testing.go:473 +0x98
                     created by testing.RunTests
                             /usr/local/go/src/testing/testing.go:582 +0x892
                     : goroutine 19 [running]:
                     gopkg.in/rana/ora%2ev3_test.testErr(0x7f196e30b028,
    0xc8210fc990, 0xc8200d8000, 0x0, 0x0, 0x0)

    /home/tgulacsi/src/gopkg.in/rana/ora.v3/z_oracle_test.go:789 +0x50
                     gopkg.in/rana/ora%2ev3_test.testBindDefine(0x6bf320,
    0xc8200a0000, 0x78b8d0, 0xd, 0xc8200d8000, 0x0, 0xc820057f18, 0x1, 0x1)

    /home/tgulacsi/src/gopkg.in/rana/ora.v3/z_oracle_test.go:230 +0x816

    gopkg.in/rana/ora%2ev3_test.TestBindDefine_bytes_blob_bufferSize_session(0xc8200d8000)

    /home/tgulacsi/src/gopkg.in/rana/ora.v3/z_bytes_session_test.go:178 +0xfa
                     testing.tRunner(0xc8200d8000, 0xb30bf8)
                             /usr/local/go/src/testing/testing.go:473 +0x98
                     created by testing.RunTests
                             /usr/local/go/src/testing/testing.go:582 +0x892

    Does the "gopkg.in/rana/ora%2ev3._cgoCheckPointer0(0x6ca160, 0xc8200a84f0,
    0xc8210fc910, 0x1, 0x1, 0x6b3e60)" line's pointers indicate which pointer
    is at bad?
    I've printed some, and 0xc8200a84f0 seems to match with &def.ociLobLocator,
    but that's just've been malloc'd!
    So I don't understand.

    Thanks again for your help!

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Ian Lance Taylor at Feb 5, 2016 at 4:59 pm

    On Fri, Feb 5, 2016 at 2:31 AM, Tamás Gulácsi wrote:
    What I can't is to solve the following. This code:


    type defLob struct {
    rset *Rset
    ocidef *C.OCIDefine
    ociLobLocator unsafe.Pointer // *C.OCILobLocator
    null C.sb2
    gct GoColumnType
    sqlt C.ub2
    charsetForm C.ub1
    }

    func (def *defLob) define(position int, charsetForm C.ub1, sqlt C.ub2, gct
    GoColumnType, rset *Rset) error {
    def.free()
    def.rset = rset
    def.gct = gct
    def.sqlt = sqlt
    def.charsetForm = charsetForm
    def.ociLobLocator =
    unsafe.Pointer(*((**C.OCILobLocator)(C.malloc(C.size_t(unsafe.Sizeof(def.ociLobLocator))))))
    fmt.Fprintf(os.Stderr, "OCIDEFINEBYPOS def=%p &def.ociLobLocator=%p
    def.null=%p\n", def, unsafe.Pointer(&def.ociLobLocator),
    unsafe.Pointer(&def.null))

    r := C.OCIDEFINEBYPOS(
    def.rset.ocistmt, //OCIStmt
    *stmtp,
    &def.ocidef, //OCIDefine
    **defnpp,
    def.rset.stmt.ses.srv.env.ocierr, //OCIError
    *errhp,
    C.ub4(position), //ub4
    position,
    unsafe.Pointer(&def.ociLobLocator), //void
    *valuep,
    C.LENGTH_TYPE(unsafe.Sizeof(def.ociLobLocator)), //sb8
    value_sz, sqlt, //ub2
    dty,
    unsafe.Pointer(&def.null), //void *indp,
    nil, //ub2 *rlenp,
    nil, //ub2 *rcodep,
    C.OCI_DEFAULT) //ub4 mode );
    if r != C.OCI_SUCCESS {
    C.free(def.ociLobLocator)
    def.ociLobLocator = nil
    return def.rset.stmt.ses.srv.env.ociError()
    }
    prefetchLength := C.boolean(C.TRUE)
    return def.rset.stmt.ses.srv.env.setAttr(unsafe.Pointer(def.ocidef),
    C.OCI_HTYPE_DEFINE, unsafe.Pointer(&prefetchLength), 0,
    C.OCI_ATTR_LOBPREFETCH_LENGTH)
    }



    panics as:
    OCIDEFINEBYPOS def=0xc8200a84e0 &def.ociLobLocator=0xc8200a84f0
    def.null=0xc8200a84f8
    --- FAIL: TestBindDefine_bytes_blob_bufferSize_session (16.00s)
    z_oracle_test.go:789: Stmt.qry.func1 recovered: runtime error: cgo
    argument has Go pointer to Go pointer
    goroutine 19 [running]:
    gopkg.in/rana/ora%2ev3.errR(0xc820057568, 0x1, 0x1, 0x0,
    0x0)
    /home/tgulacsi/src/gopkg.in/rana/ora.v3/util.go:214
    +0x97
    gopkg.in/rana/ora%2ev3.(*Stmt).qry.func1(0xc820057d60)
    /home/tgulacsi/src/gopkg.in/rana/ora.v3/stmt.go:239
    +0xa2
    gopkg.in/rana/ora%2ev3._cgoCheckPointer0(0x6ca160,
    0xc8200a84f0, 0xc8210fc910, 0x1, 0x1, 0x6b3e60)
    ??:0 +0x4d
    gopkg.in/rana/ora%2ev3.(*defLob).define(0xc8200a84e0, 0x1,
    0x711701, 0x1b, 0xc8200ac000, 0x0, 0x0)
    /home/tgulacsi/src/gopkg.in/rana/ora.v3/defLob.go:49
    +0x593
    gopkg.in/rana/ora%2ev3.(*Rset).open(0xc8200ac000,
    0xc8200aa140, 0x7f195c028158, 0x0, 0x0)
    /home/tgulacsi/src/gopkg.in/rana/ora.v3/rset.go:533
    +0x3568
    gopkg.in/rana/ora%2ev3.(*Stmt).qry(0xc8200aa140, 0x0, 0x0,
    0x0, 0xc8200ac000, 0x0, 0x0)
    /home/tgulacsi/src/gopkg.in/rana/ora.v3/stmt.go:279
    +0x66d
    gopkg.in/rana/ora%2ev3.(*Stmt).Qry(0xc8200aa140, 0x0, 0x0,
    0x0, 0x0, 0x0, 0x0)
    /home/tgulacsi/src/gopkg.in/rana/ora.v3/stmt.go:230
    +0x4b
    gopkg.in/rana/ora%2ev3_test.testBindDefine(0x6bf320,
    0xc8200a0000, 0x78b8d0, 0xd, 0xc8200d8000, 0x0, 0xc820057f18, 0x1, 0x1)

    /home/tgulacsi/src/gopkg.in/rana/ora.v3/z_oracle_test.go:229 +0x7c6

    gopkg.in/rana/ora%2ev3_test.TestBindDefine_bytes_blob_bufferSize_session(0xc8200d8000)

    /home/tgulacsi/src/gopkg.in/rana/ora.v3/z_bytes_session_test.go:178 +0xfa
    testing.tRunner(0xc8200d8000, 0xb30bf8)
    /usr/local/go/src/testing/testing.go:473 +0x98
    created by testing.RunTests
    /usr/local/go/src/testing/testing.go:582 +0x892
    : goroutine 19 [running]:
    gopkg.in/rana/ora%2ev3_test.testErr(0x7f196e30b028,
    0xc8210fc990, 0xc8200d8000, 0x0, 0x0, 0x0)

    /home/tgulacsi/src/gopkg.in/rana/ora.v3/z_oracle_test.go:789 +0x50
    gopkg.in/rana/ora%2ev3_test.testBindDefine(0x6bf320,
    0xc8200a0000, 0x78b8d0, 0xd, 0xc8200d8000, 0x0, 0xc820057f18, 0x1, 0x1)

    /home/tgulacsi/src/gopkg.in/rana/ora.v3/z_oracle_test.go:230 +0x816

    gopkg.in/rana/ora%2ev3_test.TestBindDefine_bytes_blob_bufferSize_session(0xc8200d8000)

    /home/tgulacsi/src/gopkg.in/rana/ora.v3/z_bytes_session_test.go:178 +0xfa
    testing.tRunner(0xc8200d8000, 0xb30bf8)
    /usr/local/go/src/testing/testing.go:473 +0x98
    created by testing.RunTests
    /usr/local/go/src/testing/testing.go:582 +0x892

    Does the "gopkg.in/rana/ora%2ev3._cgoCheckPointer0(0x6ca160, 0xc8200a84f0,
    0xc8210fc910, 0x1, 0x1, 0x6b3e60)" line's pointers indicate which pointer is
    at bad?
    I've printed some, and 0xc8200a84f0 seems to match with &def.ociLobLocator,
    but that's just've been malloc'd!
    So I don't understand.
    I don't know why this would happen from looking at your code, but it's
    possible that cgo is failing to understand that
    `unsafe.Pointer(&def.ociLobLocator)` is referring to only a single
    field of def. It's possible that cgo is looking at the entire def
    value, rather than just the single field whose address you are taking.
    If you can turn this into a standalone test case, please file an
    issue. Otherwise, I would imagine that you can fix your immediate
    problem by writing something like
         locator := def.ociLobLocator
         C.OCIDEFINEBYPOS(..., &locator, ...)
         def.ociLobLocator = locator

    Ian

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Gulácsi Tamás at Feb 5, 2016 at 6:07 pm
    Yes, maybe. But I don't know C enough to be able to decide whether it will
    function as needed:

    locator := def.ociLobLocator
    C.OCIDEFINEBYPOS(..., &locator, ...)
    def.ociLobLocator = locator

    What if the C side want to set the locator (through &locator) LATER?
    Actually, this is the case: here we define the placeholders where the C
    side will put the retrieved rows from the query, one after the other - to
    the same memory location.

    So I need to pass a pointer (P) to a memory, and later retrieve the
    C-written Q pointer from it, and use it at the Go side (mostly to pass it
    to C code).
    How to do this?

    Ian Lance Taylor <iant@golang.org> ezt írta (időpont: 2016. febr. 5., P,
    17:59):
    On Fri, Feb 5, 2016 at 2:31 AM, Tamás Gulácsi wrote:

    What I can't is to solve the following. This code:


    type defLob struct {
    rset *Rset
    ocidef *C.OCIDefine
    ociLobLocator unsafe.Pointer // *C.OCILobLocator
    null C.sb2
    gct GoColumnType
    sqlt C.ub2
    charsetForm C.ub1
    }

    func (def *defLob) define(position int, charsetForm C.ub1, sqlt C.ub2, gct
    GoColumnType, rset *Rset) error {
    def.free()
    def.rset = rset
    def.gct = gct
    def.sqlt = sqlt
    def.charsetForm = charsetForm
    def.ociLobLocator =
    unsafe.Pointer(*((**C.OCILobLocator)(C.malloc(C.size_t(unsafe.Sizeof(def.ociLobLocator))))))
    fmt.Fprintf(os.Stderr, "OCIDEFINEBYPOS def=%p &def.ociLobLocator=%p
    def.null=%p\n", def, unsafe.Pointer(&def.ociLobLocator),
    unsafe.Pointer(&def.null))

    r := C.OCIDEFINEBYPOS(
    def.rset.ocistmt, //OCIStmt
    *stmtp,
    &def.ocidef, //OCIDefine
    **defnpp,
    def.rset.stmt.ses.srv.env.ocierr, //OCIError
    *errhp,
    C.ub4(position), //ub4
    position,
    unsafe.Pointer(&def.ociLobLocator), //void
    *valuep,
    C.LENGTH_TYPE(unsafe.Sizeof(def.ociLobLocator)), //sb8
    value_sz, sqlt, //ub2
    dty,
    unsafe.Pointer(&def.null), //void *indp,
    nil, //ub2 *rlenp,
    nil, //ub2 *rcodep,
    C.OCI_DEFAULT) //ub4 mode );
    if r != C.OCI_SUCCESS {
    C.free(def.ociLobLocator)
    def.ociLobLocator = nil
    return def.rset.stmt.ses.srv.env.ociError()
    }
    prefetchLength := C.boolean(C.TRUE)
    return def.rset.stmt.ses.srv.env.setAttr(unsafe.Pointer(def.ocidef),
    C.OCI_HTYPE_DEFINE, unsafe.Pointer(&prefetchLength), 0,
    C.OCI_ATTR_LOBPREFETCH_LENGTH)
    }



    panics as:
    OCIDEFINEBYPOS def=0xc8200a84e0 &def.ociLobLocator=0xc8200a84f0
    def.null=0xc8200a84f8
    --- FAIL: TestBindDefine_bytes_blob_bufferSize_session (16.00s)
    z_oracle_test.go:789: Stmt.qry.func1 recovered: runtime error: cgo
    argument has Go pointer to Go pointer
    goroutine 19 [running]:
    gopkg.in/rana/ora%2ev3.errR(0xc820057568, 0x1, 0x1, 0x0,
    0x0)
    /home/tgulacsi/src/
    gopkg.in/rana/ora.v3/util.go:214
    +0x97
    gopkg.in/rana/ora%2ev3.(*Stmt).qry.func1(0xc820057d60)
    /home/tgulacsi/src/
    gopkg.in/rana/ora.v3/stmt.go:239
    +0xa2
    gopkg.in/rana/ora%2ev3._cgoCheckPointer0(0x6ca160,
    0xc8200a84f0, 0xc8210fc910, 0x1, 0x1, 0x6b3e60)
    ??:0 +0x4d
    gopkg.in/rana/ora%2ev3.(*defLob).define(0xc8200a84e0, 0x1,
    0x711701, 0x1b, 0xc8200ac000, 0x0, 0x0)
    /home/tgulacsi/src/
    gopkg.in/rana/ora.v3/defLob.go:49
    +0x593
    gopkg.in/rana/ora%2ev3.(*Rset).open(0xc8200ac000,
    0xc8200aa140, 0x7f195c028158, 0x0, 0x0)
    /home/tgulacsi/src/
    gopkg.in/rana/ora.v3/rset.go:533
    +0x3568
    gopkg.in/rana/ora%2ev3.(*Stmt).qry(0xc8200aa140, 0x0, 0x0,
    0x0, 0xc8200ac000, 0x0, 0x0)
    /home/tgulacsi/src/
    gopkg.in/rana/ora.v3/stmt.go:279
    +0x66d
    gopkg.in/rana/ora%2ev3.(*Stmt).Qry(0xc8200aa140, 0x0, 0x0,
    0x0, 0x0, 0x0, 0x0)
    /home/tgulacsi/src/
    gopkg.in/rana/ora.v3/stmt.go:230
    +0x4b
    gopkg.in/rana/ora%2ev3_test.testBindDefine(0x6bf320,
    0xc8200a0000, 0x78b8d0, 0xd, 0xc8200d8000, 0x0, 0xc820057f18, 0x1, 0x1)

    /home/tgulacsi/src/gopkg.in/rana/ora.v3/z_oracle_test.go:229 +0x7c6

    gopkg.in/rana/ora%2ev3_test.TestBindDefine_bytes_blob_bufferSize_session(0xc8200d8000)
    /home/tgulacsi/src/gopkg.in/rana/ora.v3/z_bytes_session_test.go:178 +0xfa
    testing.tRunner(0xc8200d8000, 0xb30bf8)
    /usr/local/go/src/testing/testing.go:473 +0x98
    created by testing.RunTests
    /usr/local/go/src/testing/testing.go:582 +0x892
    : goroutine 19 [running]:
    gopkg.in/rana/ora%2ev3_test.testErr(0x7f196e30b028,
    0xc8210fc990, 0xc8200d8000, 0x0, 0x0, 0x0)

    /home/tgulacsi/src/gopkg.in/rana/ora.v3/z_oracle_test.go:789 +0x50
    gopkg.in/rana/ora%2ev3_test.testBindDefine(0x6bf320,
    0xc8200a0000, 0x78b8d0, 0xd, 0xc8200d8000, 0x0, 0xc820057f18, 0x1, 0x1)

    /home/tgulacsi/src/gopkg.in/rana/ora.v3/z_oracle_test.go:230 +0x816

    gopkg.in/rana/ora%2ev3_test.TestBindDefine_bytes_blob_bufferSize_session(0xc8200d8000)
    /home/tgulacsi/src/gopkg.in/rana/ora.v3/z_bytes_session_test.go:178 +0xfa
    testing.tRunner(0xc8200d8000, 0xb30bf8)
    /usr/local/go/src/testing/testing.go:473 +0x98
    created by testing.RunTests
    /usr/local/go/src/testing/testing.go:582 +0x892

    Does the "gopkg.in/rana/ora%2ev3._cgoCheckPointer0(0x6ca160,
    0xc8200a84f0,
    0xc8210fc910, 0x1, 0x1, 0x6b3e60)" line's pointers indicate which
    pointer is
    at bad?
    I've printed some, and 0xc8200a84f0 seems to match with
    &def.ociLobLocator,
    but that's just've been malloc'd!
    So I don't understand.
    I don't know why this would happen from looking at your code, but it's
    possible that cgo is failing to understand that
    `unsafe.Pointer(&def.ociLobLocator)` is referring to only a single
    field of def. It's possible that cgo is looking at the entire def
    value, rather than just the single field whose address you are taking.
    If you can turn this into a standalone test case, please file an
    issue. Otherwise, I would imagine that you can fix your immediate
    problem by writing something like
    locator := def.ociLobLocator
    C.OCIDEFINEBYPOS(..., &locator, ...)
    def.ociLobLocator = locator

    Ian
    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Ian Lance Taylor at Feb 5, 2016 at 6:24 pm

    On Fri, Feb 5, 2016 at 10:07 AM, Gulácsi Tamás wrote:
    Yes, maybe. But I don't know C enough to be able to decide whether it will
    function as needed:

    locator := def.ociLobLocator
    C.OCIDEFINEBYPOS(..., &locator, ...)
    def.ociLobLocator = locator

    What if the C side want to set the locator (through &locator) LATER?
    Actually, this is the case: here we define the placeholders where the C side
    will put the retrieved rows from the query, one after the other - to the
    same memory location.

    So I need to pass a pointer (P) to a memory, and later retrieve the
    C-written Q pointer from it, and use it at the Go side (mostly to pass it to
    C code).
    How to do this?
    Remember that the cgo rules absolutely prohibit C code saving a Go
    pointer after the Go function returns. Any attempt to do so would
    break a possible future moving garbage collector. So if the C side is
    going to be the saving that pointer, then you must allocate def using
    C.malloc. And that will solve your whole problem anyhow.

    Ian

    Ian Lance Taylor <iant@golang.org> ezt írta (időpont: 2016. febr. 5., P,
    17:59):
    On Fri, Feb 5, 2016 at 2:31 AM, Tamás Gulácsi <tgulacsi78@gmail.com>
    wrote:
    What I can't is to solve the following. This code:


    type defLob struct {
    rset *Rset
    ocidef *C.OCIDefine
    ociLobLocator unsafe.Pointer // *C.OCILobLocator
    null C.sb2
    gct GoColumnType
    sqlt C.ub2
    charsetForm C.ub1
    }

    func (def *defLob) define(position int, charsetForm C.ub1, sqlt C.ub2,
    gct
    GoColumnType, rset *Rset) error {
    def.free()
    def.rset = rset
    def.gct = gct
    def.sqlt = sqlt
    def.charsetForm = charsetForm
    def.ociLobLocator =

    unsafe.Pointer(*((**C.OCILobLocator)(C.malloc(C.size_t(unsafe.Sizeof(def.ociLobLocator))))))
    fmt.Fprintf(os.Stderr, "OCIDEFINEBYPOS def=%p &def.ociLobLocator=%p
    def.null=%p\n", def, unsafe.Pointer(&def.ociLobLocator),
    unsafe.Pointer(&def.null))

    r := C.OCIDEFINEBYPOS(
    def.rset.ocistmt, //OCIStmt
    *stmtp,
    &def.ocidef, //OCIDefine
    **defnpp,
    def.rset.stmt.ses.srv.env.ocierr, //OCIError
    *errhp,
    C.ub4(position), //ub4
    position,
    unsafe.Pointer(&def.ociLobLocator), //void
    *valuep,
    C.LENGTH_TYPE(unsafe.Sizeof(def.ociLobLocator)), //sb8
    value_sz, sqlt, //ub2
    dty,
    unsafe.Pointer(&def.null), //void *indp,
    nil, //ub2 *rlenp,
    nil, //ub2 *rcodep,
    C.OCI_DEFAULT) //ub4 mode );
    if r != C.OCI_SUCCESS {
    C.free(def.ociLobLocator)
    def.ociLobLocator = nil
    return def.rset.stmt.ses.srv.env.ociError()
    }
    prefetchLength := C.boolean(C.TRUE)
    return def.rset.stmt.ses.srv.env.setAttr(unsafe.Pointer(def.ocidef),
    C.OCI_HTYPE_DEFINE, unsafe.Pointer(&prefetchLength), 0,
    C.OCI_ATTR_LOBPREFETCH_LENGTH)
    }



    panics as:
    OCIDEFINEBYPOS def=0xc8200a84e0 &def.ociLobLocator=0xc8200a84f0
    def.null=0xc8200a84f8
    --- FAIL: TestBindDefine_bytes_blob_bufferSize_session (16.00s)
    z_oracle_test.go:789: Stmt.qry.func1 recovered: runtime error:
    cgo
    argument has Go pointer to Go pointer
    goroutine 19 [running]:
    gopkg.in/rana/ora%2ev3.errR(0xc820057568, 0x1, 0x1, 0x0,
    0x0)

    /home/tgulacsi/src/gopkg.in/rana/ora.v3/util.go:214
    +0x97
    gopkg.in/rana/ora%2ev3.(*Stmt).qry.func1(0xc820057d60)

    /home/tgulacsi/src/gopkg.in/rana/ora.v3/stmt.go:239
    +0xa2
    gopkg.in/rana/ora%2ev3._cgoCheckPointer0(0x6ca160,
    0xc8200a84f0, 0xc8210fc910, 0x1, 0x1, 0x6b3e60)
    ??:0 +0x4d
    gopkg.in/rana/ora%2ev3.(*defLob).define(0xc8200a84e0,
    0x1,
    0x711701, 0x1b, 0xc8200ac000, 0x0, 0x0)

    /home/tgulacsi/src/gopkg.in/rana/ora.v3/defLob.go:49
    +0x593
    gopkg.in/rana/ora%2ev3.(*Rset).open(0xc8200ac000,
    0xc8200aa140, 0x7f195c028158, 0x0, 0x0)

    /home/tgulacsi/src/gopkg.in/rana/ora.v3/rset.go:533
    +0x3568
    gopkg.in/rana/ora%2ev3.(*Stmt).qry(0xc8200aa140, 0x0,
    0x0,
    0x0, 0xc8200ac000, 0x0, 0x0)

    /home/tgulacsi/src/gopkg.in/rana/ora.v3/stmt.go:279
    +0x66d
    gopkg.in/rana/ora%2ev3.(*Stmt).Qry(0xc8200aa140, 0x0,
    0x0,
    0x0, 0x0, 0x0, 0x0)

    /home/tgulacsi/src/gopkg.in/rana/ora.v3/stmt.go:230
    +0x4b
    gopkg.in/rana/ora%2ev3_test.testBindDefine(0x6bf320,
    0xc8200a0000, 0x78b8d0, 0xd, 0xc8200d8000, 0x0, 0xc820057f18, 0x1, 0x1)

    /home/tgulacsi/src/gopkg.in/rana/ora.v3/z_oracle_test.go:229 +0x7c6


    gopkg.in/rana/ora%2ev3_test.TestBindDefine_bytes_blob_bufferSize_session(0xc8200d8000)

    /home/tgulacsi/src/gopkg.in/rana/ora.v3/z_bytes_session_test.go:178
    +0xfa
    testing.tRunner(0xc8200d8000, 0xb30bf8)
    /usr/local/go/src/testing/testing.go:473 +0x98
    created by testing.RunTests
    /usr/local/go/src/testing/testing.go:582 +0x892
    : goroutine 19 [running]:
    gopkg.in/rana/ora%2ev3_test.testErr(0x7f196e30b028,
    0xc8210fc990, 0xc8200d8000, 0x0, 0x0, 0x0)

    /home/tgulacsi/src/gopkg.in/rana/ora.v3/z_oracle_test.go:789 +0x50
    gopkg.in/rana/ora%2ev3_test.testBindDefine(0x6bf320,
    0xc8200a0000, 0x78b8d0, 0xd, 0xc8200d8000, 0x0, 0xc820057f18, 0x1, 0x1)

    /home/tgulacsi/src/gopkg.in/rana/ora.v3/z_oracle_test.go:230 +0x816


    gopkg.in/rana/ora%2ev3_test.TestBindDefine_bytes_blob_bufferSize_session(0xc8200d8000)

    /home/tgulacsi/src/gopkg.in/rana/ora.v3/z_bytes_session_test.go:178
    +0xfa
    testing.tRunner(0xc8200d8000, 0xb30bf8)
    /usr/local/go/src/testing/testing.go:473 +0x98
    created by testing.RunTests
    /usr/local/go/src/testing/testing.go:582 +0x892

    Does the "gopkg.in/rana/ora%2ev3._cgoCheckPointer0(0x6ca160,
    0xc8200a84f0,
    0xc8210fc910, 0x1, 0x1, 0x6b3e60)" line's pointers indicate which
    pointer is
    at bad?
    I've printed some, and 0xc8200a84f0 seems to match with
    &def.ociLobLocator,
    but that's just've been malloc'd!
    So I don't understand.
    I don't know why this would happen from looking at your code, but it's
    possible that cgo is failing to understand that
    `unsafe.Pointer(&def.ociLobLocator)` is referring to only a single
    field of def. It's possible that cgo is looking at the entire def
    value, rather than just the single field whose address you are taking.
    If you can turn this into a standalone test case, please file an
    issue. Otherwise, I would imagine that you can fix your immediate
    problem by writing something like
    locator := def.ociLobLocator
    C.OCIDEFINEBYPOS(..., &locator, ...)
    def.ociLobLocator = locator

    Ian
    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Tamás Gulácsi at Feb 5, 2016 at 8:50 pm
    2016. február 5., péntek 19:25:14 UTC+1 időpontban Ian Lance Taylor a
    következőt írta:
    On Fri, Feb 5, 2016 at 10:07 AM, Gulácsi Tamás <tgula...@gmail.com
    <javascript:>> wrote:
    Yes, maybe. But I don't know C enough to be able to decide whether it will
    function as needed:

    locator := def.ociLobLocator
    C.OCIDEFINEBYPOS(..., &locator, ...)
    def.ociLobLocator = locator

    What if the C side want to set the locator (through &locator) LATER?
    Actually, this is the case: here we define the placeholders where the C side
    will put the retrieved rows from the query, one after the other - to the
    same memory location.

    So I need to pass a pointer (P) to a memory, and later retrieve the
    C-written Q pointer from it, and use it at the Go side (mostly to pass it to
    C code).
    How to do this?
    Remember that the cgo rules absolutely prohibit C code saving a Go
    pointer after the Go function returns. Any attempt to do so would
    break a possible future moving garbage collector. So if the C side is
    going to be the saving that pointer, then you must allocate def using
    C.malloc. And that will solve your whole problem anyhow.

    Ian
    This seems to work:

    type defLob struct {
         rset *Rset
         ocidef *C.OCIDefine
         ociLobLocatorp **C.OCILobLocator
         nullp *C.sb2
         gct GoColumnType
         sqlt C.ub2
         charsetForm C.ub1
                           }

    func (def *defLob) define(position int, charsetForm C.ub1, sqlt C.ub2, gct
    GoColumnType, rset *Rset) error {
         def.rset = rset
         def.gct = gct
         def.sqlt = sqlt
         def.charsetForm = charsetForm
         def.ociLobLocatorp = (**C.OCILobLocator)(C.malloc(C.sizeof_dvoid))
         def.nullp = (*C.sb2)(C.malloc(C.sizeof_sb2))
         r := C.OCIDEFINEBYPOS(
             def.rset.ocistmt, //OCIStmt
    *stmtp,
             &def.ocidef, //OCIDefine
    **defnpp,
             def.rset.stmt.ses.srv.env.ocierr, //OCIError
      *errhp,
             C.ub4(position), //ub4
    position,
             unsafe.Pointer(def.ociLobLocatorp), //void
      *valuep,
             C.LENGTH_TYPE(unsafe.Sizeof(*def.ociLobLocatorp)), //sb8
    value_sz,
             sqlt, //ub2 dty,
                                   unsafe.Pointer(def.nullp), //void
      *indp,
             nil, //ub2 *rlenp,
             nil, //ub2 *rcodep,
             C.OCI_DEFAULT) //ub4 mode );
         if r != C.OCI_SUCCESS {
             return def.rset.stmt.ses.srv.env.ociError()
         }
         prefetchLength := C.boolean(C.TRUE)
         return def.rset.stmt.ses.srv.env.setAttr(unsafe.Pointer(def.ocidef),
    C.OCI_HTYPE_DEFINE, unsafe.Pointer(&prefetchLength), 0,
    C.OCI_ATTR_LOBPREFETCH_LENGTH)
    }


    So, by doing the pointer indirection at every use (*def.ociLobLocatorp),
    and allocating the Go-side pointer with C.mallod, I can satisfy the cgo
    pointer validator.

    What I don't really understand is why I need to allocate the indicator
    (C.sb2) on C side?

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Matt Harden at Feb 6, 2016 at 2:14 am
    Because that's a pointer inside a struct that's in Go memory. It can't also
    point to Go memory if you're going to pass the struct to C. C.malloc
    allocates the storage outside of Go memory. The usual way I've seen to
    integrate with C libraries is to let them allocate and manage all their
    structures. Then you won't run into this problem.
    On Fri, Feb 5, 2016, 12:51 Tamás Gulácsi wrote:


    2016. február 5., péntek 19:25:14 UTC+1 időpontban Ian Lance Taylor a
    következőt írta:
    On Fri, Feb 5, 2016 at 10:07 AM, Gulácsi Tamás <tgula...@gmail.com>
    wrote:
    Yes, maybe. But I don't know C enough to be able to decide whether it will
    function as needed:

    locator := def.ociLobLocator
    C.OCIDEFINEBYPOS(..., &locator, ...)
    def.ociLobLocator = locator

    What if the C side want to set the locator (through &locator) LATER?
    Actually, this is the case: here we define the placeholders where the C side
    will put the retrieved rows from the query, one after the other - to the
    same memory location.

    So I need to pass a pointer (P) to a memory, and later retrieve the
    C-written Q pointer from it, and use it at the Go side (mostly to pass it to
    C code).
    How to do this?
    Remember that the cgo rules absolutely prohibit C code saving a Go
    pointer after the Go function returns. Any attempt to do so would
    break a possible future moving garbage collector. So if the C side is
    going to be the saving that pointer, then you must allocate def using
    C.malloc. And that will solve your whole problem anyhow.

    Ian
    This seems to work:

    type defLob struct {
    rset *Rset
    ocidef *C.OCIDefine
    ociLobLocatorp **C.OCILobLocator
    nullp *C.sb2
    gct GoColumnType
    sqlt C.ub2
    charsetForm C.ub1
    }

    func (def *defLob) define(position int, charsetForm C.ub1, sqlt C.ub2, gct
    GoColumnType, rset *Rset) error {
    def.rset = rset
    def.gct = gct
    def.sqlt = sqlt
    def.charsetForm = charsetForm
    def.ociLobLocatorp = (**C.OCILobLocator)(C.malloc(C.sizeof_dvoid))
    def.nullp = (*C.sb2)(C.malloc(C.sizeof_sb2))
    r := C.OCIDEFINEBYPOS(
    def.rset.ocistmt, //OCIStmt
    *stmtp,
    &def.ocidef, //OCIDefine
    **defnpp,
    def.rset.stmt.ses.srv.env.ocierr, //OCIError
    *errhp,
    C.ub4(position), //ub4
    position,
    unsafe.Pointer(def.ociLobLocatorp), //void
    *valuep,
    C.LENGTH_TYPE(unsafe.Sizeof(*def.ociLobLocatorp)), //sb8
    value_sz,
    sqlt, //ub2 dty,
    unsafe.Pointer(def.nullp), //void
    *indp,
    nil, //ub2 *rlenp,
    nil, //ub2 *rcodep,
    C.OCI_DEFAULT) //ub4 mode );
    if r != C.OCI_SUCCESS {
    return def.rset.stmt.ses.srv.env.ociError()
    }
    prefetchLength := C.boolean(C.TRUE)
    return def.rset.stmt.ses.srv.env.setAttr(unsafe.Pointer(def.ocidef),
    C.OCI_HTYPE_DEFINE, unsafe.Pointer(&prefetchLength), 0,
    C.OCI_ATTR_LOBPREFETCH_LENGTH)
    }


    So, by doing the pointer indirection at every use (*def.ociLobLocatorp),
    and allocating the Go-side pointer with C.mallod, I can satisfy the cgo
    pointer validator.

    What I don't really understand is why I need to allocate the indicator
    (C.sb2) on C side?

    --
    You received this message because you are subscribed to the Google Groups
    "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an
    email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Tamás Gulácsi at Feb 6, 2016 at 8:09 am
    But AFAIK I'm not passing the struct to C, only some fields of it.

    This library (OCI, Oracle Call Interface) does allocate the struct, if you call the required function, but needs a pointer to a pointer, to be able to return the allocated struct's pointer.

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupgolang-nuts @
categoriesgo
postedJan 13, '16 at 1:41p
activeFeb 6, '16 at 8:09a
posts26
users6
websitegolang.org

People

Translate

site design / logo © 2022 Grokbase