games/gemrb unable to create cache directory

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

games/gemrb unable to create cache directory

Nam Nguyen
I pasted a diff for games/gemrb that:
* adds a README
* fixes LOCALBASE typo in files/baldurs_gate_1.cfg
* remove GameOverridePath option in files/baldurs_gate1.cfg
  (from /usr/local/share/examples/gemrb/GemRB.cfg.sample:
  "You probably do NOT want to specify this!")
* backported fix from upstream for "Unable to create cache directory"

I would like to backport one out of two fixes from upstream. The more
important bug crashes GemRB during startup because it is unable to
create a cache directory. The problem has been fixed upstream.
https://github.com/gemrb/gemrb/commit/3225a40f0f0c236934feba773d0be0cc2a14c64b

Tests in reproducing the important bug and feedback on this diff are
welcome. I was able to run Baldur's Gate 1 and Baldur's Gate 2 on
amd64. The backported fix should be removed with the next release. Also,
Kirill should decide whether it is best to wait until the next release.

To reproduce:
-------------
bg1.cfg:
GamePath=~/games/data/bg1
GameType=bg1
CaseSensitive=1
Width=640
Height=480
Fullscreen=0
GemRBPath=/usr/local/share/gemrb
CachePath=/tmp/cache/
PluginsPath=/usr/local/lib/gemrb/plugins
SavePath=~/.baldursgate

$ gemrb -c bg1.cfg                                                                
[Core]: GemRB Core Version v0.8.5 Loading...
[Config]: attempting to initialize config with bg1.cfg
[Core]: Initializing the Event Manager...
[Core/FATAL]: Unable to create cache directory '/tmp/cache'

First bug details
-----------------
It is unable to create the cache directory because in
gemrb/gemrb/core/System/VFS.h:

  #ifdef WIN32
  const char PathDelimiter = '\\';
  const char PathListSeparator = ';';
  #else
  const char PathDelimiter = '/';
  const char PathListSeparator = ':';
  #endif
  const char SPathDelimiter[] = { PathDelimiter, '\0' };
  const char SPathListSeparator[] = { PathListSeparator, '\0' };

Then, in gemrb/gemrb/core/System/VFS.cpp:

  char* Token = strtok(Tokenized, &PathDelimiter);

gdb hinted:

  (gdb) print &PathDelimiter
  Can't take address of "GemRB::PathDelimiter" which isn't an lvalue.

My guess is that the compiler optimized away the address of
PathDelimiter so it isn't actually stored in memory. &PathDelimiter then
becomes nonsense. This broke MakeDirectories, which, given,
/home/user/games, should try to to repeatedly call MakeDirectory on
"/home", "/home/user" and "/home/user/games". Instead, it was fed
nonsensical tokens.

Second (less important) bug
---------------------------

The second less important bug is a non-deterministic segfault. To try
to reproduce this, start GemRB Baldur's Gate 1 and click Single
Player. Here, it has a ~10% chance of crashing. Restart the game and
try again until it crashes.

I attached a core dump, but it probably isn't worth the time to
investigate. This core dump revealed that Particles.{h,cpp} is to
blame. The fixes say that some memory is uninitialized.

Line 51 in Particles.cpp: sscanf(value+4,"%d,%d,%d)", &r, &g, &b);
But, value is the string "0" so it is accessing memory out of bounds.

I am hoping that it could be resolved by these two commits, but
since this is rare and hard to reproduce, I haven't tried to backport
it. It can wait until next release.

https://github.com/gemrb/gemrb/commit/af7040c30532c57c35d7f2093f34a6ba0a0ec30a#diff-694c114f9c1517ac5c1fabf85e1ac2af
https://github.com/gemrb/gemrb/commit/2d6d0396dd48b91786769c8ea4399f83498d3552#diff-694c114f9c1517ac5c1fabf85e1ac2af

$ egdb gemrb gemrb.core
(gdb) run -c bg1.cfg
...
Program terminated with signal SIGSEGV, Segmentation fault.
#0  strlen () at /usr/src/lib/libc/arch/amd64/string/strlen.S:125
125             movq    (%rax),%rdx             /* get bytes to check */
[Current thread is 1 (process 494538)]
(gdb) bt
#0  strlen () at /usr/src/lib/libc/arch/amd64/string/strlen.S:125
#1  0x00000cfa3e2a02d0 in _libc_sscanf (
    str=0xcf98a494e74 '\337' <repeats 199 times>, <incomplete sequence \337>...,
    fmt=0xcfa403ac19e "%d,%d,%d)") at /usr/src/lib/libc/stdio/sscanf.c:57
