[Mono-list] Gtk.TreeStore crashes the GTK mainloop

Haakon Nilsen haakonn@gmail.com
Wed, 4 Aug 2004 01:15:42 +0200


Hi,

I'm having a very strange problem with my gtk-sharp application. I
have a Gtk.TreeView that shows a directory tree from the filesystem. I
get a list of paths as input and construct a TreeStore from that, with
a simple recursive method. The TreeStore/View has columns for filename
and filesize. The TreeStore is then set as the Model for the TreeView.

This has worked fine until today, when I noticed one particular
dataset that would make it crash. There's nothing wrong with the input
itself, except that while most other inputs contains maybe 50-500
lines of paths, this one had over 8000.

Constructing the TreeStore goes as planned. I've checked that method
countless times, and it's fine. I set it as Model for the TreeView,
and you can see it being drawn. The method which does all this
(including calling the TreeStore-constructing method) exits with no
errors, and one or two seconds passes, and then -- BAM:

Unhandled Exception: System.NullReferenceException: Object reference
not set to an instance of an object
in <0x0000a> GtkSharp.DestroyNotifyWrapper:NativeCallback (intptr)
in <0x0005f> (wrapper native-to-managed)
GtkSharp.DestroyNotifyWrapper:NativeCallback (intptr)
in (unmanaged) (wrapper managed-to-native) GLib.Object:g_object_unref (intptr)
in <0x00004> (wrapper managed-to-native) GLib.Object:g_object_unref (intptr)
in <0x0012f> GLib.Object:PerformQueuedUnrefs ()
in <0x0002a> (wrapper native-to-managed) GLib.Object:PerformQueuedUnrefs ()
in (unmanaged) (wrapper managed-to-native) Gtk.Application:gtk_main ()
in <0x00004> (wrapper managed-to-native) Gtk.Application:gtk_main ()
in <0x00007> Gtk.Application:Run ()
in [0x000e9] (at
/home/haakon/MonoDevelopProjects/archibald/archibald/archibald.cs:117)
ArchLinux.Archibald.Archibald:.ctor ()
in [0x00000] (at
/home/haakon/MonoDevelopProjects/archibald/archibald/archibald.cs:86)
ArchLinux.Archibald.Archibald:Main (string[])

I'm quite a mono/c#/gtk/gtk-sharp newbie, but it looks to me like
that's the GTK mainloop crashing. The entire application shuts down,
of course.

Doing the old manual binary search on the size of the dataset, I
noticed that the highest number of lines (ie. rows) that would pass
with no crash, is 3990. I have made sure that it really is the number
of rows that's the problem, and not some faulty model values.

Just to try it, I wrote a small completely seperate program that fills
a TreeStore with 20 000 values and presents them in a TreeView. No
problem here.

The strange thing is that I don't have to involve the TreeView at all
to trigger the problem. It's enough simply to construct the TreeStore.
The symptoms are exactly equal.

For completeness, here's the method that builds the TreeStore. It's
called repeatedly (with the same store and iters args) for each line
of input (containing a filesystem path). I've checked for null values
all over it, and they just don't occur.

The method works "upwards" a path, so for "/foo/bar/baz", it recurs
all the way up to "/foo", enters that in the store and uses the
resulting TreeIter as parent on the way down again.

      private void BuildFilesTree (string filename, bool is_file,
TreeStore store, Hashtable iters) {
         string size;
         string full_filename = "/" + filename;
         is_file &= File.Exists (full_filename);
         if (is_file) {
            size = Util.FriendlySize (new FileInfo (full_filename).Length);
         } else {
            size = String.Empty;
         }
         int index = filename.LastIndexOf ('/');
         if (index > -1) {
            string prev = filename.Substring (0, index);
            if (!iters.ContainsKey (prev)) {
               BuildFilesTree (prev, false, store, iters);
            }
            TreeIter parent = (TreeIter) iters[prev];
            string teststr = filename.Substring (index + 1);
            TreeIter child = store.AppendValues (parent, teststr, size);
            iters[filename] = child;
         } else {
            TreeIter child = store.AppendValues (filename, String.Empty);
            iters[filename] = child;
         }
      }

Any input is appreciated; I'm at my wit's end here.

Thanks,
Haakon Nilsen.