dougmencken / HeadOverHeels

The free and open source remake of the game “Head over Heels”
GNU General Public License v3.0
30 stars 9 forks source link

Problem with locating data when game lives in PATH and user runs it just by its name #22

Closed attuska closed 6 years ago

attuska commented 6 years ago

Something in the "Isomot" section is not good in commit 17e8a63. The characters in menu before this commit are defective.

I get this error in gdb: (1.30 pre-release)

attila@localhost:~$ gdb headoverheels

GNU gdb (GDB) 7.11.1
Copyright (C) 2016 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 "i686-uhu-linux".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from headoverheels...(no debugging symbols found)...done.
(gdb) run
Starting program: /usr/bin/headoverheels 
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/libthread_db.so.1".
[New Thread 0xf6e42b40 (LWP 29107)]
terminate called after throwing an instance of 'std::length_error'
  what():  basic_string::_M_create

Thread 1 "headoverheels" received signal SIGABRT, Aborted.
0xf7fd9a62 in _dl_sysinfo_int80 () from /lib/ld-linux.so.2
(gdb) bt
#0  0xf7fd9a62 in _dl_sysinfo_int80 () from /lib/ld-linux.so.2
#1  0xf7158dc0 in raise () from /lib/libc.so.6
#2  0xf715a287 in abort () from /lib/libc.so.6
#3  0xf744551f in __gnu_cxx::__verbose_terminate_handler() ()
   from /usr/lib/../lib/libstdc++.so.6
#4  0xf74430d4 in __cxxabiv1::__terminate(void (*)()) ()
   from /usr/lib/../lib/libstdc++.so.6
#5  0xf744314d in std::terminate() () from /usr/lib/../lib/libstdc++.so.6
#6  0xf7443401 in __cxa_throw () from /usr/lib/../lib/libstdc++.so.6
#7  0xf746deb6 in std::__throw_length_error(char const*) ()
   from /usr/lib/../lib/libstdc++.so.6
#8  0xf74daf10 in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_create(unsigned int&, unsigned int) ()
   from /usr/lib/../lib/libstdc++.so.6
#9  0x0809e414 in ?? ()
#10 0x0809e81e in ?? ()
#11 0x080d25e0 in ?? ()
#12 0x080d3219 in ?? ()
#13 0x0804ec76 in ?? ()
#14 0xf7145356 in __libc_start_main () from /lib/libc.so.6
#15 0x0808af59 in ?? ()
(gdb) quit
dougmencken commented 6 years ago

may you build current master with “ --enable-debug ” switch to configure?

as for “ The characters in menu before this commit are defective ” ~ it is due to “ ++ ” inside invokation of function is implementation-specific, I already solved that

an yep, I haven’t yet tested with c++11, I build with CXX="${pathToCompiler}/bin/g++ -std=c++03", and I want pre-c++11 support ... ... but without cost of breaking c++11

attuska commented 6 years ago

With the master I get the following errors: /usr/include/c++/6.2.0/bits/stl_pair.h:376:5: note: template argument deduction/substitution failed: gui/Font.cpp:56:37: note: ‘std::ifstream {aka std::basic_ifstream}’ is not derived from ‘const std::pair<_T1, _T2>’ if ( lettersFile != 0 ) ^ gui/Font.cpp: In member function ‘std::__cxx11::string gui::Font::getFamily() const’: gui/Font.cpp:149:32: error: invalid conversion from ‘const char’ to ‘char’ [-fpermissive] char* family = strrchr ( fontName.c_str () , '.' );


make[1]: *** [Makefile:1564: gui/headoverheels-Font.o] Error 1
make[1]: *** Waiting for unfinished jobs....
mv -f gui/.deps/headoverheels-ConfigurationManager.Tpo gui/.deps/headoverheels-ConfigurationManager.Po
make[1]: Leaving directory '/var/uhubuild/work/compile/src'
make: *** [Makefile:382: all-recursive] Error 1
dougmencken commented 6 years ago

I uploaded updated master

attuska commented 6 years ago

I'll try it... It's already compile, but it's still bad

attila@localhost:~$ headoverheels PathToGame is "headoverheels" FullPathToGame is "/home/attila/headoverheels" terminate called after throwing an instance of 'std::length_error' what(): basic_string::_M_create Félbeszakítva (core készült) attila@localhost:~$

Now I compile it with the --enable-debug switch

attuska commented 6 years ago

And compiled with the --enable-debug switch is alright!!!

dougmencken commented 6 years ago

Yes, that would give some point to me instead of useless ?? like “ 0x0809e414 in ?? () ”

