OpenTTD

Tasklist

FS#5246 - Segfault on startup

Attached to Project: OpenTTD
Opened by hthhs (hthhs) - Saturday, 14 July 2012, 19:12 GMT
Last edited by Remko Bijker (Rubidium) - Monday, 16 July 2012, 16:11 GMT
Type Bug
Category Core
Status Closed
Assigned To No-one
Operating System Linux
Severity High
Priority Normal
Reported Version trunk
Due in Version Undecided
Due Date Undecided
Percent Complete 100%
Votes 0
Private No

Details

OpenTTD segfaults on startup. openttd.cfg attached. No crash.log, etc. present.

Ubuntu 11.04

gb54a165c (svn r24400)

gdb backtrace:

$ make run-gdb
make[1]: Entering directory `/home/harriet/openttd-git/objs/lang'
make[1]: Nothing to be done for `all'.
make[1]: Leaving directory `/home/harriet/openttd-git/objs/lang'
make[1]: Entering directory `/home/harriet/openttd-git/objs/setting'
make[1]: Nothing to be done for `all'.
make[1]: Leaving directory `/home/harriet/openttd-git/objs/setting'
make[1]: Entering directory `/home/harriet/openttd-git/objs/extra_grf'
make[1]: Nothing to be done for `all'.
make[1]: Leaving directory `/home/harriet/openttd-git/objs/extra_grf'
make[1]: Entering directory `/home/harriet/openttd-git/objs/debug'
make[1]: Nothing to be done for `all'.
make[1]: Leaving directory `/home/harriet/openttd-git/objs/debug'
GNU gdb (Ubuntu/Linaro 7.2-1ubuntu11) 7.2
Copyright (C) 2010 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-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/harriet/openttd-git/bin/openttd...done.
Starting program: /home/harriet/openttd-git/bin/openttd
[Thread debugging using libthread_db enabled]
[New Thread 0x2aaab6ed8700 (LWP 21605)]
[Thread 0x2aaab6ed8700 (LWP 21605) exited]
[New Thread 0x2aaab6ed8700 (LWP 21606)]

Program received signal SIGSEGV, Segmentation fault.
0x00000000006d3ba5 in SpriteGroup::Resolve (group=0x100000000, object=0x7fffffffdab0) at /home/harriet/openttd-git/src/newgrf_spritegroup.h:94
94 return group == NULL ? NULL : group->Resolve(object);
(gdb) bt
#0 0x00000000006d3ba5 in SpriteGroup::Resolve (group=0x100000000, object=0x7fffffffdab0) at /home/harriet/openttd-git/src/newgrf_spritegroup.h:94
#1 0x0000000000717d89 in GetCustomSignalSprite (rti=0xe12320, tile=<value optimised out>, type=<value optimised out>, var=<value optimised out>, state=<value optimised out>, gui=<value optimised out>)
at /home/harriet/openttd-git/src/newgrf_railtype.cpp:144
#2 0x0000000000773cf2 in ResolveRailTypeGUISprites (rti=0xe12320) at /home/harriet/openttd-git/src/rail_cmd.cpp:101
#3 0x0000000000773d76 in InitRailTypes () at /home/harriet/openttd-git/src/rail_cmd.cpp:116
#4 0x00000000006f3eba in AfterLoadGRFs () at /home/harriet/openttd-git/src/newgrf.cpp:9034
#5 0x00000000006f9aca in LoadNewGRF (load_index=<value optimised out>, file_index=4) at /home/harriet/openttd-git/src/newgrf.cpp:9161
#6 0x0000000000664e64 in LoadSpriteTables () at /home/harriet/openttd-git/src/gfxinit.cpp:218
#7 0x00000000006653aa in GfxLoadSprites () at /home/harriet/openttd-git/src/gfxinit.cpp:261
#8 0x00000000006564d3 in GenerateWorld (mode=GWM_EMPTY, size_x=64, size_y=64, reset_settings=true) at /home/harriet/openttd-git/src/genworld.cpp:312
#9 0x000000000072f1ce in ttd_main (argc=<value optimised out>, argv=<value optimised out>) at /home/harriet/openttd-git/src/openttd.cpp:839
#10 0x00002aaaadbc4eff in __libc_start_main () from /lib/x86_64-linux-gnu/libc.so.6
#11 0x0000000000570569 in _start ()
This task depends upon

Closed by  Remko Bijker (Rubidium)
Monday, 16 July 2012, 16:11 GMT
Reason for closing:  Bug in external library
Additional comments about closing:  Or rather a bug in the compiler.
Comment by hthhs (hthhs) - Saturday, 14 July 2012, 19:58 GMT
r24367 contains the offending change(s).
Comment by hthhs (hthhs) - Saturday, 14 July 2012, 21:11 GMT
The problem lay in ResolveRailTypeGUISprites in rail_cmd.cpp. Specifically, the following loop:

for (SignalType type = SIGTYPE_NORMAL; type < SIGTYPE_END; type = (SignalType)(type + 1)) {
for (SignalVariant var = SIG_ELECTRIC; var <= SIG_SEMAPHORE; var = (SignalVariant)(var + 1)) {
SpriteID red = GetCustomSignalSprite(rti, INVALID_TILE, type, var, SIGNAL_STATE_RED, true);
SpriteID green = GetCustomSignalSprite(rti, INVALID_TILE, type, var, SIGNAL_STATE_GREEN, true);
rti->gui_sprites.signals[type][var][0] = (red != 0) ? red + SIGNAL_TO_SOUTH : _signal_lookup[var][type];
rti->gui_sprites.signals[type][var][1] = (green != 0) ? green + SIGNAL_TO_SOUTH : _signal_lookup[var][type] + 1;
}
}

The inner loop was never terminating. If I had to guess, I'd say the compiler was converting the termination condition to a constant, reasoning that every valid value in the SignalVariant enum made it evaluate to true.
Comment by frosch (frosch) - Sunday, 15 July 2012, 13:03 GMT
What compiler version are you using?
I remember gcc over-optimizing enum comparisons, but I thought that was fixed.
Comment by hthhs (hthhs) - Sunday, 15 July 2012, 13:30 GMT
$ g++ -v
Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/usr/lib/x86_64-linux-gnu/gcc/x86_64-linux-gnu/4.5.2/lto-wrapper
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu/Linaro 4.5.2-8ubuntu4' --with-bugurl=file:///usr/share/doc/gcc-4.5/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.5 --enable-shared --enable-multiarch --with-multiarch-defaults=x86_64-linux-gnu --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib/x86_64-linux-gnu --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.5 --libdir=/usr/lib/x86_64-linux-gnu --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-plugin --enable-gold --enable-ld=default --with-plugin-ld=ld.gold --enable-objc-gc --disable-werror --with-arch-32=i686 --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 4.5.2 (Ubuntu/Linaro 4.5.2-8ubuntu4)

EDIT
I think you're right, it looks like it's the same behaviour as that described in <http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43680>, which was fixed in 4.6.0.
Comment by frosch (frosch) - Tuesday, 17 July 2012, 18:39 GMT
For reference:
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43680

That page also links to a clarification/change of the C++ standard wrt. handling of enumeration values out of range.

Loading...