Skip to content


The last GUADEC post?

GUADEC‘s over (and has been so for a while) and was great. The talk videos are up, and still I haven’t blogged about the conference. Naughty me.

The conference was great: it was good to meet up with friends (old and new) again, get a bit of hacking done and hear lots of discussion about the future of GNOME. My thanks to the GNOME Foundation and my summer employer, Collabora, for sponsoring my accommodation and travel. Thank you to the local team for organising a brilliant GUADEC in a nice city, and here’s to a successful GCDS 2011 in Berlin!

In other news, I’ve finally got fed up with forgetting to add new files in my project to either the project-wide header file or the documentation index, so I wrote some `make check` rules which will check for my braindeadness:

This one goes in the Makefile.am in the directory which builds your public header (such as gtk/gtk.h), and assumes a list of all the headers you’re going to install is in public_headers, and that your main header’s path is in main_header.

check-local: check-headers
check-headers:
	@any_missing=0; for header_file in $(public_headers); do \
		if test "x$$header_file" != "x$(main_header)"; then \
			if ! grep "#include <$$header_file>" $(main_header) >/dev/null; then \
				echo "$(main_header) doesn't appear to include \"$$header_file\""; \
				any_missing=1; \
			fi; \
		fi; \
	done; exit "$$any_missing"

This one goes in the Makefile.am in your gtk-doc directory (e.g. docs/reference), and only assumes the existence of DOC_MAIN_SGML_FILE, which needs to be defined for gtk-doc anyway.

check-local: check-xml-includes
check-xml-includes:
	@any_missing=0; find $(srcdir) -name "*.xml" | while read x; do \
		xml_file="$${x#./}"; \
		if test "x$$xml_file" != "x$(DOC_MAIN_SGML_FILE)"; then \
			if ! grep "\"$$xml_file\"" $(DOC_MAIN_SGML_FILE) >/dev/null; then \
				echo "$(DOC_MAIN_SGML_FILE) doesn't appear to include \"$$xml_file\""; \
				any_missing=1; \
			fi; \
		fi; \
	done; exit "$$any_missing"

I’ve filed bgo#627920 about adding the second rule to gtk-doc itself. I’m not sure the first rule is general enough to be put anywhere common.

Posted in GNOME.

Tagged with , , , .


GUADEC’s nearly here!

Less than a week from now GUADEC 2010 will have started: a week of talks, work and partying in The Hague! This doesn’t happen by magic, though, and we’re still looking for volunteers to help the week run smoothly. We need just a few more heralds, particularly for Thursday and Friday, to announce each speaker, keep time, ensure that the speaker has what they need, and help out with the changeover between speakers. Volunteering to herald for just one morning or afternoon would be a great help, and the only requirement is that you can spend the entirety of that morning or afternoon in one room. With the interesting talks on this year’s schedule, this should be possible!

If you want to help out but don’t fancy heralding, there’s always more which can be done! In either case, please leave a comment below or e-mail guadec-list {at} gnome(.)org with your availability.

I am attending GUADEC

Posted in GNOME.

Tagged with .


Reference count debugging with systemtap

I got some really helpful comments on yesterday’s post about reference count debugging with gdb which enabled me to get systemtap working.

Getting systemtap working (on Fedora 13)

Install the systemtap-* and kernel-devel packages as per the instructions on the systemtap wiki. Note that the kernel packages need to be for the same version as the kernel you’re currently running. I got caught out by this since I hadn’t rebooted since I last downloaded an updated kernel package. You then need to add yourself to the stapdev and stapusr groups. Run the command stap -v -e 'probe vfs.read {printf("read performed\n"); exit()}' to test whether everything’s installed and working properly. systemtap might ask you to run a make command at this point, which you need to do.

Writing systemtap probes

The probe I’m using to sort out referencing issues is the following, based off the examples Alex Larsson gave when static probes were initially added to GLib and GObject. I’ve saved it as refs.stp:

