From: Marco Trevisan (TreviƱo) <mail@3v1n0.net>
authorraster <raster@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Sun, 5 Dec 2010 03:14:03 +0000 (03:14 +0000)
committerraster <raster@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Sun, 5 Dec 2010 03:14:03 +0000 (03:14 +0000)
Subject: [E-devel] [PATCH] eina share common check for node type

Hello, recentely I've been experiencing a lot of segfaults when running
an Elementary application which uses a genlist with some swallowed parts
in which I put some elm icons (png files).
When running it I often get crashes... Debugging it I found this:

=========
CRI<14207>: eina_share_common.c:561 _eina_share_common_node_from_str()
*** Eina Magic Check Failed !!!
    Input handle is wrong type
        Expected: 98761254 - Eina Stringshare Node
            Supplied: 6e657070 - (unknown)
            *** NAUGHTY PROGRAMMER!!!
            *** SPANK SPANK SPANK!!!
            *** Now go fix your code. Tut tut tut!

            //DEBUG: Node referencies 622869060 (slen: 1145307236)

            Program received signal SIGSEGV, Segmentation fault.
            eina_share_common_del (share=0x65c810, str=0x7ffff1219150
"5hhu %5hu '%
s'\n")
    at eina_share_common.c:858
    858        node->references--;
    =========

    So it seems that edje tries to delete an invalid eina_share_common
    string (is this a bug that should be fixed or is it
theme-dependent?),
and so the "node" pointer in eina share is not valid...

However eina never checks for its validity, so it seg-faults...
The attached patch fix this issue, setting the node to null when its
magic is not valid, and then always checking for its validity.

Is this fine?

Full stack trace:

#0  eina_share_common_del (share=0x65c810, str=0x7ffff1219150 "5hhu %5hu
'%s'\n")
    at eina_share_common.c:858
    #1  0x00007ffff120e047 in eina_stringshare_del (str=0x7ffff1219150
"5hhu
%5hu '%s'\n")
    at eina_stringshare.c:632
    #2  0x00007ffff1e1f7bc in _edje_text_recalc_apply (ed=0x95b900,
    ep=0x70c3a0,
        params=0x70c500, chosen_desc=<value optimized out>) at
        edje_text.c:556
        #3  0x00007ffff1de402d in _edje_part_recalc (ed=0x95b900,
ep=0x70c3a0,
flags=3)
    at edje_calc.c:2007
    #4  0x00007ffff1de4d86 in _edje_recalc_do (ed=0x95b900) at
    edje_calc.c:268
    #5  0x00007ffff1e25c7d in edje_object_part_swallow (obj=<value
optimized
out>,
    part=0x7fffe001484c "elm.swallow.icon", obj_swallow=0x7fffe0017860)
        at edje_util.c:2300
        #6  0x00007ffff1b5d5fc in _item_realize (it=0x7fffe0016ed0,
in=10,
calc=1)
    at elm_genlist.c:1489
    #7  0x00007ffff1b5db89 in _item_block_recalc (itb=0x95b6a0,
in=<value
optimized out>,
    qadd=<value optimized out>, norender=<value optimized out>) at
    elm_genlist.c:1609
    #8  0x00007ffff1b5e329 in _queue_proecess (wd=0x721b70,
norender=<value
optimized out>)
    at elm_genlist.c:2425
    #9  0x00007ffff1b5e567 in _item_queue (wd=0x721b70, it=<value
optimized
out>)
    at elm_genlist.c:2476
    #10 0x00007ffff1b5ead9 in elm_genlist_item_append (obj=<value
optimized
out>,
    itc=0x7ffff2977040, data=0x8fed90, parent=0x0,
    flags=ELM_GENLIST_ITEM_NONE,
        func=<value optimized out>, func_data=0x0) at elm_genlist.c:2528

        [eina-share-common-del-check-for-node.patch  text/x-patch
(1.2KB)]
Index: src/lib/eina_share_common.c
===================================================================
--- src/lib/eina_share_common.c(revisione 55018)
+++ src/lib/eina_share_common.c(copia locale)
@@ -558,7 +558,7 @@
    const size_t offset = offsetof(Eina_Share_Common_Node, str);

         node = (Eina_Share_Common_Node *)(str - offset);
         -   EINA_MAGIC_CHECK_SHARE_COMMON_NODE(node, node_magic, );
         +   EINA_MAGIC_CHECK_SHARE_COMMON_NODE(node, node_magic, node
= NULL);
    return node;

         (void) node_magic; /* When magic are disable, node_magic is
unused, this remove a warning. */
@@ -821,6 +821,7 @@

     SHARE_COMMON_LOCK_BIG();
         node = _eina_share_common_node_from_str(str,
share->node_magic);
+   if (!node) return str;
    node->references++;
        DBG("str=%p refs=%u", str, node->references);

         @@ -847,6 +848,9 @@
             SHARE_COMMON_LOCK_BIG();

                  node = _eina_share_common_node_from_str(str,
share->node_magic);
+   if (!node)
+      return;
+
    slen = node->length;
        eina_share_common_population_del(share, slen);
            if (node->references > 1)
            @@ -901,6 +905,7 @@
                   return -1;

                        node = _eina_share_common_node_from_str(str,
share->node_magic);
+   if (!node) return 0;
    return node->length;
     }

git-svn-id: svn+ssh://svn.enlightenment.org/var/svn/e/trunk/eina@55265 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33

src/lib/eina_share_common.c

index 2302843..bacd94a 100644 (file)
@@ -558,7 +558,7 @@ _eina_share_common_node_from_str(const char *str, Eina_Magic node_magic)
    const size_t offset = offsetof(Eina_Share_Common_Node, str);
 
    node = (Eina_Share_Common_Node *)(str - offset);
-   EINA_MAGIC_CHECK_SHARE_COMMON_NODE(node, node_magic, );
+   EINA_MAGIC_CHECK_SHARE_COMMON_NODE(node, node_magic, node = NULL);
    return node;
 
    (void) node_magic; /* When magic are disable, node_magic is unused, this remove a warning. */
@@ -821,6 +821,7 @@ eina_share_common_ref(Eina_Share *share, const char *str)
 
    SHARE_COMMON_LOCK_BIG();
    node = _eina_share_common_node_from_str(str, share->node_magic);
+   if (!node) return str;
    node->references++;
    DBG("str=%p refs=%u", str, node->references);
 
@@ -847,6 +848,9 @@ eina_share_common_del(Eina_Share *share, const char *str)
    SHARE_COMMON_LOCK_BIG();
 
    node = _eina_share_common_node_from_str(str, share->node_magic);
+   if (!node)
+      return;
+
    slen = node->length;
    eina_share_common_population_del(share, slen);
    if (node->references > 1)
@@ -901,6 +905,7 @@ eina_share_common_length(__UNUSED__ Eina_Share *share, const char *str)
       return -1;
 
    node = _eina_share_common_node_from_str(str, share->node_magic);
+   if (!node) return 0;
    return node->length;
 }