Because the same Go routine doesn’t mean it will be called on the same thread. 
It is essentially a race condition. I could be wrong - I’m sure someone will 
correct me. :)

> On Mar 16, 2020, at 9:32 AM, Nitish Saboo <nitish.sabo...@gmail.com> wrote:
> 
> 
> Hi Robert,
> 
> Looks like pattern_db is a global. Are you sure you don’t have multiple Go 
> routines calling the load? The global changes may not be visible- so the free 
> is doing nothing. 
> 
> patterndb is a global variable on C side.load method is getting called from a 
> single go routine every 3 mins.I used gdb to put a break point on 
> pattern_db_free and that is getting called.
> 
> The global changes may not be visible- so the free is doing nothing. 
> 
> >>Since it is a global variable it should be visible..right?
> 
> You probably need synchronization or pinning the access routine to a thread. 
> 
> >>Why we need to pin routine to a thread ?
> 
> Thanks,
> Nitish
> 
>> On Mon, Mar 16, 2020 at 7:41 PM Robert Engels <reng...@ix.netcom.com> wrote:
>> Looks like pattern_db is a global. Are you sure you don’t have multiple Go 
>> routines calling the load? The global changes may not be visible- so the 
>> free is doing nothing. 
>> 
>> You probably need synchronization or pinning the access routine to a thread. 
>> 
>>>> On Mar 16, 2020, at 9:03 AM, Nitish Saboo <nitish.sabo...@gmail.com> wrote:
>>>> 
>>> 
>>> Hi,
>>> 
>>> From reading the code, I assume that the `pattern_db_new()` does some sort 
>>> of allocation of a new pattern DB. I don't see any code releasing the 
>>> pattern DB. Is that just missing from your post or something that some 
>>> automatic mechanism does?
>>> 
>>> >>Apologies, that part got missed in the code snippet. I am making the free 
>>> >>call in the C code.
>>> 
>>> node.c
>>> ---------
>>> int load_pattern_db(const gchar* file, key_value_cb cb)
>>> {
>>>  if(patterndb != NULL){
>>>     pattern_db_free(patterndb);
>>>   }
>>>   patterndb = pattern_db_new();
>>>   pattern_db_reload_ruleset(patterndb, configuration, file);
>>>   pattern_db_set_emit_func(patterndb, pdbtool_pdb_emit_accumulate, cb);
>>>   return 0;
>>> }
>>> 
>>> You can try a similar C program that instantiates and frees the structure 
>>> to check for similar behavior. 
>>> 
>>> >> To verify if the C code had some issue, I called the C wrapper code 
>>> >> method 'load_pattern_db' from my main.c to completely eliminate Go code 
>>> >> here. What I found is there is no increase in memory consumption after 
>>> >> every call ('load_pattern_db' was called 5 times). Hence there is no 
>>> >> issue from C code.
>>> 
>>> Thanks,
>>> Nitish
>>> 
>>>> On Mon, Mar 16, 2020 at 7:04 PM Gregor Best <b...@pferdewetten.de> wrote:
>>>> This might be a dumb question but...
>>>> 
>>>> From reading the code, I assume that the `pattern_db_new()` does some sort 
>>>> of allocation of a new pattern DB. I don't see any code releasing the 
>>>> pattern DB. Is that just missing from your post or something that some 
>>>> automatic mechanism does?
>>>> 
>>>> If not, that might be your leak.
>>>> 
>>>>> On 09.03.20 12:33, Nitish Saboo wrote:
>>>>> Hi
>>>>> 
>>>>> Following are my Go code and C header file and C wrapper code
>>>>> 
>>>>> parser.go
>>>>> ==========
>>>>> var f *os.File
>>>>> 
>>>>> func LoadPatternDB(patterndb string) {
>>>>> path := C.CString(patterndb)
>>>>> defer C.free(unsafe.Pointer(path))
>>>>> C.load_pattern_db(path, 
>>>>> (C.key_value_cb)(unsafe.Pointer(C.callOnMeGo_cgo)))
>>>>> }
>>>>> 
>>>>> //export ParsedData
>>>>> func ParsedData(k *C.char, val *C.char, val_len C.size_t) {
>>>>> f.WriteString(C.GoString(k))
>>>>> f.WriteString("\n")
>>>>> }
>>>>> 
>>>>> cfunc.go
>>>>> ========
>>>>> /*
>>>>> #include <stdio.h>
>>>>> // The gateway function
>>>>> void callOnMeGo_cgo(char *k, char *val, size_t val_len)
>>>>> {
>>>>> void ParsedData(const char *k, const char *val, size_t val_len);
>>>>> ParsedData(k, val, val_len);
>>>>> }
>>>>> */
>>>>> import "C"
>>>>> 
>>>>> node.h
>>>>> =======
>>>>> 
>>>>> #ifndef TEST_H_INCLUDED
>>>>> #define TEST_H_INCLUDED
>>>>> 
>>>>> #include <stdlib.h>
>>>>> 
>>>>> typedef void (*key_value_cb)(const char* k, const char* val, size_t 
>>>>> val_len);
>>>>> int load_pattern_db(const char* file, key_value_cb cb);
>>>>> 
>>>>> #endif
>>>>> 
>>>>> node.c
>>>>> ---------
>>>>> int load_pattern_db(const gchar* file, key_value_cb cb)
>>>>> {
>>>>>   patterndb = pattern_db_new();
>>>>>   pattern_db_reload_ruleset(patterndb, configuration, file);
>>>>>   pattern_db_set_emit_func(patterndb, pdbtool_pdb_emit_accumulate, cb);
>>>>>   return 0;
>>>>> }
>>>>> 
>>>>> 
>>>>> I am calling 'LoadPatternDB' method in my parser.go file that makes a cgo 
>>>>> call 'C.load_pattern_db' where I am passing a callback function to the C 
>>>>> code.
>>>>> The C code is a wrapper code that internally calls some syslog-ng library 
>>>>> apis'
>>>>> 
>>>>> What I observed is:
>>>>> 
>>>>> 1)As soon as I call LoadPatternDB() method in parser.go there is some 
>>>>> increase in memory consumption(some memory leak).Ideally that should not 
>>>>> have happened.
>>>>> 
>>>>> 2)To verify if the C code had some issue, I called the C wrapper code 
>>>>> method 'load_pattern_db' from my main.c in the following manner to 
>>>>> completely eliminate Go code here.What I found is there is no increase in 
>>>>> memory consumption after every call ('load_pattern_db' was called 5 
>>>>> times).Hence there is no memory leak from C code.So the issue lies in the 
>>>>> Go code in 'LoadPatternDB' method in parser.go
>>>>> 
>>>>> main.c
>>>>> =======
>>>>> 
>>>>> void check(char *key, char *value, size_t value_len)
>>>>> {
>>>>>   printf("I am in function check\n");
>>>>> }
>>>>> 
>>>>> int main(void){
>>>>>         char* filename = "/home/nitish/default.xml";
>>>>>         key_value_cb s = check;
>>>>>         int i;
>>>>>     for (i=1; i<=5; i++)
>>>>>     {
>>>>>         load_pattern_db(filename, s);
>>>>>         printf("Sleeping for 5 second.\n");
>>>>>         sleep(5);
>>>>>     }
>>>>>     printf("Loading done 5 times.\n");
>>>>>         return 0;
>>>>> }
>>>>> 
>>>>> 3)Can someone please guide me and help me figure out the mem-leak in 
>>>>> 'LoadPatternDB' method in parser.go at very first glance? Is the callback 
>>>>> function pointer an issue here ?
>>>>> 
>>>>> 4)What tool can I use to check this mem-leak ?
>>>>> 
>>>>> Thanks,
>>>>> Nitish
>>>>> -- 
>>>>> 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/CALjMrq5cAJ19CQ8OmMPSJmVB1P3t4hE0CKZ4HsEsH-mp6zm3Ng%40mail.gmail.com.
>>>> -- 
>>>> --
>>>>   Gregor Best
>>>>   b...@pferdewetten.de
>>>> -- 
>>>> 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/fee07a13-e3d7-4a2e-6a6c-fdb11140ce21%40pferdewetten.de.
>>> 
>>> -- 
>>> 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/CALjMrq4-%3DcsuKRP4Xa-MVgrm5MJdWLNVe0v5_i3jswjesHQTqA%40mail.gmail.com.

-- 
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/02BB1DD2-0168-452A-A978-A43FAEE38107%40ix.netcom.com.

Reply via email to