global alive
global my_object = "FooObject"

probe gobject.object_new {
	if (type == my_object)
		alive++
}

probe gobject.object_ref {
	if (type == my_object) {
		printf ("%s %p ref (%u)\n", type, object, refcount)
		print_ubacktrace_brief ()
		printf ("\n")
	}
}

probe gobject.object_unref {
	if (type == my_object) {
		printf ("%s %p unref (%u)\n", type, object, old_refcount)
		print_ubacktrace_brief ()
		printf ("\n")

		if (old_refcount == 1)
			alive--
	}
}

probe end {
	printf ("Alive objects: \n")
	if (alive > 0)
		printf ("%d\t%s\n", alive, my_object)
}

This counts how many instances of the FooObject class are created (using a probe on g_object_new()) and destroyed (probing on g_object_unref() and decrementing the alive counter when the last reference is dropped). References and dereferences are also counted, with a short backtrace being outputted for each, which is the key thing I was looking for when debugging reference counting problems.

Using the probes

I was debugging problems in Empathy, so I had to use the following command:

stap refs.stp \
-d ${libdir}/libfolks.so \
-d ${libdir}/libfolks-telepathy.so \
-d ${libdir}/libglib-2.0.so \
-d ${libdir}/libgobject-2.0.so \
-d ${libdir}/libgee.so \
-d ${libdir}/libgtk-x11-2.0.so \
-d ${bindir}/empathy \
-c "${bindir}/empathy"

Each -d option tells systemtap to load unwind data from the given library or executable, which is the key thing I was missing yesterday; these options are necessary for the backtraces to be useful, since systemtap stops unwinding a backtrace at the first frame it can’t map to a symbol name. Note that it’s necessary to explicitly tell systemtap to load data from the empathy executable, even though it then runs Empathy to trace it.

This gives output like the following when tracing the EmpathyMainWindow object:

EmpathyIndividualStore 0x09c05a10 ref (2)
g_object_ref+0x138
g_value_object_collect_value+0xe0
g_value_set_instance+0x190
.L1016+0x1e0
g_signal_emit_by_name+0x165
gtk_tree_sortable_sort_column_changed+0x78
gtk_tree_store_set_sort_column_id+0xde
gtk_tree_sortable_set_sort_column_id+0xe6
empathy_individual_store_set_sort_criterium+0x108
individual_store_setup+0x162
empathy_individual_store_init+0xb0
g_type_create_instance+0x1c3
g_object_constructor+0x1d
g_object_newv+0x438
.L345+0xfd
g_object_new+0x8d
empathy_individual_store_new+0xb6
empathy_main_window_init+0x890
g_type_create_instance+0x1c3
g_object_constructor+0x1d
empathy_main_window_constructor+0x4c

EmpathyIndividualStore 0x09c05a10 unref (2)
g_object_unref+0x13f
g_value_object_free_value+0x2a
g_value_unset+0x6d
.L1041+0x100
g_signal_emit_by_name+0x165
gtk_tree_sortable_sort_column_changed+0x78
gtk_tree_store_set_sort_column_id+0xde
gtk_tree_sortable_set_sort_column_id+0xe6
empathy_individual_store_set_sort_criterium+0x108
individual_store_setup+0x162
empathy_individual_store_init+0xb0
g_type_create_instance+0x1c3
g_object_constructor+0x1d
g_object_newv+0x438
.L345+0xfd
g_object_new+0x8d
empathy_individual_store_new+0xb6
empathy_main_window_init+0x890
g_type_create_instance+0x1c3
g_object_constructor+0x1d
empathy_main_window_constructor+0x4c

The only thing I need to do now is to figure out how to script systemtap so that it indents each backtrace nicely according to the reference count of the object.

Posted in GNOME, Tutorials.

Tagged with , , .


Reference count debugging with gdb

As I was hacking today, I ran into some hard-to-debug reference counting problems with one of my classes. The normal smattering of printf()s didn’t help, and neither did this newfangled systemtap, which was a bit disappointing.

