Bug 187263
Summary: | g_list_remove() problem | ||
---|---|---|---|
Product: | [Fedora] Fedora | Reporter: | Paul Osmialowski <newchief> |
Component: | glib2 | Assignee: | Matthias Clasen <mclasen> |
Status: | CLOSED NOTABUG | QA Contact: | |
Severity: | medium | Docs Contact: | |
Priority: | medium | ||
Version: | 5 | ||
Target Milestone: | --- | ||
Target Release: | --- | ||
Hardware: | i386 | ||
OS: | Linux | ||
Whiteboard: | |||
Fixed In Version: | Doc Type: | Bug Fix | |
Doc Text: | Story Points: | --- | |
Clone Of: | Environment: | ||
Last Closed: | 2006-03-29 19:23:30 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
Paul Osmialowski
2006-03-29 17:23:42 UTC
g_list_remove does not free the data. It does free the list element, and has always done so. Most likely the problem is in your code. Can you try to distill it to a small testcase that still shows your problem ? The problem seems to be more complex. Example program works properly: #include <glib.h> #include <stddef.h> #include <stdlib.h> int main() { GList * list = NULL; void * my_resource = malloc(2048); list = g_list_append(list, my_resource); list = g_list_remove(list, my_resource); free(my_resource); return 0; } Affected function in Stage plugin looks like this: int stg_model_remove_property_callback( stg_model_t* mod, const char* propname, stg_property_callback_t callback ) { stg_property_t* prop = g_datalist_get_data( &mod->props, propname ); if( ! prop ) { PRINT_WARN2( "attempting to remove a callback from a nonexistent property (%s:%s)", mod->token, propname ); return 1; // error } // else // find our callback in the list of stg_cbarg_t GList* el = NULL; // scan the list for the first matching callback for( el = g_list_first( prop->callbacks); el; el = el->next ) { if( ((stg_cbarg_t*)el->data)->callback == callback ) break; } if( el ) // if we found the matching callback, remove it prop->callbacks = g_list_remove( prop->callbacks, el->data); if( el && el->data ) free( el->data ); // THIS CALL CAUSES PROGRAM TO CRASH return 0; //ok } Since we know free was called, the el pointer can't be NULL, so this condition must have been true: if( ((stg_cbarg_t*)el->data)->callback == callback ) break; so I may expect that el->data holds valid address of stg_cbarg_t object. How it could became invalud on free() call? Strangely, the problem wasn't seen before we've upgraded FC3 to FC5, and is not seen on our Gentoo machines with glib-2.8.6 well, the call to g_list_remove () will remove and free the first list element whose data matches el->data. If that is el, then you are using freed memory after that removal, and all bets are off. If you want to do things like this, you need to do somthing like if (el) { tmp = el->data; g_list_remove (prop->callbacks, tmp); if (tmp) free (tmp); } |