Are you sure the document is not doing the free of the file and the opt when it is destroyed? It might need those references beyond the function scope.
> On Oct 11, 2018, at 3:52 AM, ndav...@turnitin.com wrote: > > > package main > > /* > #cgo CFLAGS: -g -Wall -I/usr/local/include > #cgo LDFLAGS: -L/usr/local/lib -lm -lstdc++ > #include <stdlib.h> > #include <string.h> > #include <stdint.h> > #include <math.h> > > // tet_pcos_get_string wraps the TET_pcos_get_string so we can use it in Go, > cgo does not support > // variadic args, this is the solution > char* str_add(const char *s1, const char *s2) { > char *result = malloc(strlen(s1) + strlen(s2) + 1); // +1 for the > null-terminator > // in real code you would check for errors in malloc here > strcpy(result, s1); > strcat(result, s2); > return result; > } > */ > import "C" > import ( > "fmt" > "unsafe" > ) > > func main() { > str := doTheCStuff() > fmt.Println(str) > } > > func doTheCStuff() string{ > s1 := C.CString("string one") > //defer C.free(unsafe.Pointer(file)) > s2 := C.CString("string 2") > //defer C.free(unsafe.Pointer(opt)) > > defer func(){ > C.free(unsafe.Pointer(s1)) > C.free(unsafe.Pointer(s2)) > }() > > s3 := C.GoString(C.str_add(s1, s2)) > return s3 > } > > This is the sort of thing, this will run just fine and no re-produce the > error. The exact use case in production where I see this involves using a 3rd > party C library that opens a document. This then, sometimes, results in the > error. The trouble is, using the 3rd party lib requires a license key so I'm > not sure how much I can post on here. > > The actual snippet from prod that occasionally causes this issue is: > // openDoc returns the document handle for the metadata extraction > func (e *Extractor) openDoc(fp string) (*doc, error) { > file := C.CString(fp) > defer C.free(unsafe.Pointer(file)) > opt := C.CString("shrug checkglyphlists=true decompose={none} > tetml={elements={docinfo=true}} fold={{[U+0640] preserve} {[:Private_Use:] > unknownchar} {[:space:] remove} {[U+0009] remove} {[U+000D] remove} > {[:Control:] remove} {[:Unassigned:] preserve} {[U+FFFF] remove}} > unknownchar=U+003F allowjpeg2000=true") > defer C.free(unsafe.Pointer(opt)) > > // For documentation see page 175 > docNum := C.TET_open_document(e.tet, file, 0, opt) > if docNum < 0 { > return nil, fmt.Errorf("failed to open document") > } > doc := &doc{ > num: docNum, > tet: e.tet, // added for convenience > } > return doc, nil > } > > > For this to work you need to have an instance ofTET and a license key. I > can't share that, for obvious reason. But What you can see in this code is > that I now have the more common pattern for create and free. Yet when I use > the defer closure pattern here, after creating both file and opt, I sometimes > get the double free. We have have noticed that the issue was reproducible > with a specific set of files. Using this pattern fixes that issue, I'm just > curious as to why the defer would cause trouble. > >> On Thursday, October 11, 2018 at 9:23:23 AM UTC+1, Jan Mercl wrote: >> >> On Thu, Oct 11, 2018 at 10:15 AM <nda...@turnitin.com> wrote: >> >> > What I am wondering is why the closure approach does not work? >> >> ISTM it should work. Please post a full, standalone reproduction code here >> or at the issue tracker, thanks. >> >> >> -- >> -j >> > > -- > 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+unsubscr...@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+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.