It worked, in that my probes were correctly run and correctly highlighted each reference/dereference of the class I was interested in, but printing a backtrace only extended to the g_object_ref()/g_object_unref() call, and no further. I’m guessing this was a problem with the location of the debug symbols for my code (since it was in a development prefix, whereas systemtap was not), but it might be that systemtap hasn’t quite finished userspace stuff yet. That’s what I read, at least.

In the end, I ended up using conditional breakpoints in gdb. This was a lot slower than systemtap, but it worked. It’s the sort of thing I would’ve killed to know a few years (or even a few months) ago, so hopefully it’s useful for someone (even if it’s not the most elegant solution out there).

set pagination off
set $foo=0
break main
run

break g_object_ref
condition 2 _object==$foo
commands
	silent
	bt 8
	cont
	end

break g_object_unref
condition 3 _object==$foo
commands
	silent
	bt 8
	cont
	end

break my_object_init
commands
	silent
	set $foo=my_object
	cont
	end
enable once 4
cont

The breakpoint in main() is to stop gdb discarding our breakpoints out of hand because the relevant libraries haven’t been loaded yet. $foo contains the address of the first instance of MyObject in the program; if you need to trace the n+1th instance, use ignore 4 n to only fire the my_object_init breakpoint on the n+1th MyObject instantiation.

This can be extended to track (a fixed number of) multiple instances of the object, by using several $fooi variables and gdb’s if statements to set them as appropriate. This is left as an exercise to the reader!

I welcome the inevitable feedback and criticism of this approach. It’s hacky, ugly and slower than systemtap, but at least it works.

Posted in GNOME, Tutorials.

Tagged with , , .


Helping out at GUADEC 2010

GUADEC‘s approaching fast, and we’re looking for volunteers to act as heralds in each room; announcing each speaker, keeping time, ensuring that the speaker has what they need, and helping out with the changeover between speakers.

Volunteers are needed for the three main rooms (Paris, Copenhagen and Seville) for the three core days of GUADEC, plus for the GNOME Open Desktop Day in the Seville room. Each heralding slot is half a day long, which you’d spend in one room, attending to the talks for that morning or afternoon. We’re flexible about which rooms people are assigned to, so if you want to help out but don’t want to miss a particular talk, we can try and get you heralding in the right room for it!

Anybody who helps out with heralding will get a warm fuzzy feeling and an exclusive shiny new t-shirt. If you want your very own warm fuzzy feeling (and t-shirt), please leave a comment below or e-mail guadec-list {at} gnome(.)org with your availability and any preference you have as to rooms or times.

I am attending GUADEC

Posted in GNOME.


Totem and libpeas

I’ve just released Totem 2.90.0 after some person conned me into rolling the tarball. This release is notable because Totem’s now been ported to use libpeas for plugin handling. This allowed us to eliminate a lot of the old plugin handling code, but unfortunately it means that Python and Vala plugins don’t work any more. We’re working on this (when we’re not reading comics).

Posted in GNOME.

Tagged with , .


Unicode in Python

Now that exams are finally over, I can spend more time on GNOMEy things. One problem which has been sitting on my to-do list for a while is that of translatable Unicode strings in Python. It appears that my patch in bug #591496 to get Hamster to use Unicode em-dashes inadvertently broke translation of the strings. Whoops.

It turns out that in order for gettext to properly match and translate a C-locale string which contains Unicode characters, the encoding of the Python file must be specified using a coding: line at the top of the file, and the string in question must be a Unicode object. For example:

# -*- coding: utf-8 -*-
…
import gettext
gettext.textdomain('myapp')
…
my_translated_string = gettext.gettext(u'My Unicode string…')
…

I don’t think this is too common a problem, and I’ve checked that it doesn’t affect any of the other Python modules I’ve fiddled with, but hopefully this will be useful to someone. As far as I understand it, all translatable strings in Python modules should be u'Unicode objects rather than normal strings' anyway, ideally, but don’t take my word on it because my Python-fu is weak.

