GNOME Bugzilla – Bug 527441
clock applet segfaults on archlinux where /etc/localtime is a copy instead of a symlink
Last modified: 2008-04-19 08:46:22 UTC
This is what happens when /etc/localtime is a copy instead of a symlink. This is the default case on archlinux. This happens with gnome-panel 2.22.1.2 and with the latest trunk changes to the clock applet. Distribution: Unknown Gnome Release: 2.22.1 2008-04-10 (Archlinux) BugBuddy Version: 2.22.0 System: Linux 2.6.24-ARCH #1 SMP PREEMPT Sun Mar 30 10:50:22 CEST 2008 x86_64 X Vendor: The X.Org Foundation X Vendor Release: 10400090 Selinux: No Accessibility: Disabled GTK+ Theme: Mist Icon Theme: gnome Memory status: size: 256204800 vsize: 256204800 resident: 17092608 share: 11730944 rss: 17092608 rss_rlim: 18446744073709551615 CPU usage: start_time: 1207865806 rtime: 8 utime: 6 stime: 2 cutime:0 cstime: 0 timeout: 0 it_real_value: 0 frequency: 100 Backtrace was generated from '/usr/libexec/clock-applet' Using host libthread_db library "/lib/libthread_db.so.1". [Thread debugging using libthread_db enabled] [New Thread 0x2b90180b7910 (LWP 6441)] 0x00002b901055c535 in waitpid () from /lib/libpthread.so.0
+ Trace 194886
Thread 1 (Thread 0x2b90180b7910 (LWP 6441))
----------- .xsession-errors (304 sec old) --------------------- ** Message: GetValue variable 2 (2) GCJ PLUGIN: thread 0x8832d0: NP_GetMIMEDescription GCJ PLUGIN: thread 0x8832d0: NP_GetMIMEDescription return GCJ PLUGIN: thread 0x8832d0: NP_GetValue GCJ PLUGIN: thread 0x8832d0: NP_GetValue: returning plugin name. GCJ PLUGIN: thread 0x8832d0: NP_GetValue return GCJ PLUGIN: thread 0x8832d0: NP_GetValue GCJ PLUGIN: thread 0x8832d0: NP_GetValue: returning plugin description. GCJ PLUGIN: thread 0x8832d0: NP_GetValue return LoadPlugin: failed to initialize shared library /usr/lib/mozilla/plugins/libflashplayer.so [/usr/lib/mozilla/plugins/libflashplayer.so: wrong ELF class: ELFCLASS32] CalDAV Eplugin starting up ... ** (evolution:6387): DEBUG: mailto URL command: evolution %s ** (evolution:6387): DEBUG: mailto URL program: evolution libnm_glib_nm_state_cb: dbus returned an error. (org.freedesktop.DBus.Error.ServiceUnknown) The name org.freedesktop.NetworkManager was not provided by any .service files --------------------------------------------------
valgrind reports an invalid read of size 1, strace shows that it traverses /usr/share/zoneinfo until the right zone (Europe/Amsterdam) is detected and crashes right after that: stat("/usr/share/zoneinfo/posix/Europe/Stockholm", {st_mode=S_IFREG|0644, st_size=1892, ...}) = 0 stat("/usr/share/zoneinfo/posix/Europe/Amsterdam", {st_mode=S_IFREG|0644, st_size=2917, ...}) = 0 open("/usr/share/zoneinfo/posix/Europe/Amsterdam", O_RDONLY) = 20 fstat(20, {st_mode=S_IFREG|0644, st_size=2917, ...}) = 0 read(20, "TZif2\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\r\0\0\0\r\0\0\0\0"..., 2917) = 2917 close(20) = 0 close(19) = 0 close(18) = 0 close(17) = 0 --- SIGSEGV (Segmentation fault) @ 0 (0) --- Some more gdb output:
+ Trace 194888
Line 786 is the g_ascii_isalnum() check in system_timezone_is_valid() for (c = tz; *c != '\0'; c++) { if (!(g_ascii_isalnum (*c) || *c == '/' || *c == '-' || *c == '_')) return FALSE; } Looks like tz is not NULL-terminated here.
In recursive_compare(): return g_strdup (file + strlen (SYSTEM_ZONEINFODIR"/")); While reading this, I assume this won't be NULL-terminated, I see a char* and integer value concatenated and duplicated into a string.
Hmm, ignore the last comment. C is not PHP or VB, strings are not concatenated with + in C, it's a pointer operation that strips off the /usr/share/zoneinfo/ part of the timezone.
Interesting. While I try to find the bug, I have one question for ArchLinux: is there a file somewhere giving the information about the system timezone? I've read that there might be a TIMEZONE key in /etc/rc.conf? Also interesting to see that the used file is from /usr/share/zoneinfo/posix/Europe/Stockholm. You don't have /usr/share/zoneinfo/Europe/Stockholm? I guess I should handle the posix/...
Archlinux sets TIMEZONE in /etc/rc.conf as "Europe/Amsterdam" as example for my own timezone setting. rc.conf is a bash script that is sourced by every /etc/rc.d/ bootscript and the rc.sysinit script that copies /usr/share/zoneinfo/$TIMEZONE to /etc/localtime (no idea why we don't symlink it though). About the /usr/share/zoneinfo entries: [root@jan ~]# pacman -Ql tzdata | grep Stockholm tzdata /usr/share/zoneinfo/Europe/Stockholm tzdata /usr/share/zoneinfo/posix/Europe/Stockholm tzdata /usr/share/zoneinfo/right/Europe/Stockholm The Europe/Stockholm and posix/Europe/Stockholm rules are equal, the right/Europe/Stockholm file is different. Note that these files are also present on a debian etch system, so it's normal to have these files.
Thanks. I'll add support for /etc/rc.conf after fixing the bug. I've committed something to strip the posix/, so we're now back to the bug. Back to the bug: I've checked, and when using the method to compare the content of the files, it perfectly works for me, and I don't have the valgrind error...
I tested code from svn trunk (rev 11051) compiled with gcc 4.3.0 (release) with "-march=x86_64 -O2 -pipe" as CFLAGS. using the trunk code, I still get this: 0x000000000041ff13 in system_timezone_find () at system-timezone.c:802 802 if (!(g_ascii_isalnum (*c) || (gdb) print *c Cannot access memory at address 0xff00ff (gdb) print c $3 = 16711935 I've been debugging a bit, removing CFLAGS from the Makefile for the clock applet, leaving only "-g", the applet doesn't crash anymore. Looks like a mis-optimization by gcc 4.3.0.
Note that you can easily compile a small test program (look at the system-timezone.c comments at the top) to debug this. If you update from trunk, please move system_timezone_read_etc_localtime_content at the top of get_system_timezone_methods since I've added support for Arch Linux. Marking as NEEDINFO for now. Feel free to close if you're sure it's a gcc bug. Sounds weird to have a gcc bug here, though...
With -O2: [jan@jan clock]$ gcc -O2 -g -DSYSTZ_GET_TEST -Wall -o system-timezone-get `pkg-config --cflags --libs glib-2.0 gobject-2.0 gio-2.0` system-timezone.c system-timezone.c: In function ‘system_timezone_write_key_file’: system-timezone.c:460: warning: passing argument 3 of ‘g_file_get_contents’ from incompatible pointer type system-timezone.c: In function ‘files_are_identical_content’: system-timezone.c:734: warning: passing argument 3 of ‘g_file_get_contents’ from incompatible pointer type system-timezone.c: In function ‘system_timezone_read_etc_localtime_content’: system-timezone.c:766: warning: passing argument 3 of ‘g_file_get_contents’ from incompatible pointer type system-timezone.c: In function ‘system_timezone_is_zone_file_valid’: system-timezone.c:869: warning: passing argument 4 of ‘g_io_channel_read_chars’ from incompatible pointer type system-timezone.c: In function ‘system_timezone_set_etc_timezone’: system-timezone.c:917: warning: passing argument 3 of ‘g_file_get_contents’ from incompatible pointer type Starting program: /home/jan/svn/gnome-panel/trunk/src/gnome-panel-2.22.1.2/applets/clock/system-timezone-get Program received signal SIGSEGV, Segmentation fault. 0x0000000000401b43 in system_timezone_find () at system-timezone.c:802 802 if (!(g_ascii_isalnum (*c) || Using -O: [jan@jan clock]$ gcc -O -g -DSYSTZ_GET_TEST -Wall -o system-timezone-get `pkg-config --cflags --libs glib-2.0 gobject-2.0 gio-2.0` system-timezone.c system-timezone.c: In function ‘system_timezone_write_key_file’: system-timezone.c:460: warning: passing argument 3 of ‘g_file_get_contents’ from incompatible pointer type system-timezone.c: In function ‘files_are_identical_content’: system-timezone.c:734: warning: passing argument 3 of ‘g_file_get_contents’ from incompatible pointer type system-timezone.c: In function ‘system_timezone_read_etc_localtime_content’: system-timezone.c:766: warning: passing argument 3 of ‘g_file_get_contents’ from incompatible pointer type system-timezone.c: In function ‘system_timezone_is_zone_file_valid’: system-timezone.c:869: warning: passing argument 4 of ‘g_io_channel_read_chars’ from incompatible pointer type system-timezone.c: In function ‘system_timezone_set_etc_timezone’: system-timezone.c:917: warning: passing argument 3 of ‘g_file_get_contents’ from incompatible pointer type [jan@jan clock]$ ./system-timezone-get Europe/Amsterdam
Net a compiler bug after all. After fixing the warnings (the parameters should not be "unsigned int" but "gsize" instead), the system-timezone-get program runs fine when compiled with gcc -O2.
On amd64, a sizeof(unsigned int) returns 4, while sizeof(gsize) returns 8. It's quite weird to see that gcc -O2 uncovers an integer overflow here (64 bit pointers don't fit in unsigned ints).
Good catch, thanks. I've committed a patch to replace all unsigned int usage with gsize. I'm closing the bug, but please test. Man, I'm sure that I've written code elsewhere that assumes unsigned int and gsize is the same :/ If you catch any other warning of this type anywhere else in GNOME, please file bugs...
*** Bug 528442 has been marked as a duplicate of this bug. ***
*** Bug 528532 has been marked as a duplicate of this bug. ***
*** Bug 528669 has been marked as a duplicate of this bug. ***
*** Bug 528703 has been marked as a duplicate of this bug. ***
*** Bug 528865 has been marked as a duplicate of this bug. ***
*** Bug 528866 has been marked as a duplicate of this bug. ***
*** Bug 528867 has been marked as a duplicate of this bug. ***