#2  0x00000cfa404e8a97 in GemRB::TranslateColor (value=0xcf98a494e70 "0", color=...)
    at /usr/ports/pobj/gemrb-0.8.5/gemrb-0.8.5/gemrb/core/Particles.cpp:51
#3  0x00000cfa404e79f1 in GemRB::InitSparks ()
    at /usr/ports/pobj/gemrb-0.8.5/gemrb-0.8.5/gemrb/core/Particles.cpp:84
#4  0x00000cfa404e77e0 in GemRB::Particles::Particles (this=0xcf9c12bb280, s=200)
    at /usr/ports/pobj/gemrb-0.8.5/gemrb-0.8.5/gemrb/core/Particles.cpp:101
#5  0x00000cfa4046b260 in GemRB::Game::Game (this=0xcf9ef76c800)
    at /usr/ports/pobj/gemrb-0.8.5/gemrb-0.8.5/gemrb/core/Game.cpp:116
#6  0x00000cfa40494c2b in GemRB::Interface::LoadGame (this=0xcfa2d06c000, sg=0x0,
    ver_override=0)
    at /usr/ports/pobj/gemrb-0.8.5/gemrb-0.8.5/gemrb/core/Interface.cpp:3836
#7  0x00000cfa40494463 in GemRB::Interface::HandleFlags (this=0xcfa2d06c000)
    at /usr/ports/pobj/gemrb-0.8.5/gemrb-0.8.5/gemrb/core/Interface.cpp:626
#8  0x00000cfa404971da in GemRB::Interface::Main (this=0xcfa2d06c000)
    at /usr/ports/pobj/gemrb-0.8.5/gemrb-0.8.5/gemrb/core/Interface.cpp:992
#9  0x00000cf7782934cd in main (argc=3, argv=0x7f7ffffc18e8)
    at /usr/ports/pobj/gemrb-0.8.5/gemrb-0.8.5/gemrb/GemRB.cpp:99

Index: Makefile
===================================================================
RCS file: /cvs/ports/games/gemrb/Makefile,v
retrieving revision 1.13
diff -u -p -r1.13 Makefile
--- Makefile 12 Jul 2019 20:46:18 -0000 1.13
+++ Makefile 29 Jul 2019 05:55:54 -0000
@@ -5,7 +5,7 @@ SHARED_LIBS += gemrb_core 0.0
 COMMENT = open-source implementation of Bioware's Infinity Engine
 
 DISTNAME = gemrb-0.8.5
-REVISION = 2
+REVISION = 3
 
 CATEGORIES = games emulators x11
 
Index: files/baldurs_gate_1.cfg
===================================================================
RCS file: /cvs/ports/games/gemrb/files/baldurs_gate_1.cfg,v
retrieving revision 1.1.1.1
diff -u -p -r1.1.1.1 baldurs_gate_1.cfg
--- files/baldurs_gate_1.cfg 21 Aug 2015 09:14:22 -0000 1.1.1.1
+++ files/baldurs_gate_1.cfg 29 Jul 2019 05:55:54 -0000
@@ -10,8 +10,7 @@ CaseSensitive=1
 Width=640
 Height=480
 Fullscreen=1
-GemRBPath=${LOCALASE}/share/gemrb
-GameOverridePath=/data
+GemRBPath=${LOCALBASE}/share/gemrb
 CachePath=/tmp/cache/
 PluginsPath=${LOCALBASE}/lib/gemrb/plugins
 SavePath=~/.baldursgate