dougmencken commented 6 years ago

Hmm, I haven’t build it without debugging on since a lot of time. Yet on your side, non-debug build fails and debug build is okay?

attuska commented 6 years ago

The debug-build is ok, but only in gdb. Otherwise the error is there.

dougmencken commented 6 years ago

Which platform are you on? If you’re on linux @ x86_*, build with -fsanitize=address -fno-omit-frame-pointer, that would help me a lot

attuska commented 6 years ago

I made the packages for UHU Linux ubk1 and ubk2 for 32 and 64 bit Here is the build files for ubk1 https://github.com/uhulinux/ub-ubk1/tree/master/hoh The 1bb01dd commit sources are patched with these patches: https://github.com/uhulinux/ub-ubk1/tree/master/hoh/patches And the package runs fine.

attuska commented 6 years ago

Terminal-log hoh.log.tar.gz Build-log hoh_log.tar.gz

dougmencken commented 6 years ago

The 1bb01dd commit sources are patched with these patches:

So you’re going to revert some stuff and use your fork instead of making this game better together? It’s up to you, but I just can’t get it

dougmencken commented 6 years ago

As for

terminate called after throwing an instance of 'std::length_error'
  what():  basic_string::_M_create

from hoh.log

look for issue #18

and play with these paths

attuska commented 6 years ago

I'm not a C programmer, just a packager that makes from sources packages for our distributon. My favorite game is headoverheels, already 20 years. I do not speak the English language at all, the German already, and of course the Hungarian, which is my mother tongue. I need to contact Google translator from german to english. I want to make this game better for everyone, that's why I made this issue.

Well, I looked it over and made a patch, this one:

diff -Nur orig/src/Ism.cpp mod/src/Ism.cpp --- orig/src/Ism.cpp 2018-03-01 14:09:47.000000000 +0100 +++ mod/src/Ism.cpp 2018-03-01 20:22:32.857030909 +0100 @@ -122,7 +122,7 @@

if defined ( CYGWIN ) || defined ( __WIN32 )

            const char* cpath = FullPathToGame.c_str ();

else

  • const char* cpath = PathToGame.c_str ();
  • const char* cpath = FullPathToGame.c_str ();

    endif

          char* filename = get_filename( cpath );

And so I get already in a terminal sensible message:

attila@localhost:~$ headoverheels PathToGame is "headoverheels" FullPathToGame is "/home/attila/headoverheels" SharePath is "/home/share/headoverheels/" reading from file "/home/share/headoverheels/font.png" to create font "white.regular" can’t get font "white.regular" from file "/home/share/headoverheels/font.png" reading from file "/home/share/headoverheels/font.png" to create font "white.big" can’t get font "white.big" from file "/home/share/headoverheels/font.png" reading from file "/home/share/headoverheels/font.png" to create font "orange.regular" can’t get font "orange.regular" from file "/home/share/headoverheels/font.png" reading from file "/home/share/headoverheels/font.png" to create font "cyan.regular" can’t get font "cyan.regular" from file "/home/share/headoverheels/font.png" reading from file "/home/share/headoverheels/font.png" to create font "yellow.regular" can’t get font "yellow.regular" from file "/home/share/headoverheels/font.png" reading from file "/home/share/headoverheels/font.png" to create font "orange.big" can’t get font "orange.big" from file "/home/share/headoverheels/font.png" reading from file "/home/share/headoverheels/font.png" to create font "cyan.big" can’t get font "cyan.big" from file "/home/share/headoverheels/font.png" reading from file "/home/share/headoverheels/font.png" to create font "yellow.big" can’t get font "yellow.big" from file "/home/share/headoverheels/font.png" reading from file "/home/share/headoverheels/font.png" to create font "green.regular" can’t get font "green.regular" from file "/home/share/headoverheels/font.png" reading from file "/home/share/headoverheels/font.png" to create font "green.big" can’t get font "green.big" from file "/home/share/headoverheels/font.png" reading from file "/home/share/headoverheels/font.png" to create font "magenta.regular" can’t get font "magenta.regular" from file "/home/share/headoverheels/font.png" reading from file "/home/share/headoverheels/font.png" to create font "magenta.big" can’t get font "magenta.big" from file "/home/share/headoverheels/font.png" parse "/home/share/headoverheels/sounds.xml" can not parse instance document parse "/home/attila/.headoverheels/preferences.xml" language "hu_HU" parse "/home/share/headoverheels/text/hu_HU.xml" can not parse instance document

But running in gdb, I get the right sharepath, and the game is running.