Posted in GNOME.

Tagged with , , , .


GUADEC!

Thanks to the generous sponsorship of the GNOME Foundation, I’m going to GUADEC this year! Thanks to all those involved in funding and sorting out travel sponsorship.I am attending GUADEC
Sponsored by the GNOME Foundation

Posted in GNOME.

Tagged with , .


Evolution kicks the libgdata-google habit

So, after a year of blood, sweat and tears repeatedly appearing at exactly the wrong time to get my patches in, I’ve finally managed to commit my patches to Evolution and evolution-data-server to port it to use libgdata rather than its home-grown libgdata-google library. Since Evolution has switched to using CalDAV for its Google Calendar backend, libgdata is just used for the Google Contacts backend. This is the first outing into the big scary world of popular usage for libgdata’s Google Contacts support, so any and all testing of the changes would be appreciated.

In the meantime, I’ll get back to looking at adding support for any additional features/contact fields I can to the Google Contacts backend.

Posted in GNOME.

Tagged with , , .


Use of the pure attribute for GObject convenience getters

In my quest to make my code completely correct and beautiful, largely through the liberal application of obscure and anal-retentive attributes like __warn_unused_result__ and __malloc__, I’ve hit a problem. Is it safe and correct to use __pure__ with GObject convenience getter functions?

As far as the literature explains it, “pure” C functions (no relation to pure mathematical or functional functions) can access pointers and global memory, but must not write to them, and cannot use system resources. In return, gcc can apply extra optimisations to calls to pure functions, since it can assume the return value of a pure function (for a given set of arguments) will not change, no matter how many times the function is called, until memory is written or a non-pure function is called. This allows for elimination of redundant calls to pure functions (since they’re known to not have any side-effects) or, conversely, for gcc to add in calls to a pure function in preference to storing the result in memory, if it thinks that will perform better. Furthermore, gcc can perform loop optimisations on loops which just use pure functions.

This is all good, and I think I’ve done a good job of regurgitating the gcc manual here, but it doesn’t answer the question. There are loads of GObject-based libraries out there, and none of them (as far as I can tell) are using pure convenience getters. I must be missing something from the wisdom of the masses.

The only situation I can think of where using the __pure__ attribute on a convenience getter function could result in incorrect code is if the object in question is modified from a thread (2) other than the one (1) calling the getter. For example, thread 1′s frobnicate() function calls my_object_get_property_foo() a couple of times in a function at the same time as thread 2 calls my_object_set_property_foo(). Normally, let’s say, the first call to my_object_get_property_foo() would return the old value, and the second call would return the new value. If my_object_get_property_foo() was a pure function, though, the compiler could potentially optimise out the second call, and so thread 1 would never see the new value of the “foo” property.

There are fairly few places where this is the desired behaviour with or without use of __pure__, though. The frobnicate() function is likely to have locking in this situation, which would prevent the race condition as normal, while still allowing the compiler to optimise out some of the calls to the pure my_object_get_property_foo() function.

In summary, what I’m proposing is that people use the G_GNUC_PURE attribute on their GObject convenience getter functions as much as appropriate. From my tests adding the attribute to functions in libgdata, it doesn’t make much of a difference in performance but does reduce the code size of applications which use libgdata. (These tests weren’t particularly thorough, though; they were actually just done against one function, looking at the disassembly of a test program which called it.)

Just as an example, here’s a pure convenience getter function I wrote earlier:

GList *gdata_entry_get_categories (GDataEntry *self) G_GNUC_PURE;

GList *
gdata_entry_get_categories (GDataEntry *self)
{
	g_return_val_if_fail (GDATA_IS_ENTRY (self), NULL);
	return self->priv->categories;
}

On another note, that return type should really be const GList*, but GLib’s list functions aren’t const-correct.

Posted in GNOME.

Tagged with , , , , .