Index: patches/patch-gemrb_core_System_VFS_cpp
===================================================================
RCS file: patches/patch-gemrb_core_System_VFS_cpp
diff -N patches/patch-gemrb_core_System_VFS_cpp
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ patches/patch-gemrb_core_System_VFS_cpp 29 Jul 2019 05:55:54 -0000
@@ -0,0 +1,27 @@
+$OpenBSD$
+
+Fixes [Core/FATAL]: Unable to create cache directory '/tmp/cache'
+
+XX Remove when >0.8.5 releases.
+
+Index: gemrb/core/System/VFS.cpp
+--- gemrb/core/System/VFS.cpp.orig
++++ gemrb/core/System/VFS.cpp
+@@ -413,7 +413,7 @@ bool MakeDirectories(const char* path)
+ assert(strnlen(path, _MAX_PATH/2) < _MAX_PATH/2);
+ strcpy(Tokenized, path);
+
+- char* Token = strtok(Tokenized, &PathDelimiter);
++ char* Token = strtok(Tokenized, SPathDelimiter);
+ while(Token != NULL) {
+ if(TempFilePath[0] == 0) {
+ if(path[0] == PathDelimiter) {
+@@ -428,7 +428,7 @@ bool MakeDirectories(const char* path)
+ if(!MakeDirectory(TempFilePath))
+ return false;
+
+- Token = strtok(NULL, &PathDelimiter);
++ Token = strtok(NULL, SPathDelimiter);
+ }
+ return true;
+ }
Index: pkg/PLIST
===================================================================
RCS file: /cvs/ports/games/gemrb/pkg/PLIST,v
retrieving revision 1.5
diff -u -p -r1.5 PLIST
--- pkg/PLIST 29 Jun 2018 22:16:13 -0000 1.5
+++ pkg/PLIST 29 Jul 2019 05:55:54 -0000
@@ -138,6 +138,7 @@ share/doc/gemrb/en/Tables/wstwohnd.txt
 share/doc/gemrb/en/Tables/wstwowpn.txt
 share/doc/gemrb/en/default_ini.txt
 share/doc/gemrb/en/gemrb_ini.txt
+share/doc/pkg-readmes/${PKGSTEM}
 share/examples/gemrb/
 @sample ${SYSCONFDIR}/gemrb/
 share/examples/gemrb/GemRB.cfg.noinstall.sample
Index: pkg/README
===================================================================
RCS file: pkg/README
diff -N pkg/README
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ pkg/README 29 Jul 2019 05:55:54 -0000
@@ -0,0 +1,29 @@
+$OpenBSD$
+
++-------------------------------------------------------------------------------
+| Running ${PKGSTEM} on OpenBSD
++-------------------------------------------------------------------------------
+
+Getting the games
+=================
+GemRB requires the original game files. These can be from original CDs or
+GOG.com.
+
+Extracting
+----------
+innoextract is in ports and can be used to extract the GOG.com version.
+
+$ innoextract -g -m setup_baldurs_gate_2.0.0.20.exe
+
+Configuration file
+==================
+Refer to /usr/local/share/examples/gemrb/baldurs_gate_1.cfg for a quickstart
+configuration file. (GemRB.cfg.sample contains more options, including using
+data from original CDs with options CD1-CD5.)
+
+Configuring
+-----------
+$ cp /usr/local/share/examples/gemrb/baldurs_gate_1.cfg ~/
+$ chmod 744 ~/baldurs_gate_1.cfg
+Edit GamePath.
+$ gemrb -c ~/baldurs_gate_1.cfg


gemrb.core (33M) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: games/gemrb unable to create cache directory

Kirill Bychkov
On Mon, July 29, 2019 11:27, Nam Nguyen wrote:
> I pasted a diff for games/gemrb that:
> * adds a README
> * fixes LOCALBASE typo in files/baldurs_gate_1.cfg
> * remove GameOverridePath option in files/baldurs_gate1.cfg
>   (from /usr/local/share/examples/gemrb/GemRB.cfg.sample:
>   "You probably do NOT want to specify this!")
> * backported fix from upstream for "Unable to create cache directory"
>

Hi.
There is /etc/gemrb/GemRB.cfg and gemrb also looks into
~/.gemrb/gemrb.cfg so the "config file" part is unnecessary.
Configuration is also explained in gemrb manual.
I used small rewording to encourage people to use packages instead
of ports.
Thanks for the fixes!

[...]

Index: Makefile
===================================================================
RCS file: /cvs/ports/games/gemrb/Makefile,v
retrieving revision 1.13
diff -u -p -r1.13 Makefile
--- Makefile 12 Jul 2019 20:46:18 -0000 1.13
+++ Makefile 30 Jul 2019 17:04:40 -0000
@@ -5,7 +5,7 @@ SHARED_LIBS += gemrb_core 0.0
 COMMENT = open-source implementation of Bioware's Infinity Engine

 DISTNAME = gemrb-0.8.5
-REVISION = 2
+REVISION = 3

 CATEGORIES = games emulators x11

Index: files/baldurs_gate_1.cfg
===================================================================
RCS file: /cvs/ports/games/gemrb/files/baldurs_gate_1.cfg,v
retrieving revision 1.1.1.1
diff -u -p -r1.1.1.1 baldurs_gate_1.cfg
--- files/baldurs_gate_1.cfg 21 Aug 2015 09:14:22 -0000 1.1.1.1
+++ files/baldurs_gate_1.cfg 30 Jul 2019 17:04:40 -0000
@@ -10,8 +10,7 @@ CaseSensitive=1
 Width=640
 Height=480
 Fullscreen=1
-GemRBPath=${LOCALASE}/share/gemrb
-GameOverridePath=/data
+GemRBPath=${LOCALBASE}/share/gemrb
 CachePath=/tmp/cache/
 PluginsPath=${LOCALBASE}/lib/gemrb/plugins
 SavePath=~/.baldursgate
Index: patches/patch-gemrb_core_System_VFS_cpp
===================================================================
RCS file: patches/patch-gemrb_core_System_VFS_cpp
diff -N patches/patch-gemrb_core_System_VFS_cpp
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ patches/patch-gemrb_core_System_VFS_cpp 30 Jul 2019 17:04:40 -0000
@@ -0,0 +1,26 @@
+$OpenBSD$
+
+Fixes [Core/FATAL]: Unable to create cache directory '/tmp/cache'
+Upstream commit 3225a40f0f0c236934feba773d0be0cc2a14c64b
+
+Index: gemrb/core/System/VFS.cpp
+--- gemrb/core/System/VFS.cpp.orig
++++ gemrb/core/System/VFS.cpp
+@@ -413,7 +413,7 @@ bool MakeDirectories(const char* path)
+ assert(strnlen(path, _MAX_PATH/2) < _MAX_PATH/2);
+ strcpy(Tokenized, path);
+
+- char* Token = strtok(Tokenized, &PathDelimiter);
++ char* Token = strtok(Tokenized, SPathDelimiter);
+ while(Token != NULL) {
+ if(TempFilePath[0] == 0) {
+ if(path[0] == PathDelimiter) {
+@@ -428,7 +428,7 @@ bool MakeDirectories(const char* path)
+ if(!MakeDirectory(TempFilePath))
+ return false;
+
+- Token = strtok(NULL, &PathDelimiter);
++ Token = strtok(NULL, SPathDelimiter);
+ }
+ return true;
+ }
Index: pkg/PLIST
===================================================================
RCS file: /cvs/ports/games/gemrb/pkg/PLIST,v
retrieving revision 1.5
diff -u -p -r1.5 PLIST
--- pkg/PLIST 29 Jun 2018 22:16:13 -0000 1.5
+++ pkg/PLIST 30 Jul 2019 17:04:40 -0000
@@ -138,6 +138,7 @@ share/doc/gemrb/en/Tables/wstwohnd.txt
 share/doc/gemrb/en/Tables/wstwowpn.txt
 share/doc/gemrb/en/default_ini.txt
 share/doc/gemrb/en/gemrb_ini.txt
+share/doc/pkg-readmes/${PKGSTEM}
 share/examples/gemrb/
 @sample ${SYSCONFDIR}/gemrb/
 share/examples/gemrb/GemRB.cfg.noinstall.sample
Index: pkg/README
===================================================================
RCS file: pkg/README
diff -N pkg/README
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ pkg/README 30 Jul 2019 17:04:40 -0000
@@ -0,0 +1,16 @@
+$OpenBSD$
+
++-------------------------------------------------------------------------------
+| Running ${PKGSTEM} on OpenBSD
++-------------------------------------------------------------------------------
+
+Getting the games
+=================
+GemRB requires the original game files. These can be from original CDs or
+GOG.com.
+
+Extracting
+----------
+innoextract from packages can be used to extract the GOG.com version.
+
+$ innoextract -g -m setup_baldurs_gate_2.0.0.20.exe


Reply | Threaded
Open this post in threaded view
|

Re: games/gemrb unable to create cache directory

Stuart Henderson
In reply to this post by Nam Nguyen
On 2019/07/29 01:27, Nam Nguyen wrote:
> I attached a core dump

please don't do that.