(gdb) r Starting program: /usr/bin/headoverheels [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib/libthread_db.so.1". PathToGame is "/usr/bin/headoverheels" FullPathToGame is "/usr/bin/headoverheels" [New Thread 0xf39ffb40 (LWP 11224)] SharePath is "/usr/share/headoverheels/" reading from file "/usr/share/headoverheels/font.png" to create font "white.regular" file "/usr/share/headoverheels/letters.utf8" has table for 336 letters reading from file "/usr/share/headoverheels/font.png" to create font "white.big" reading from file "/usr/share/headoverheels/font.png" to create font "orange.regular" reading from file "/usr/share/headoverheels/font.png" to create font "cyan.regular" reading from file "/usr/share/headoverheels/font.png" to create font "yellow.regular" reading from file "/usr/share/headoverheels/font.png" to create font "orange.big" reading from file "/usr/share/headoverheels/font.png" to create font "cyan.big" reading from file "/usr/share/headoverheels/font.png" to create font "yellow.big" reading from file "/usr/share/headoverheels/font.png" to create font "green.regular" reading from file "/usr/share/headoverheels/font.png" to create font "green.big" reading from file "/usr/share/headoverheels/font.png" to create font "magenta.regular" reading from file "/usr/share/headoverheels/font.png" to create font "magenta.big" [New Thread 0xed4d1b40 (LWP 11225)]

attuska commented 6 years ago

I have replaced these lines:

if defined ( CYGWIN ) || defined ( __WIN32 )

          const char* cpath = FullPathToGame.c_str ();

else

         const char* cpath = PathToGame.c_str ();

With this:

         const char* cpath = FullPathToGame.c_str ();

And the game only runs if I am in the directory / usr / share. Bad:

attila@localhost:/usr$ headoverheels
PathToGame is "headoverheels"
FullPathToGame is "/usr/headoverheels"
SharePath is "/share/headoverheels/"

Good:

attila@localhost:/usr$ cd share attila@localhost:/usr/share$ headoverheels PathToGame is "headoverheels" FullPathToGame is "/usr/share/headoverheels" SharePath is "/usr/share/headoverheels/" reading from file "/usr/share/headoverheels/font.png" to create font "white.regular"

attuska commented 6 years ago

I can not start the game.

Screen::loadAnimation( "heels.gif" ) got 16 frames
language "hu_HU"
parse "/usr/share/headoverheels/text/hu_HU.xml"
parse "/usr/share/headoverheels/text/en_US.xml"
looping Ogg music/MainTheme.ogg
going to create new screen for action " CreateMainMenu "
Screen::loadAnimation( "head.gif" ) got 18 frames
Screen::loadAnimation( "heels.gif" ) got 16 frames
=================================================================
==31231==ERROR: AddressSanitizer: heap-use-after-free on address 0xf445aaa0 at pc 0x080f6ba3 bp 0xff992558 sp 0xff99254c
WRITE of size 4 at 0xf445aaa0 thread T0
    #0 0x80f6ba2  (/usr/bin/headoverheels+0x80f6ba2)
    #1 0x80f6851  (/usr/bin/headoverheels+0x80f6851)
    #2 0x813b1b3  (/usr/bin/headoverheels+0x813b1b3)
    #3 0x81121d3  (/usr/bin/headoverheels+0x81121d3)
    #4 0x8117593  (/usr/bin/headoverheels+0x8117593)
    #5 0x811d948  (/usr/bin/headoverheels+0x811d948)
    #6 0x8125886  (/usr/bin/headoverheels+0x8125886)
    #7 0x81109a9  (/usr/bin/headoverheels+0x81109a9)
    #8 0x8057cab  (/usr/bin/headoverheels+0x8057cab)
    #9 0xf639c355 in __libc_start_main (/lib/libc.so.6+0x18355)
    #10 0x8050731  (/usr/bin/headoverheels+0x8050731)

0xf445aaa0 is located 32 bytes inside of 1068-byte region [0xf445aa80,0xf445aeac)
freed by thread T0 here:
    #0 0xf72ec72c in __interceptor_free (/usr/lib/../lib/libasan.so.3+0xbd72c)
    #1 0x80f6b30  (/usr/bin/headoverheels+0x80f6b30)
    #2 0x80f6851  (/usr/bin/headoverheels+0x80f6851)
    #3 0x813b1b3  (/usr/bin/headoverheels+0x813b1b3)
    #4 0x81121d3  (/usr/bin/headoverheels+0x81121d3)
    #5 0x8117593  (/usr/bin/headoverheels+0x8117593)
    #6 0x811d948  (/usr/bin/headoverheels+0x811d948)
    #7 0x8125886  (/usr/bin/headoverheels+0x8125886)
    #8 0x81109a9  (/usr/bin/headoverheels+0x81109a9)
    #9 0x8057cab  (/usr/bin/headoverheels+0x8057cab)
    #10 0xf639c355 in __libc_start_main (/lib/libc.so.6+0x18355)

previously allocated by thread T0 here:
    #0 0xf72eca64 in __interceptor_malloc (/usr/lib/../lib/libasan.so.3+0xbda64)
    #1 0x8100b45  (/usr/bin/headoverheels+0x8100b45)
    #2 0x80f678d  (/usr/bin/headoverheels+0x80f678d)
    #3 0x813a1a1  (/usr/bin/headoverheels+0x813a1a1)
    #4 0x81121d3  (/usr/bin/headoverheels+0x81121d3)
    #5 0x813f6d1  (/usr/bin/headoverheels+0x813f6d1)
    #6 0x81121d3  (/usr/bin/headoverheels+0x81121d3)
    #7 0x8117593  (/usr/bin/headoverheels+0x8117593)
    #8 0x811d948  (/usr/bin/headoverheels+0x811d948)
    #9 0x8125886  (/usr/bin/headoverheels+0x8125886)
    #10 0x81109a9  (/usr/bin/headoverheels+0x81109a9)
    #11 0x8057cab  (/usr/bin/headoverheels+0x8057cab)
    #12 0xf639c355 in __libc_start_main (/lib/libc.so.6+0x18355)

SUMMARY: AddressSanitizer: heap-use-after-free (/usr/bin/headoverheels+0x80f6ba2) 
Shadow bytes around the buggy address:
  0x3e88b500: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x3e88b510: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x3e88b520: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x3e88b530: fd fd fd fd fa fa fa fa fa fa fa fa fa fa fa fa
  0x3e88b540: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
=>0x3e88b550: fd fd fd fd[fd]fd fd fd fd fd fd fd fd fd fd fd
  0x3e88b560: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x3e88b570: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x3e88b580: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x3e88b590: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x3e88b5a0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Heap right redzone:      fb
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack partial redzone:   f4
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==31231==ABORTING
attila@localhost:/usr/share$ 
dougmencken commented 6 years ago

nice digging, I’m going to deal with it in a couple of days, thanks

multi-reading of the same file with font is a thing to optimize too

dougmencken commented 6 years ago

is it okay now?

note that I hard-coded FullPathToGame = "/usr/bin/headoverheels" ; in cases when game is in PATH and is run just by its name

for other install paths like /usr/local and custom names of game it would need more logic

attuska commented 6 years ago

Yes! Is OK!

In most linux systems the installed binaries are always under the folder / usr / bin, for the users this way is always reachable.

In my install phase, I made a headoverheels.desktop in the folder / usr / share / applications to make the game appear in desktops menus.

[Desktop Entry] Name = headoverheels GenericName = Head over Hells Comment = Solid 3d Game Comment [hu] = Classical szobás játék Exec = headoverheels Icon = headoverheels StartupNotify = false Type = Application Categories = Game; action game;

And in the install phase, I've copied the menu icon in the right place.

mkdir -p $ UB_INSTALLDIR / usr / share / pixmaps cp extras / icons / headoverheels48.png $ UB_INSTALLDIR / usr / share / pixmaps / headoverheels.png

($ UB_INSTALLDIR is my "fake" chroot folder, it packs everything into an installable package.)

I have noticed a thing to translate:

"play room tunes" is in Hungarian: "helyiség hangok"

Otherwise, you have done a nice job!

dougmencken commented 6 years ago

Thanks, I already uploaded updated commit with "helyiség hangok" (;

dougmencken commented 6 years ago

and if you like, I may add your "headoverheels.desktop" file to extras folder of git repository, if you’d attach it

or make a commit by yourself

attuska commented 6 years ago

I do not want to make a fork from your repository, from here you can download the desktop file, then install it in your repository: https://raw.githubusercontent.com/uhulinux/ub-ubk2/master/hoh/addons/usr/share/applications/headoverheels.desktop

In the desktop file is "Icon = headoverheels" without the png extension, because the extension png is not needed.

I renamed the iconfile name from headoverheels48 to headoverheels because I put in the headoverheels.png package instead of headoverheels48.png

When a stable release is done, I will make packages again. Until then, this pre-release is enough. Then the other distributions, such as ubuntu, arch, debian, and so on, will be easier to package.

And many can play at first!