Bug 716447

Summary: glib2 problem: hash table collisions
Product: Red Hat Enterprise Linux 5 Reporter: Jose Pedro Oliveira <jose.p.oliveira.oss>
Component: glib2Assignee: Colin Walters <walters>
Status: CLOSED WONTFIX QA Contact: desktop-bugs <desktop-bugs>
Severity: high Docs Contact:
Priority: unspecified    
Version: 5.6CC: jose.p.oliveira.oss, rfranknj
Target Milestone: rc   
Target Release: ---   
Hardware: Unspecified   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2014-06-02 13:05:57 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:

Description Jose Pedro Oliveira 2011-06-24 13:42:54 UTC
Description of problem:
The test suite of syslog-ng (bug 714409 comments 4 to 7) exposes 
collisions problems in the GHashTable implementation of glib2-2.12.3.

Version-Release number of selected component (if applicable):
glib2-2.12.3-4

How reproducible:
Always.

Steps to Reproduce:
See example code below.
  
Actual results:
Collisions.

Expected results:
No collisions (eg: glib2-2.22.5, glib2-2.28).


Example code that exposes the problem:
----------
#include <stdio.h>
#include <glib.h>

// gcc -Wall -Wextra `pkg-config glib-2.0 --cflags` `pkg-config glib-2.0
--libs` ghashtable.c

void insert(GHashTable *name_map, const gchar *name)
{
    printf("hash insert: key = <%s>: ", name);

    gpointer p = g_hash_table_lookup(name_map, name);
    if (p) {
        printf("found (ARGH)\n");
    } else {
        printf("not found\n");
        g_hash_table_insert(name_map, (gpointer)name, (gpointer)name);
    }
}

int main(void)
{
    int i;
    GHashTable *h = g_hash_table_new(g_str_hash, g_str_equal);
    for (i = 4; i < 15; i++) {
        gchar dyn_name[16];
        g_snprintf(dyn_name, sizeof(dyn_name), "DYN%05d", i);
        insert(h, dyn_name);
    }
    printf("There are %d keys in the hash\n", g_hash_table_size(h));
    g_hash_table_destroy(h);
    return 0;
}
----------



Program output in EPEL 5 (glib2-devel-2.12.3-4):
----------
hash insert: key = <DYN00004>: not found
hash insert: key = <DYN00005>: not found
hash insert: key = <DYN00006>: not found
hash insert: key = <DYN00007>: not found
hash insert: key = <DYN00008>: not found
hash insert: key = <DYN00009>: not found
hash insert: key = <DYN00010>: found (ARGH)
hash insert: key = <DYN00011>: not found
hash insert: key = <DYN00012>: not found
hash insert: key = <DYN00013>: not found
hash insert: key = <DYN00014>: not found
There are 10 keys in the hash
----------

Program output in EPEL 6 (glib2-devel-2.22.5-5) or in Fedora 15
(glib2-devel-2.28.8-1)
----------
hash insert: key = <DYN00004>: not found
hash insert: key = <DYN00005>: not found
hash insert: key = <DYN00006>: not found
hash insert: key = <DYN00007>: not found
hash insert: key = <DYN00008>: not found
hash insert: key = <DYN00009>: not found
hash insert: key = <DYN00010>: not found
hash insert: key = <DYN00011>: not found
hash insert: key = <DYN00012>: not found
hash insert: key = <DYN00013>: not found
hash insert: key = <DYN00014>: not found
There are 11 keys in the hash
----------

Comment 1 Jose Pedro Oliveira 2011-10-26 15:04:09 UTC
This ticket can be closed (not a RHEL5 glib2 problem).


The above example, showing similar behavior as the problematic syslog-ng test, is buggy: the keys/values inserted aren't being kept during the hash lifetime (missing at leat one g_strdup() before the hash_insert).

----------
-        g_hash_table_insert(name_map, (gpointer)name, (gpointer)name);
+        gchar *dupname = g_strdup(name);
+        g_hash_table_insert(name_map, (gpointer)dupname, (gpointer)dupname);
----------


From the glib2 documentation:
...
Note that neither keys nor values are copied when inserted into the GHashTable, so they must exist for the lifetime of the GHashTable. This means that the use of static strings is OK, but temporary strings (i.e. those created in buffers and those returned by GTK+ widgets) should be copied with g_strdup() before being inserted.

If keys or values are dynamically allocated, you must be careful to ensure that they are freed when they are removed from the GHashTable, and also when they are overwritten by new insertions into the GHashTable. It is also not advisable to mix static strings and dynamically-allocated strings in a GHashTable, because it then becomes difficult to determine whether the string should be freed. 
...

Comment 4 RHEL Program Management 2014-03-07 13:37:43 UTC
This bug/component is not included in scope for RHEL-5.11.0 which is the last RHEL5 minor release. This Bugzilla will soon be CLOSED as WONTFIX (at the end of RHEL5.11 development phase (Apr 22, 2014)). Please contact your account manager or support representative in case you need to escalate this bug.

Comment 5 RHEL Program Management 2014-06-02 13:05:57 UTC
Thank you for submitting this request for inclusion in Red Hat Enterprise Linux 5. We've carefully evaluated the request, but are unable to include it in RHEL5 stream. If the issue is critical for your business, please provide additional business justification through the appropriate support channels (https://access.redhat.com/site/support).

Comment 6 Red Hat Bugzilla 2023-09-14 01:24:05 UTC
The needinfo request[s] on this closed bug have been removed as they have been unresolved for 1000 days