After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 540423 - unrecoverable error after g_seekable_truncate(seekable, 0, ...)
unrecoverable error after g_seekable_truncate(seekable, 0, ...)
Status: RESOLVED FIXED
Product: glib
Classification: Platform
Component: gio
2.16.x
Other Linux
: Normal normal
: ---
Assigned To: Alexander Larsson
gtkdev
Depends on:
Blocks:
 
 
Reported: 2008-06-27 06:07 UTC by Akira TAGOH
Modified: 2008-06-30 03:47 UTC
See Also:
GNOME target: ---
GNOME version: ---



Description Akira TAGOH 2008-06-27 06:07:00 UTC
after calling g_seekable_truncate with offset=0, that makes segfault when calling realloc happens next time. the object can't be reused.

$ cat t.c
#include <gio/gio.h>

int
main(void)
{
        GOutputStream *mo;
        GDataOutputStream *o;
        int i;
        GError *error = NULL;

        g_type_init();
        mo = g_memory_output_stream_new(NULL, 0, g_realloc, g_free);
        o = g_data_output_stream_new(mo);
        for (i = 0; i < 1000; i++)
                g_data_output_stream_put_byte(o, 1, NULL, NULL);
        g_seekable_truncate(G_SEEKABLE (mo), 0, NULL, &error);
        if (error)
                g_print("%s\n", error->message);
        for (i = 0; i < 2000; i++)
                g_data_output_stream_put_byte(o, 1, NULL, NULL);

        return 0;
}
$ gcc t.c `pkg-config --cflags --libs gio-2.0`
$ gdb ./a.out
GNU gdb Fedora (6.8-10.fc9)
Copyright (C) 2008 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu"...
(no debugging symbols found)
(gdb) r
Starting program: /home/tagoh/a.out 
warning: the debug information found in "/usr/lib/debug//lib64/libselinux.so.1.debug" does not match "/lib64/libselinux.so.1" (CRC mismatch).

warning: the debug information found in "/usr/lib/debug/lib64/libselinux.so.1.debug" does not match "/lib64/libselinux.so.1" (CRC mismatch).

Failed to resize memory output stream

Program received signal SIGSEGV, Segmentation fault.
_int_realloc (av=<value optimized out>, oldmem=<value optimized out>, 
    bytes=<value optimized out>) at malloc.c:4953
4953        INTERNAL_SIZE_T nextsize = chunksize(next);
Missing separate debuginfos, use: debuginfo-install libselinux.x86_64
(gdb) bt
  • #0 _int_realloc
    at malloc.c line 4953
  • #1 __libc_realloc
    at malloc.c line 3708
  • #2 IA__g_realloc
    at gmem.c line 170
  • #3 array_resize
    at gmemoryoutputstream.c line 309
  • #4 g_memory_output_stream_write
    at gmemoryoutputstream.c line 369
  • #5 IA__g_output_stream_write
    at goutputstream.c line 212
  • #6 IA__g_output_stream_write
    at goutputstream.c line 212
  • #7 IA__g_output_stream_write_all
    at goutputstream.c line 264
  • #8 IA__g_data_output_stream_put_byte
    at gdataoutputstream.c line 231
  • #9 main


Giving 0 to realloc(3) behaves like free(3). so

static gboolean
array_resize (GMemoryOutputStream  *ostream,
              gsize                 size,
	      gboolean              allow_partial,
              GError              **error)
{
...
  data = priv->realloc_fn (priv->data, size);

  if (!data) 
    {
      if (allow_partial &&
	  priv->pos < priv->len)
	return TRUE; /* Short write */
      
      g_set_error (error,
                   G_IO_ERROR,
                   G_IO_ERROR_NO_SPACE,
                   _("Failed to resize memory output stream"));
      return FALSE;
    }
...
}

priv->data has invalid pointer after calling priv->realloc_fn and no updates happens in this case.
Comment 1 Matthias Clasen 2008-06-30 03:47:36 UTC
2008-06-29  Matthias Clasen  <mclasen@redhat.com>

        * tests/Makefile.am:
        * tests/memory-output-stream.c: Add some tests for
        GMemoryOutputStream.

2008-06-29  Matthias Clasen  <mclasen@redhat.com>

        Bug 540423 – unrecoverable error after g_seekable_truncate(seekable,
        0, ...)

        * gmemoryoutputstream.c (array_resize): Handle truncation to
        zero correctly. Reported by Akira Tagoh