On Thu, Jul 11, 2019 at 7:16 AM Nitish Saboo <nitish.sabo...@gmail.com> wrote: > > I have the following function 'LoadPatternDB' where I am allocating memory > for a C struct.My C struct contains the callback function. > > 1)I cannot deference the struct in the same func 'LoadPatternDB' because I > get the following error when my callback function is called from C code: > > signal SIGSEGV: segmentation violation code=0x1 addr=0x7f1e00415341 > pc=0x7f1e00415341] > > 2)The same code is running in multiple go routines.And because of that if I > don't deallocate the memory I get the following error: > > *** Error in `fatal error: bin/main': double free or corruption > (fasttop)unexpected signal during runtime execution: 0x00007fd2b8588060 *** > > My question is: > > How can I store the address of the C struct (when memory is allocated using > calloc) on Go side in an array so that I can deallocate the memory using > 'defer C.free(unsafe.Pointer(InitStruct))' when the callback is done. > > > 'InitStruct := (*C.Accumulatedparams)(C.calloc(1, > C.sizeof_struct_Accumulatedparams))' >>>> I want to store this address on Go > side. > > > Can some please guide me here ? > > > syslogparser.go > ============= > > func (obj SyslogParser) LoadPatternDB(opts Syslog, workerId int) { > patterndbpath := C.CString(opts.Patterndb) > defer C.free(unsafe.Pointer(patterndbpath)) > InitStruct := (*C.Accumulatedparams)(C.calloc(1, > C.sizeof_struct_Accumulatedparams)) > //defer C.free(unsafe.Pointer(InitStruct)) . <<<<<<<<<<<<<<<<<<<<<<I cannot > do this here > InitStruct.callback = (C.key_value_cb)(C.callback) > InitStruct.data = C.int(workerId) > C.load_pattern_db(patterndbpath, > (*C.Accumulatedparams)(unsafe.Pointer(InitStruct)), C.int(workerId)) > } > > > //export Result > func Result(key *C.char, value *C.char, value_len C.size_t, mapid C.int) { > fmt.Println("Map Id: " + strconv.Itoa(int(mapid))) > value_field := C.GoStringN(value, C.int(value_len)) > key_field := C.GoString(key) > remap, ok := constants.FIELD_MAPPINGS[key_field] > if ok { > Check.result[int(mapid)][remap] = value_field > //check.result[remap] = value_field > } else { > //check.result[key_field] = value_field > Check.result[int(mapid)][key_field] = value_field > } > } > > > cfuncs.go > -======== > package lib > > /* > > #include <stdio.h> > > // The gateway function > void callback(char *key, char *value, size_t value_len, int mapid) > { > //printf("C.callOnMeGo_cgo(): called"); > void Result(const char *key, const char *value, size_t value_len, int mapid); > Result(key, value, value_len, mapid); > } > */ > import "C" > > syslog-node.h > ============ > > #ifndef TEST_H_INCLUDED > #define TEST_H_INCLUDED > > #include <stdlib.h> > > typedef void (*key_value_cb)(const char* key, const char* value, size_t > value_len, int data); > typedef struct Accumulatedparams{ > key_value_cb callback; > int data; > }Accumulatedparams; > int initialize_engine(const char* filename, const char* module_path); > int reload_pattern_db(const char* filename, Accumulatedparams *cb, int > workerId); > int load_pattern_db(const char* filename, Accumulatedparams *cb, int > workerId); > > #endif
I don't see anything obviously wrong in your Go code, but it's impossible to answer your question without knowing what the C code does. What you describe is consistent with C code that expects to retain the memory passed to load_pattern_db, or alternatively is also consistent with C code that does not expect to be called concurrently from multiple threads of execution. 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+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/CAOyqgcU2ACrQFZJB7k-%3DaOAWyFODB%2B6FNd%3DqUsj1XciV3GhV3w%40mail.gmail.com. For more options, visit https://groups.google.com/d/optout.