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.

Reply via email to