[Lognorm] Race condition in deletion of json-objects with 'event.tags'

Pavel Levshin pavel at levshin.spb.ru
Mon Dec 8 23:50:14 CET 2014


Your analysis is most probably correct. As far as I remember, this 
object reuse was confusing to me. But there were no segfaults at the moment.

Object reuse is intended to reduce memory allocations/frees, which have 
big impact on performance. On the other side, locks are expensive too. 
Even unsuitable for the case.

Can you confirm that just duplication of event.tags solves your segfaults?


--
Pavel


07.12.2014 0:03, singh.janmejay:
> Little bit of an elaborate story.
>
> So, I was fighting a segfault for last few hours. It was happening in 
> freeing-up of msg. Here is backtrace (it was the same in many core-dumps):
>
> (gdb) bt
> #0  0x0000000100000019 in ?? ()
> #1  0x00007fa23ee9d536 in lh_table_free (t=0x7fa22a28bc70) at 
> linkhash.c:116
> #2  0x00007fa23ee9a6fd in json_object_object_delete 
> (jso=0x7fa22967bf50) at json_object.c:273
> #3  0x00007fa23ee9d536 in lh_table_free (t=0x7fa2009ac960) at 
> linkhash.c:116
> #4  0x00007fa23ee9a6fd in json_object_object_delete 
> (jso=0x7fa22dcd8a70) at json_object.c:273
> #5  0x000000000041bef7 in msgDestruct (ppThis=0x7fa2317f9b48) at msg.c:928
> #6  0x0000000000441bd4 in DeleteProcessedBatch (pThis=0xa7eb90, 
> pBatch=0xac35a8) at queue.c:1589
> #7  0x0000000000441c9e in DequeueConsumableElements (pThis=0xa7eb90, 
> pWti=0xac3570, piRemainingQueueSize=0x7fa2317f9bd8) at queue.c:1626
> #8  0x0000000000441e6d in DequeueConsumable (pThis=0xa7eb90, 
> pWti=0xac3570) at queue.c:1680
> #9  0x000000000044226c in DequeueForConsumer (pThis=0xa7eb90, 
> pWti=0xac3570) at queue.c:1821
> #10 0x0000000000442502 in ConsumerReg (pThis=0xa7eb90, pWti=0xac3570) 
> at queue.c:1875
> #11 0x000000000043d95a in wtiWorker (pThis=0xac3570) at wti.c:334
> #12 0x000000000043c51f in wtpWorker (arg=0xac3570) at wtp.c:389
> #13 0x00007fa23f6b6b50 in start_thread (arg=<optimized out>) at 
> pthread_create.c:304
> #14 0x00007fa23e7de7bd in clone () at 
> ../sysdeps/unix/sysv/linux/x86_64/clone.S:112
> #15 0x0000000000000000 in ?? ()
>
>
> Now, turns out, the thing lh_table_free is trying to free(#1), is 
> basically an object with several keys, and whenever it failed, it 
> failed on the last one. How do I know that?
>
> (gdb) up 1
> #1  0x00007fa23ee9d536 in lh_table_free (t=0x7fa22a28bc70) at 
> linkhash.c:116
> 116     linkhash.c: No such file or directory.
> (gdb) p *c
> $1 = {k = 0x7fa22dcd8a50, v = 0xa6bd20, next = 0x0, prev = 0x7fa22e93d490}
>
> And out of 2 rulebases(both being called for events of roughly the 
> same frequency), every single segfault was for the rulebase that was 
> using tags on rule.
>
> The rulebase in question had 2 rules, matching several fields, and 
> both rules had tags applied.
>
> Note that ln_normalize applies event.tags only when tags are present, 
> and insert of new key in json-c linked-hash-map goes in the end of the 
> linked-list (check lh_table_insert).
>
> So, this key-value pair was supposed to be 'event.tags' and 
> corresponding tags. The data that c was pointing to was garbled, so I 
> couldn't tell what the key actually is, but I can conclude it was 
> 'event.tags' based on size of objects. The garbling may be because the 
> memory allocated for key was reused(note key is freed-up before value, 
> check json_object_lh_entry_free). Considering it is allocated in a 
> different thread (when message is parsed using mmnormalize), it is 
> possible (as opposed to an object allocated in the same thread, using 
> the same virtual-address range from one thread only).
>
> Now, what makes it a race condition? Not that event.tags object in 
> ln_normalize is not duplicated, instead it is the same object with 
> incrementing reference count. Not freeing routine does the counter 
> check without locking or using atomic operation, check json_object_put.
>
> The only lock that msgDestruct has, is on msg->mut, which means 
> different messages being processed at the same time can get that lock 
> and concurrently try to free 'event.tags' object.
>
> With careful timing, some of them may concurrently decrement the 
> counter and one of them may free the object. Now segfault can happen 
> either because someone accesses it, or because someone tries to free 
> it again etc.
>
> For me, the segfault was reproducing every few hours.
>
> The solution is simple, we need to duplicate the event.tags object 
> instead of passing it on with incrementing reference count.
>
> I'll fix it, but before jumping to fix need another (few?) pairs of 
> eyes to check correctness in reasoning (to point out any mistakes in 
> analysis and ensure I haven't overlooked anything and misdiagnosed).
>
> Can someone please help validate/correct?
>
> -- 
> Regards,
> Janmejay
> http://codehunk.wordpress.com
>
>
> _______________________________________________
> Lognorm mailing list
> Lognorm at lists.adiscon.com
> http://lists.adiscon.net/mailman/listinfo/lognorm

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.adiscon.net/pipermail/lognorm/attachments/20141209/16d21602/attachment-0001.html>


More information about the Lognorm mailing list