Fanciful memory management

/* gcc -Wall -Werror -o references `pkg-config --cflags --libs
   gstreamer-0.10` references.c */

#include <gst/gst.h>
#include <glib-object.h>

int main(int argc, char *argv[])
{
  GstElement *old_object, *object;

  gst_init(&argc, &argv);

  object = gst_element_factory_make("playbin2", "playbin");
  old_object = object;
  g_object_unref(object);
  object = gst_element_factory_make("playbin2", "playbin");

  g_print("old_object: %pn", old_object);
  g_print("object: %pn", object);
  if (old_object == object) {
    g_print("pointers are the same!n");
  }

  return 0;
}

In this code, as you can see we alloc an object, keep the pointer in another variable, release it and then alloc it again. Then we print those pointers and the surprise sentence if they are the same. Let’s see what I got from running this program:

$ ./references
old_object: 0x63f6e0
object: 0x63f6e0
pointers are the same!

Then I decided to disable G_SLICE and I got:

$ G_SLICE=always-malloc,debug-blocks ./references
old_object: 0x81dfa0
object: 0x81df60

There were even some occasions where I had the opposite in both cases, though I guess it is easier that this happens with G_SLICE as it is designed to optimize memory management and this would be like an easy case. In other cases, I guess having the same pointer happens because of the kernel.

The thing is that if you are debugging object references, you need to pay attention to pointer itself as sometimes you can get to wrong conclusions.

Example 1: let’s say that you get something meaningful as reference count for the old object. It could be that there is some missing reference elsewhere, though if the pointer is the same as the new one, it has been released (unless somebody replaced your old pointer) and reasigned again for the new object.

Example 2: let’s say that you get garbage, then your object is released and the memory has been overwritten (or you would have a bigger problem). You could easily get a segfault if the memory has been claimed by the kernel.

Example 3: let’s say that you get 0, then it has been released and maybe not rewritten, though maybe somewhere else somebody wrote a 0 there. It could be claimed by the kernel (or GSlice) or not, but if it has been, you can easily get a segfault.

One comment

Leave a Reply

Your email address will not be published. Required fields are marked *

What is 11 + 4 ?
Please leave these two fields as-is:
IMPORTANT! To be able to proceed, you need to solve the following simple math (so we know that you are a human) :-)